pax_global_header00006660000000000000000000000064125715263730014525gustar00rootroot0000000000000052 comment=c53eb1472537da1694a5adc4c8fef5611eae7ab8 davix-R_0_5_0/000077500000000000000000000000001257152637300132655ustar00rootroot00000000000000davix-R_0_5_0/.gitmodules000066400000000000000000000001751257152637300154450ustar00rootroot00000000000000[submodule "deps/boost_intern"] path = deps/boost_intern url = https://github.com/cern-it-sdc-id/davix-submodule-boost.git davix-R_0_5_0/CMakeLists.txt000066400000000000000000000065401257152637300160320ustar00rootroot00000000000000 ## cmake build script for davix project (davix) cmake_minimum_required (VERSION 2.6) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") option(SHARED_LIBRARY "generate shared library" TRUE) option(STATIC_LIBRARY "generate static library" FALSE) # build type if(NOT CMAKE_BUILD_TYPE) message(STATUS "No build type selected, default to RelWithDebInfo") set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif(NOT CMAKE_BUILD_TYPE) # load module include(DefineInstallationPaths REQUIRED) include(ReleaseDebugAutoFlags REQUIRED) include(CMakeGeneratePkgConfig REQUIRED) include(MacroAddDoxygen REQUIRED) include(PortabilityGNUCheck REQUIRED) include(CMakeCXX11Support REQUIRED) #enable testing INCLUDE(CTest) set(OUTPUT_NAME_DAVIX "davix") set(VERSION_MAJOR 0) set(VERSION_MINOR 5) set(VERSION_PATCH 0) set(VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(VERSION_TAG "") # dependency mode option(BOOST_EXTERNAL "Enable the usage of an external boost dependency" TRUE) set (Boost_NO_BOOST_CMAKE ON) # components option(ENABLE_TOOLS "enable or disable tools " TRUE) # features option(ENABLE_IPV6 "enable or disable IPv6 support " TRUE) option(ENABLE_TCP_NODELAY "enable or disable tcp_nodelay" TRUE) option(ENABLE_THIRD_PARTY_COPY "enable or disable third party copy support" FALSE) # tests option(UNIT_TESTS "enable or disable the unit tests" FALSE) option(FUNCTIONAL_TESTS "enable or disable the functional tests" FALSE) option(BENCH_TESTS "enable or disable the bench tests" FALSE) # libs checks find_package(Threads) # openssl find_package(OpenSSL) SET(LIBSSL_PKG_LIBRARIES "${OPENSSL_LIBRARIES}") SET(CRYPTO_PKG "") SET(LIBSSL_PKG_INCLUDE_DIRS "${OPENSSL_INCLUDE_DIR}") find_package(LibXml2) set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR}) if(BOOST_EXTERNAL) find_package(Boost 1.41.0 COMPONENTS thread system) endif(BOOST_EXTERNAL) #const set(HAVE_OPENSSL 1) set(NE_HAVE_SSL 1) add_subdirectory(deps) ## general defs add_definitions( -D_GNU_SOURCE) # GNU source, import LFS, etc... add_definitions( -D__DAVIX_INSIDE__) # protection flag add_definitions( -D__STDC_LIMIT_MACROS ) # C99 limit macros set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG_ENABLE}") include_directories( ${Boost_INCLUDE_DIRS}) include_directories( ${HTTPLIB_PKG_INCLUDE_DIRS} ${GLIB2_PKG_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/deps ${CMAKE_CURRENT_SOURCE_DIR}/deps/libneon/src/ ) include_directories( ${CMAKE_SOURCE_DIR}/include/davix ) include_directories( ${CMAKE_SOURCE_DIR}/src/libs/) add_subdirectory (src) add_subdirectory (doc) add_subdirectory (dist) add_subdirectory (test) add_subdirectory (packaging) ############################################################################# ## headers install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/davix/ DESTINATION ${INCLUDE_INSTALL_DIR}/davix) ############################################################################## ## Doc file install(FILES RELEASE-NOTES LICENSE DESTINATION ${DOC_INSTALL_DIR}/) # install release notes ####################################################### # Configure an 'uninstall' target CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") davix-R_0_5_0/LICENSE000066400000000000000000000636421257152637300143050ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 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. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; 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. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! davix-R_0_5_0/README000066400000000000000000000074351257152637300141560ustar00rootroot00000000000000 === DAVIX === Davix provides a share library and tools for advanced file I/O with HTTP based protocols. It is compatible WebDav, S3, HTTP Davix is composed of a shared library, libdavix and of a set of utility tools for data management Libdavix offers a high level C++ File API allowing resource manipulation with abstraction of the protocol. Libdavix has been design with the following objectives in mind : - Simplicity - High performances - Reliability - Portability * Davix and libdavix Website and documentation link : http://dmc.web.cern.ch/projects/davix/home * Is Davix is an other HTTP Library ? No, Davix targets file and resources interactions. It provides a high level abstraction of the underlying HTTP protocol mechanisms * What does Davix support ? Davix supports : - all common file manipulation operations ( Stat, read, write, copy, delete, rename ) - all common posix operation ( stat/opendir/readdir/open/read/write/close/mkdir ) - Webdav and XML parsing - remote random I/O - client side credential in PEM, P12 format, VOMS proxy, RFC proxy with support of VOMS extensions - transparent redirection caching - third party copy Server to Server - Session reuse for both SSL and HTTP - Basic authentication scheme - S3 authentication - bulk operations - metalinks Davix is going to support soon : - transparent meta-link support with failover - kerberos auth * How to compile : - Davix Dependencies : - openssl - libxml-2.0 - boost (available as submodule) - doxygen ( optional, for doc generation ) - gtest ( optional, unit tests only ) - Compile : $ # For Mac OSX and grid usage, see Compile Davix in embedded mode $ git https://github.com/cern-it-sdc-id/davix.git davix $ cd davix $ mkdir build; cd build $ cmake ../ $ make - Generate doc : - * run cmake - make doc - Compile Davix in embedded mode ( no dependencies ) : $ git clone https://github.com/cern-it-sdc-id/davix.git davix $ cd davix $ git submodule update --recursive --init $ mkdir build; cd build $ cmake -D BOOST_EXTERNAL=NO ../ $ make - Compile and run unit tests : - cmake -DUNIT_TESTS=TRUE ../ - make - make test - Compile & execute func tests : * warning : functionals test needs davserver and a valid credential - " 4. cmake -DFUNCTIONAL_TESTS=TRUE ../ " - " 5. . ../test/setup_test_env.sh - " 5. make; make test" - create SRPM : - ./packaging/bin/packager_rpm.sh ./packaging/rpm/specs/ ./ - mock -r [mycfg] RPMS/davix-[...].src.rpm * How to use * Libdavix, please follow the comments in the doxygen generated documentation * Command line tools davix-ls: listing and meta-data davix-del: delete existing resource or collection davix-get: download and display the content of a resource davix-put: upload the content of a resource davix-cp: copy, support 3rd party copy davix-mk: create collection or resource. davix-mv: relocate resource * Davix Support or information : Any suggestion is welcome. please contact us on davix-devel@cern.ch ( CERN e-group & mailing list ) or personnaly on adrien.devresse@cern.ch Davix is an open source and free project and will stay like this. Any contribution is welcome davix-R_0_5_0/RELEASE-NOTES000066400000000000000000000260731257152637300151660ustar00rootroot00000000000000 Version - 0.5.0 ** Bug * [DMC-629] - Bulk davs deletion seems to fail every 18 operations as a clock * [DMC-630] - Davix: davposix and davfile stat on S3 objects defaults to HTTP head request, bypasses signing * [DMC-660] - Davix-put does not recognize the --verbose option ? * [DMC-671] - Davix: S3 Uri transformer incorrectly assumes all operations are done without SSL * [DMC-675] - Found a host that hangs Davix indefinitely * [DMC-447] - Davix SSL Error needs to be clarified * [DMC-569] - Davix: libneon has problems with the handling of corrupted or invalid ceritificate * [DMC-691] - davix-put returns 0 ( =OK ) in case of permission denied * [DMC-699] - Bad regression bugs * [DMC-707] - Davix: xml parser does not handle multi-status response correctly for delete * [DMC-193] - DAVIX: Transform and simply the rety mechanism on davix * [DMC-633] - Connection timeout is sometimes triggered before the deadline when the global timeout is default. ** Improvement * [DMC-614] - Davix: Add hierarchical file listing support for S3 bucket * [DMC-621] - Davix: Add last modified date/time to S3 long listing * [DMC-631] - Davix: Add virtual S3 directory stats request handling * [DMC-634] - Davix: Add configurable max-keys param for S3 list object request * [DMC-658] - Davix: Add functionality to support uploading and downloading collections * [DMC-700] - Davix-get should not retry 10 times on err 403 (and maybe others) * [DMC-702] - Davix: Implement Content-Type and Content-MD5 signing for S3 requests * [DMC-715] - Davix: Implement multi-threaded crawler for recursive directory listing * [DMC-716] - Davix: Allow user to specify the number of threads for recursive operations * [DMC-718] - Davix can't copy a 0-sized file ** New Feature * [DMC-665] - Add support for 3rd party copy FROM dav TO s3 * [DMC-693] - Add support for pulling http 3rd party copies ** Suggestion * [DMC-668] - Davix-rm: bulk/folder remove ** Task * [DMC-624] - No decent error message if certificate or key are not readable * [DMC-695] - Makes recursive operations on directory optional rather than default (davix-get/put) * [DMC-703] - Davix: Remove gridsite dependency * [DMC-708] - Davix: Add new parser for S3 multi-objects deletion response * [DMC-711] - Davix: Update banner in source files with correct copyright info * [DMC-713] - Shall the davix recursive crawler ignore more common errors and continue ? Version - 0.4.0 ** Bug Fixes * [DMC-443] - Wrong section in .TH tag for libdavix.3 * [DMC-444] - Fix SSL Error related to too big digest (reported by Martin) * [DMC-472] - Fix Davix follows redirection automatically even though redirectionSupport is switched off * [DMC-501] - Fix SIGPIPE error with OpenSSL in Davix * [DMC-518] - Fix POODLE vulnerability CVE-2014-3566 affects libneon, then davix * [DMC-538] - Fix davix cmd line tool print an error in case of double authentication x509 -> login/password * [DMC-547] - Update the functional tests * [DMC-554] - Fix Thread-safety issue in the new davix logger system * [DMC-564] - Fix issue: Libneon does not set OpenSSL thread callback for some plateforms ( Ubuntu ) * [DMC-571] - Fix compilation warnings on the libneon part * [DMC-573] - Reinforce auto retry mechanism (dCache Door problem) * [DMC-581] - Solve portability problem under OSX/BSD due to the new hard timeout support * [DMC-586] - Fix ** Improvement * [DMC-474] - Log response body on http 3rd party copies * [DMC-476] - Delegation v2 support needed * [DMC-503] - Implement checksum support for S3 interface via Davix::File::checksum * [DMC-534] - Davix: re-design the logger to be more user friendly and easier to tune ** New Feature * [DMC-498] - S3 bucket creation support * [DMC-499] - S3 checksum support * [DMC-182] - Implement a list bucket feature for davix on the opendir/readdir model * [DMC-505] - Hard timeout support * [DMC-535] - Implement move operation in the File API * [DMC-552] - DAVIX: improve PUT operation support in the file API Version - 0.3.6 Bug fixs: * [LCGUTIL-418] - DAVIX: Solve OpenSSL issue with davix cmd line tools and password shell * [LCGUTIL-475] - davfile.getToFd does not return the number of bytes read, but 0 on success * [LCGUTIL-478] - Davix 32 bits ABI break problem * [LCGUTIL-480] - Davix maps badly http statuses to errno Version - 0.3.4 Bug fixs: * [LCGUTIL-410] - davix-cp help is not up to date and confusing * [LCGUTIL-411] - davix-cp does not support the profile features of the davix command line tool * [LCGUTIL-454] - Davix: libneon ignores connexion timeout * [LCGUTIL-455] - DAVIX: bug reported by johannes concerning dCache and very long connexion re-use * [LCGUTIL-456] - LCGUTIL: davix under heavy I/O usage for vector query send sometimes empty vector query Version - 0.3.1 Main changes: - Support for transparent fail-over based on Metalink, supported by all read I/O with HTTP - Multi-Range support compatible with TDavixFile/ROOT 5/6 -> tested and working for dCache, DPM, Apache2, EOS, DynaFed, Owncloud, S3 - Implement SOCKS5 support based on libneon - Add support for POSIX write operations, davix can now be used to write remotely on top of POSIX layer. - Add getReplicas call, allowing to list replica of a resources using Metalink - Introduce Checksum calculation feature - Extend the command line tool with davix-mkdir, davix-rm - Add long listing option to davix-ls -l - Add the -P options to all command line tools, can be used to enable the usage of pre-defined profile -> For instance "davix-ls -P grid davs://grid-storage.com/" enable all grid extensions for davix-ls - Introduce a callback mechanism, allowing to intercept event inside davix based on std::function - Drop internal library for boost ( dependency optional, git submodule ) - The "davix" http query tool is renamed "davix-http" - First port on cygwin - Add --headers options for OAuth spport to all command line tools - Add --trace-headers options to all command line tools for query debugging - create man pages for each cmd line tool - Reduce default connextion timeout from 180s to 30s List Of JIRA tickets solved : * [LCGUTIL-170] - Davix : Correct important coverity warnings * [LCGUTIL-275] - Double HEAD coming from gfal-copy/gfal2/davix (?) relies on KeepAlive * [LCGUTIL-301] - Create Davix MetalinkParser and test it * [LCGUTIL-302] - Implement replicas selector from Metalink parsers * [LCGUTIL-103] - DAVIX: Evaluate performance of Http based IO and compare with other protocols ( gsiftp, xrootd ) * [LCGUTIL-154] - Davix: koji build hangs forever on rawhide * [LCGUTIL-162] - DAVIX: portability issue seen on Win32 plateform * [LCGUTIL-172] - Davix posix write does not handle failures correctly * [LCGUTIL-174] - DAVIX : Add a request parameter flag in order to disable completely any session reuse * [LCGUTIL-188] - Davix: prefixed install problem with cmake 2.8.7 * [LCGUTIL-196] - Davix & TDavixFile : map the main option to the ROOT Open file * [LCGUTIL-318] - DAVIX: storm webdav parsing problem * [LCGUTIL-341] - DAVIX: redirection caching problem with dCache instance * [LCGUTIL-348] - gfal-copy produces misleading error * [LCGUTIL-357] - gfal2-http fails to create the directories on 3rd party copies * [LCGUTIL-383] - Merge fixes for 405 error mapping and discard body after a request is done * [LCGUTIL-73] - DAVIX: design an API for advanced meta-link file management. * [LCGUTIL-119] - DAVIX: implement a simple transparent failover case using meta-link. * [LCGUTIL-344] - DAVIX : simplify davix code using boost, internal boost version is needed for ROOT usage * [LCGUTIL-370] - DAVIX : rename davix cmd line tool to davix-http in order to avoid confusion * [LCGUTIL-407] - DAVIX: Implement basic SOCKS5 support for Davix * [LCGUTIL-408] - DAVIX: Add a "load module" feature to davix * [LCGUTIL-113] - Davix misses a getReplicas function * [LCGUTIL-115] - DAVIX: split clearly the C API and the C++ API * [LCGUTIL-116] - DAVIX: export the IO buff map functions to the Object API * [LCGUTIL-339] - DAVIX: add support for login/password HTTP auth when URL contains login/password * [LCGUTIL-19] - add third party transfer support inside davix ( gfal 2.0 need ) * [LCGUTIL-175] - DAVIX: add options in order to display only request headers to the logging system * [LCGUTIL-246] - DAVIX : Add support for davix command line tools for plain encrypted PEM credential * [LCGUTIL-336] - DAVIX : error in case of separated cred and key usage * [LCGUTIL-337] - Davix: Support 303 redirection code for GET Operation too * [LCGUTIL-338] - Davix : Support for file request parameter level personalized header * [LCGUTIL-369] - Davix: add cmd line tool for simple collection creation ( mkdir ) * [LCGUTIL-371] - DAVIX : abi break between 0.2.8, and 0.3 : an ABI break has been detected on davix, this need to be fixed * [LCGUTIL-372] - DAVIX: add simple stupid option --headers to display request headers of any operations with davix * [LCGUTIL-373] - DAVIX : fix compilation problems and warning on OSX with clang compilation * [LCGUTIL-375] - DAVIX: prepare internal IO stack for Metalink usage, Rucio parsing and s3 bucket parsing * [LCGUTIL-379] - DAVIX: Fix misleading Connexion timeout debug message * [LCGUTIL-381] - DAVIX: include man page for the software distribution * [LCGUTIL-394] - DAVIX: bad_alloc throw by davix in some case with dCache endpoints * [LCGUTIL-409] - DAVIX: implement POSIX partial write support with davix Version - 0.2.8 * [LCGUTIL-197] - Davix : bug inside the vector request system : vector request split to "one" range can trigger parsing problem * [LCGUTIL-333] - Improve Davix setup on OSX * [LCGUTIL-327] - DAVIX: add long listing support to davix-ls * [LCGUTIL-274] - add an error code "redirection needed" to davix status errors Version - 0.2.7 - remove several GNU ext dependency - first version stable for TDavixFile/TDavixSystem - include prefetching support - several minor bug fixes - fix a problem related to stat() mode flag in plain http mode - clean of old C error code system Version - 0.2.5 - support for S3 auth tokens - add external gtest support - simplify build system - remove strlcpy dependency - add several Meta-data operation support - support for very large Vector IO query ( > 1000 chunks ) - support for IO prefecthing - add initial tools - bug fixe in the session reuse system - bug fixe in the redirection system - add stream support for Davix Uri - clean and re-organize headers - add support for dav:// davs:// s3:// and s3s:// schemes - several warnings correction from coverity scan - resolve several packaging issues - Inclusion of the prototype davix_copy feature: third party copy based on HTTP Version - 0.2.0 - Initial Stable version - Support POSIX and FILE API - Remote I/O read only - support for S3 - support for X509 / VOMS / Proxy credential - support for Vector IO - support for session reuse davix-R_0_5_0/cmake/000077500000000000000000000000001257152637300143455ustar00rootroot00000000000000davix-R_0_5_0/cmake/modules/000077500000000000000000000000001257152637300160155ustar00rootroot00000000000000davix-R_0_5_0/cmake/modules/CMakeCXX11Support.cmake000066400000000000000000000022141257152637300221200ustar00rootroot00000000000000include(CheckCXXSourceCompiles REQUIRED) if(CMAKE_COMPILER_IS_GNUCXX) execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7) SET(HAVE_CXX011_FULL_SUPPORT TRUE) SET(HAVE_CXX011_PARTIAL_SUPPORT TRUE) SET(CXX11_FLAG_ENABLE "-std=c++11") elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3) message(STATUS "C++11 partial support") SET(HAVE_CXX011_PARTIAL_SUPPORT TRUE) SET(CXX11_FLAG_ENABLE "-std=c++0x") else () message(STATUS "C++11 no support ") SET(CXX11_FLAG_ENABLE "") endif() else(CMAKE_COMPILER_IS_GNUCXX) message(STATUS "C++11 activated full") SET(HAVE_CXX011_FULL_SUPPORT TRUE) SET(HAVE_CXX011_PARTIAL_SUPPORT TRUE) SET(CXX11_FLAG_ENABLE "-std=c++0x") endif(CMAKE_COMPILER_IS_GNUCXX) ## Check TR1 CHECK_CXX_SOURCE_COMPILES(" #include int main() { return 0; }" HAVE_TR1_SUPPORT) if(HAVE_TR1_SUPPORT) message(STATUS "TR1 support detected") else(HAVE_TR1_SUPPORT) message(STATUS "no TR1 support") endif(HAVE_TR1_SUPPORT) davix-R_0_5_0/cmake/modules/CMakeGeneratePkgConfig.cmake000066400000000000000000000077231257152637300232530ustar00rootroot00000000000000# @title cmake macro for pkgconfig files generation # @brief generate a .pc package config file with a given name # @author Adrien Devresse include(DefineInstallationPaths REQUIRED) include(CMakeMacroParseArguments REQUIRED) include(CMakeStringHelpers REQUIRED) SET(CMAKE_PKGCONFIG_TEMPLATE "prefix=@PREFIX@ exec_prefix=@PREFIX@ libdir=@LIBDIR_VAR includedir=@INCLUDE_VAR@ Name: @NAME_PROJECT@ Description: @DESCRIPTION_PROJECT@ Version: @VERSION_PROJECT@ URL: @URL_PROJECT@ Requires: @REQUIRES_PROJECT@ Conflicts: @CONFLICTS_PROJECT@ Libs: @LIBS_PROJECT@ Libs.private: @LIBS_PRIVATE_PROJECT@ Cflags: @CFLAGS_PROJECT@ ") SET(CMAKE_PKGCONFIG_TEMPLATE_BASE " prefix=@PREFIX@ exec_prefix= \\\${prefix} libdir= @LIBDIR_VAR@ includedir=@INCLUDE_VAR@ Name: @NAME_PROJECT@ Description: @DESCRIPTION_PROJECT@ Version: @VERSION_PROJECT@ Requires: @REQUIRES_PROJECT@ Libs: @LIBS_PROJECT@ Cflags: @CFLAGS_PROJECT@ " ) LIST(APPEND CMAKE_PKGCONFIG_TEMPLATE_BASE_PATTERN "@PREFIX@" "@LIBDIR_VAR@" "@INCLUDE_VAR@" "@NAME_PROJECT@" "@DESCRIPTION_PROJECT@" "@VERSION_PROJECT@" "@REQUIRES_PROJECT@" "@LIBS_PROJECT@" "@CFLAGS_PROJECT@") # main function to use # FORMAT : add_PkgConfigFile_for_Library("string_filename.pc" target_library # [DESCRIPTION] "description of the pkgconfig files" # [HEADER_DIRS] dir1, dir2 # [REQUIRES] req1 req 2 ) # list of dir to include in $prefix/include/, ex : $prefix/include/dir1 # the pc file is produced in the ${CMAKE_CURRENT_BINARY_DIR} directory function(add_PkgConfigFile_for_Library) PARSE_ARGUMENTS(PKGCONFIGFILE "HEADER_DIRS;DESCRIPTION;REQUIRES;CFLAGS" "" ${ARGN} ) LIST(GET PKGCONFIGFILE_DEFAULT_ARGS 0 pkgconfig_filename) LIST(GET PKGCONFIGFILE_DEFAULT_ARGS 1 lib_target) LIST(GET PKGCONFIGFILE_DESCRIPTION 0 description) get_target_property(library_name ${lib_target} OUTPUT_NAME) get_target_property(library_version ${lib_target} VERSION) set(pkgconfig_prefix "${CMAKE_INSTALL_PREFIX}") set(pkgconfig_libdir_var "\\\${prefix}/lib${LIB_SUFFIX}") set(pkgconfig_include_var "\\\${prefix}/include") set(pkgconfig_linkflags "-l${library_name} -L\\\${libdir}") set(pkgconfig_name "${pkgconfig_filename}") set(pkgconfig_version "${library_version}") set(pkgconfig_description "pkgconfig file for ${library_name}") set(pkgconfig_requires " ") set(pkgconfig_cflags "") IF(PKGCONFIGFILE_REQUIRES) FOREACH(req ${PKGCONFIGFILE_REQUIRES}) set(pkgconfig_requires "${pkgconfig_requires} ${req}") ENDFOREACH(req PKGCONFIGFILE_REQUIRES) ENDIF(PKGCONFIGFILE_REQUIRES) IF(PKGCONFIGFILE_CFLAGS) FOREACH(req ${PKGCONFIGFILE_CFLAGS}) set(pkgconfig_cflags "${pkgconfig_cflags} ${req}") ENDFOREACH(req PKGCONFIGFILE_CFLAGS) ENDIF(PKGCONFIGFILE_CFLAGS) IF(PKGCONFIGFILE_HEADER_DIRS) FOREACH(dir ${PKGCONFIGFILE_HEADER_DIRS}) set(pkgconfig_includedir "${pkgconfig_includedir} -I\\\${includedir}/${dir}") ENDFOREACH(dir PKGCONFIGFILE_HEADER_DIRS) ELSE(PKGCONFIGFILE_HEADER_DIRS) set(pkgconfig_includedir " -I\\\${includedir}") ENDIF(PKGCONFIGFILE_HEADER_DIRS) IF(description) set(pkgconfig_description "${description}") ENDIF(description) set(pkgconfig_cflags "${pkgconfig_cflags} ${pkgconfig_includedir} ") LIST(APPEND pkgconfig_list_var ${pkgconfig_prefix} ${pkgconfig_libdir_var} ${pkgconfig_include_var} ${pkgconfig_name} ${pkgconfig_description} ${pkgconfig_version} ${pkgconfig_requires} ${pkgconfig_linkflags} ${pkgconfig_cflags}) replace_all_occurence(pc_file_content ${CMAKE_PKGCONFIG_TEMPLATE_BASE} LIST_PATTERN ${CMAKE_PKGCONFIG_TEMPLATE_BASE_PATTERN} LIST_REPLACER ${pkgconfig_list_var}) SET(filename "${CMAKE_CURRENT_BINARY_DIR}/${pkgconfig_filename}") FILE(WRITE ${filename} "${pc_file_content}" ) message(STATUS "generate pkgconfig file for ${lib_target} under ${filename}") endfunction(add_PkgConfigFile_for_Library) davix-R_0_5_0/cmake/modules/CMakeMacroParseArguments.cmake000066400000000000000000000020651257152637300236450ustar00rootroot00000000000000 MACRO(PARSE_ARGUMENTS prefix arg_names option_names) SET(DEFAULT_ARGS) FOREACH(arg_name ${arg_names}) SET(${prefix}_${arg_name}) ENDFOREACH(arg_name) FOREACH(option ${option_names}) SET(${prefix}_${option} FALSE) ENDFOREACH(option) SET(current_arg_name DEFAULT_ARGS) SET(current_arg_list) FOREACH(arg ${ARGN}) SET(larg_names ${arg_names}) LIST(FIND larg_names "${arg}" is_arg_name) IF (is_arg_name GREATER -1) SET(${prefix}_${current_arg_name} ${current_arg_list}) SET(current_arg_name ${arg}) SET(current_arg_list) ELSE (is_arg_name GREATER -1) SET(loption_names ${option_names}) LIST(FIND loption_names "${arg}" is_option) IF (is_option GREATER -1) SET(${prefix}_${arg} TRUE) ELSE (is_option GREATER -1) SET(current_arg_list ${current_arg_list} ${arg}) ENDIF (is_option GREATER -1) ENDIF (is_arg_name GREATER -1) ENDFOREACH(arg) SET(${prefix}_${current_arg_name} ${current_arg_list}) ENDMACRO(PARSE_ARGUMENTS) davix-R_0_5_0/cmake/modules/CMakeStringHelpers.cmake000066400000000000000000000023741257152637300225170ustar00rootroot00000000000000##convenience function for string manipulation function(replace_occurence output input pattern replacer) string(REGEX REPLACE ${pattern} ${replacer} tmp_str ${input}) set(${output} ${tmp_str} PARENT_SCOPE) endfunction(replace_occurence output input pattern replacer) function(replace_all_occurence) PARSE_ARGUMENTS(REPLACE_ALL "LIST_PATTERN;LIST_REPLACER" "" ${ARGN} ) LIST(APPEND list_pattern ${REPLACE_ALL_LIST_PATTERN}) LIST(APPEND list_replacer ${REPLACE_ALL_LIST_REPLACER}) LIST(LENGTH list_pattern list_size ) LIST(LENGTH list_replacer list2_size ) math(EXPR list_size ${list_size}-1) LIST(GET REPLACE_ALL_DEFAULT_ARGS 0 output_var) LIST(GET REPLACE_ALL_DEFAULT_ARGS 1 intput_content ) SET(tmp_str ${intput_content}) SET(tmp_str2 "") foreach(i RANGE ${list_size}) list(GET list_pattern ${i} current_pattern ) list(GET list_replacer ${i} current_replacer ) replace_occurence(tmp_str2 ${tmp_str} ${current_pattern} ${current_replacer} ) SET(tmp_str ${tmp_str2}) endforeach(i RANGE ${list_size}) SET(${output_var} ${tmp_str} PARENT_SCOPE) endfunction(replace_all_occurence) function(STRING_APPEND var_name content) SET(${var_name} "${${var_name}}${content}" PARENT_SCOPE) endfunction(STRING_APPEND var_name content) davix-R_0_5_0/cmake/modules/DefineInstallationPaths.cmake000066400000000000000000000117131257152637300235760ustar00rootroot00000000000000if (UNIX) IF (NOT APPLICATION_NAME) MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME") SET(APPLICATION_NAME ${PROJECT_NAME}) ENDIF (NOT APPLICATION_NAME) # detect lib suffix IF(EXISTS "/usr/lib64") SET(LIB_SUFFIX "64" CACHE STRING "Suffix of the lib") SET (PKG_ARCH "x86_64") ELSE(EXISTS "/usr/lib64" ) SET(LIB_SUFFIX "" CACHE STRING "Suffix of the lib") SET (PKG_ARCH "i386") ENDIF(EXISTS "/usr/lib64" ) # correct cmake netpath issue with cmake 2.8 IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/") SET(INTERNAL_BASE_PREFIX "") ELSE("${CMAKE_INSTALL_PREFIX}" STREQUAL "/") SET(INTERNAL_BASE_PREFIX "${CMAKE_INSTALL_PREFIX}") ENDIF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/") SET(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Base directory for executables and libraries" ) SET(SHARE_INSTALL_PREFIX "${INTERNAL_BASE_PREFIX}/share" CACHE PATH "Base directory for files which go to share/" ) SET(DATA_INSTALL_PREFIX "${INTERNAL_BASE_PREFIX}/${APPLICATION_NAME}" CACHE PATH "The parent directory where applications can install their data") # The following are directories where stuff will be installed to SET(BIN_INSTALL_DIR "${INTERNAL_BASE_PREFIX}/bin" CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)" ) SET(SBIN_INSTALL_DIR "${INTERNAL_BASE_PREFIX}/sbin" CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)" ) SET(LIB_INSTALL_DIR "${INTERNAL_BASE_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)" ) SET(LIBEXEC_INSTALL_DIR "${INTERNAL_BASE_PREFIX}/libexec" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)" ) SET(PKGCONFIG_FILES_DIR "${LIB_INSTALL_DIR}/pkgconfig/" CACHE PATH "subdirectory relative to the install prefix where pkgconfig files (.pc) will be installed" ) SET(PLUGIN_INSTALL_DIR "${LIB_INSTALL_DIR}/${APPLICATION_NAME}" CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})" ) SET(INCLUDE_INSTALL_DIR "${INTERNAL_BASE_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix (default prefix/include)" ) SET(DATA_INSTALL_DIR "${DATA_INSTALL_PREFIX}" CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})" ) SET(DOC_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/doc/${APPLICATION_NAME}" CACHE PATH "The parent directory where applications can install their documentation (default prefix/share/doc/${APPLICATION_NAME})" ) SET(HTML_INSTALL_DIR "${DATA_INSTALL_PREFIX}/doc/HTML" CACHE PATH "The HTML install dir for documentation (default data/doc/html)" ) SET(ICON_INSTALL_DIR "${DATA_INSTALL_PREFIX}/icons" CACHE PATH "The icon install dir (default data/icons/)" ) SET(SOUND_INSTALL_DIR "${DATA_INSTALL_PREFIX}/sounds" CACHE PATH "The install dir for sound files (default data/sounds)" ) SET(LOCALE_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/locale" CACHE PATH "The install dir for translations (default prefix/share/locale)" ) SET(XDG_APPS_DIR "${SHARE_INSTALL_PREFIX}/applications/" CACHE PATH "The XDG apps dir" ) SET(XDG_DIRECTORY_DIR "${SHARE_INSTALL_PREFIX}/desktop-directories" CACHE PATH "The XDG directory" ) SET(SYSCONF_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/etc" CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)" ) SET(MAN_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/man" CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)" ) SET(INFO_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/info" CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)" ) endif (UNIX) if (WIN32) # Same same SET(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Base directory for executables and libraries" ) set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "-") set(SBIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "-") set(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "-") set(INCLUDE_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/include" CACHE PATH "-") SET(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc" CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)" ) SET(PKGCONFIG_FILES_DIR "${EXEC_INSTALL_PREFIX}/lib/pkgconfig/" CACHE PATH "subdirectory relative to the install prefix where pkgconfig files (.pc) will be installed" ) set(PLUGIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin/plugins" CACHE PATH "-") set(HTML_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/doc/HTML" CACHE PATH "-") set(ICON_INSTALL_DIR "." CACHE PATH "-") set(SOUND_INSTALL_DIR "." CACHE PATH "-") set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-") endif (WIN32) davix-R_0_5_0/cmake/modules/FindCGSI_GSOAP.cmake000066400000000000000000000034201257152637300212750ustar00rootroot00000000000000# # This module detects if CGSI_GSOAP is installed and determines where the # include files and libraries are. # # This code sets the following variables: # # CGSI_GSOAP_LIBRARIES = full path to the CGSI_GSOAP libraries # CGSI_GSOAP_INCLUDE_DIR = include dir to be used when using the CGSI_GSOAP library # CGSI_GSOAP_FOUND = set to true if CGSI_GSOAP was found successfully # # CGSI_GSOAP_LOCATION # setting this enables search for CGSI_GSOAP libraries / headers in this location # ----------------------------------------------------- # CGSI_GSOAP Libraries # ----------------------------------------------------- find_library(CGSI_GSOAP_LIBRARIES NAMES cgsi_plugin cgsi_plugin_gsoap_2.7 HINTS ${CGSI_GSOAP_LOCATION}/lib ${CGSI_GSOAP_LOCATION}/lib64 ${CGSI_GSOAP_LOCATION}/lib32 ${STAGE_DIR}/lib ${STAGE_DIR}/lib64 DOC "The main CGSI_GSOAP library" ) # ----------------------------------------------------- # CGSI_GSOAP Include Directories # ----------------------------------------------------- find_path(CGSI_GSOAP_INCLUDE_DIR NAMES cgsi_plugin.h HINTS ${CGSI_GSOAP_LOCATION} ${CGSI_GSOAP_LOCATION}/include ${CGSI_GSOAP_LOCATION}/include/* ${STAGE_DIR}/include ${STAGE_DIR}/include DOC "The CGSI_GSOAP include directory" ) if(CGSI_GSOAP_INCLUDE_DIR) message(STATUS "CGSI_GSOAP includes found in ${CGSI_GSOAP_INCLUDE_DIR}") endif() # ----------------------------------------------------- # handle the QUIETLY and REQUIRED arguments and set CGSI_GSOAP_FOUND to TRUE if # all listed variables are TRUE # ----------------------------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CGSI_GSOAP DEFAULT_MSG CGSI_GSOAP_LIBRARIES CGSI_GSOAP_INCLUDE_DIR) mark_as_advanced(CGSI_GSOAP_INCLUDE_DIR CGSI_GSOAP_LIBRARIES) davix-R_0_5_0/cmake/modules/FindGRIDSITE.cmake000066400000000000000000000042731257152637300210400ustar00rootroot00000000000000# # This module detects if GRIDSITE is installed and determines where the # include files and libraries are. # # This code sets the following variables: # # GRIDSITE_LIBRARIES = full path to the GRIDSITE libraries # GRIDSITE_SSL_LIBRARIES = full path to the GRIDSITE ssl libraries # GRIDSITE_INCLUDE_DIR = include dir to be used when using the GRIDSITE library # GRIDSITE_WSDL2H = wsdl2h binary # GRIDSITE_SOAPCPP2 = soapcpp2 binary # GRIDSITE_FOUND = set to true if GRIDSITE was found successfully # # GRIDSITE_LOCATION # setting this enables search for GRIDSITE libraries / headers in this location # ------------------------------------------------------ # try pkg config search # # ----------------------------------------------------- find_package(PkgConfig) pkg_check_modules(PC_GRIDSITE QUIET gridsite-openssl>=1.7.25) IF(PC_GRIDSITE_FOUND) SET(GRIDSITE_LIBRARIES ${PC_GRIDSITE_LIBRARIES}) SET(GRIDSITE_INCLUDE_DIR ${PC_GRIDSITE_INCLUDE_DIRS}) SET(GRIDSITE_DEFINITIONS "${PC_GRIDSITE_CFLAGS} ${PC_GRIDSITE_CFLAGS_OTHER}") ELSE(PC_GRIDSITE_FOUND) # ----------------------------------------------------- # GRIDSITE Libraries # ----------------------------------------------------- find_library(GRIDSITE_LIBRARIES NAMES gridsite HINTS ${GRIDSITE_LOCATION}/lib ${GRIDSITE_LOCATION}/lib64 ${GRIDSITE_LOCATION}/lib32 DOC "The main GRIDSITE library" ) # ----------------------------------------------------- # GRIDSITE Include Directories # ----------------------------------------------------- find_path(GRIDSITE_INCLUDE_DIR NAMES gridsite.h HINTS ${GRIDSITE_LOCATION} ${GRIDSITE_LOCATION}/include ${GRIDSITE_LOCATION}/include/* DOC "The GRIDSITE include directory" ) SET(GRIDSITE_DEFINITIONS "") ENDIF(PC_GRIDSITE_FOUND) # ----------------------------------------------------- # handle the QUIETLY and REQUIRED arguments and set GRIDSITE_FOUND to TRUE if # all listed variables are TRUE # ----------------------------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GRIDSITE DEFAULT_MSG GRIDSITE_LIBRARIES GRIDSITE_INCLUDE_DIR) mark_as_advanced(GRIDSITE_INCLUDE_DIR GRIDSITE_LIBRARIES ) davix-R_0_5_0/cmake/modules/FindROOT.cmake000066400000000000000000000147161257152637300204140ustar00rootroot00000000000000# - Finds ROOT instalation # This module sets up ROOT information # It defines: # ROOT_FOUND If the ROOT is found # ROOT_INCLUDE_DIR PATH to the include directory # ROOT_INCLUDE_DIRS PATH to the include directories (not cached) # ROOT_LIBRARIES Most common libraries # ROOT__LIBRARY Full path to the library # ROOT_LIBRARY_DIR PATH to the library directory # # Updated by K. Smith (ksmith37@nd.edu) to properly handle # dependencies in ROOT_GENERATE_DICTIONARY find_program(ROOT_CONFIG_EXECUTABLE root-config PATHS $ENV{ROOTSYS}/bin) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --prefix OUTPUT_VARIABLE ROOTSYS OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --version OUTPUT_VARIABLE ROOT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --incdir OUTPUT_VARIABLE ROOT_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) set(ROOT_INCLUDE_DIRS ${ROOT_INCLUDE_DIR}) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --libdir OUTPUT_VARIABLE ROOT_LIBRARY_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) set(ROOT_LIBRARY_DIRS ${ROOT_LIBRARY_DIR}) set(rootlibs Core Cint RIO Net Hist Graf Graf3d Gpad Tree Rint Postscript Matrix Physics MathCore Thread) set(ROOT_LIBRARIES) foreach(_cpt ${rootlibs} ${ROOT_FIND_COMPONENTS}) find_library(ROOT_${_cpt}_LIBRARY ${_cpt} HINTS ${ROOT_LIBRARY_DIR}) if(ROOT_${_cpt}_LIBRARY) mark_as_advanced(ROOT_${_cpt}_LIBRARY) list(APPEND ROOT_LIBRARIES ${ROOT_${_cpt}_LIBRARY}) list(REMOVE_ITEM ROOT_FIND_COMPONENTS ${_cpt}) endif() endforeach() list(REMOVE_DUPLICATES ROOT_LIBRARIES) execute_process( COMMAND ${ROOT_CONFIG_EXECUTABLE} --features OUTPUT_VARIABLE _root_options OUTPUT_STRIP_TRAILING_WHITESPACE) foreach(_opt ${_root_options}) set(ROOT_${_opt}_FOUND TRUE) endforeach() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ROOT DEFAULT_MSG ROOT_CONFIG_EXECUTABLE ROOTSYS ROOT_VERSION ROOT_INCLUDE_DIR ROOT_LIBRARIES ROOT_LIBRARY_DIR) mark_as_advanced(ROOT_CONFIG_EXECUTABLE) include(CMakeParseArguments) find_program(ROOTCINT_EXECUTABLE rootcint PATHS $ENV{ROOTSYS}/bin) find_program(GENREFLEX_EXECUTABLE genreflex PATHS $ENV{ROOTSYS}/bin) find_package(GCCXML) #---------------------------------------------------------------------------- # function ROOT_GENERATE_DICTIONARY( dictionary # header1 header2 ... # LINKDEF linkdef1 ... # OPTIONS opt1...) function(ROOT_GENERATE_DICTIONARY dictionary) CMAKE_PARSE_ARGUMENTS(ARG "" "" "LINKDEF;OPTIONS" "" ${ARGN}) #---Get the list of include directories------------------ get_directory_property(incdirs INCLUDE_DIRECTORIES) set(includedirs) foreach( d ${incdirs}) set(includedirs ${includedirs} -I${d}) endforeach() #---Get the list of header files------------------------- set(headerfiles) foreach(fp ${ARG_UNPARSED_ARGUMENTS}) if(${fp} MATCHES "[*?]") # Is this header a globbing expression? file(GLOB files ${fp}) foreach(f ${files}) if(NOT f MATCHES LinkDef) # skip LinkDefs from globbing result set(headerfiles ${headerfiles} ${f}) endif() endforeach() else() find_file(headerFile ${fp} PATHS ${incdirs}) set(headerfiles ${headerfiles} ${headerFile}) unset(headerFile CACHE) endif() endforeach() #---Get LinkDef.h file------------------------------------ set(linkdefs) foreach( f ${ARG_LINKDEF}) find_file(linkFile ${f} PATHS ${incdirs}) set(linkdefs ${linkdefs} ${linkFile}) unset(linkFile CACHE) endforeach() #---call rootcint------------------------------------------ add_custom_command(OUTPUT ${dictionary}.cxx ${dictionary}.h COMMAND ${ROOTCINT_EXECUTABLE} -cint -f ${dictionary}.cxx -c ${ARG_OPTIONS} ${includedirs} ${headerfiles} ${linkdefs} DEPENDS ${headerfiles} ${linkdefs} VERBATIM) endfunction() #---------------------------------------------------------------------------- # function REFLEX_GENERATE_DICTIONARY(dictionary # header1 header2 ... # SELECTION selectionfile ... # OPTIONS opt1...) function(REFLEX_GENERATE_DICTIONARY dictionary) CMAKE_PARSE_ARGUMENTS(ARG "" "" "SELECTION;OPTIONS" "" ${ARGN}) #---Get the list of header files------------------------- set(headerfiles) foreach(fp ${ARG_UNPARSED_ARGUMENTS}) file(GLOB files ${fp}) if(files) foreach(f ${files}) set(headerfiles ${headerfiles} ${f}) endforeach() else() set(headerfiles ${headerfiles} ${fp}) endif() endforeach() #---Get Selection file------------------------------------ if(IS_ABSOLUTE ${ARG_SELECTION}) set(selectionfile ${ARG_SELECTION}) else() set(selectionfile ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_SELECTION}) endif() #---Get the list of include directories------------------ get_directory_property(incdirs INCLUDE_DIRECTORIES) set(includedirs) foreach( d ${incdirs}) set(includedirs ${includedirs} -I${d}) endforeach() #---Get preprocessor definitions-------------------------- get_directory_property(defs COMPILE_DEFINITIONS) foreach( d ${defs}) set(definitions ${definitions} -D${d}) endforeach() #---Nanes and others--------------------------------------- set(gensrcdict ${dictionary}.cpp) if(MSVC) set(gccxmlopts "--gccxmlopt=\"--gccxml-compiler cl\"") else() #set(gccxmlopts "--gccxmlopt=\'--gccxml-cxxflags -m64 \'") set(gccxmlopts) endif() #set(rootmapname ${dictionary}Dict.rootmap) #set(rootmapopts --rootmap=${rootmapname} --rootmap-lib=${libprefix}${dictionary}Dict) #---Check GCCXML and get path----------------------------- if(GCCXML) get_filename_component(gccxmlpath ${GCCXML} PATH) else() message(WARNING "GCCXML not found. Install and setup your environment to find 'gccxml' executable") endif() #---Actual command---------------------------------------- add_custom_command(OUTPUT ${gensrcdict} ${rootmapname} COMMAND ${GENREFLEX_EXECUTABLE} ${headerfiles} -o ${gensrcdict} ${gccxmlopts} ${rootmapopts} --select=${selectionfile} --gccxmlpath=${gccxmlpath} ${ARG_OPTIONS} ${includedirs} ${definitions} DEPENDS ${headerfiles} ${selectionfile}) endfunction() davix-R_0_5_0/cmake/modules/FindSOCKET.cmake000066400000000000000000000012171257152637300206110ustar00rootroot00000000000000# # This module detects if W32 SOCKETS are needed # include files and libraries are. # # This code sets the following variables: # # SOCKET_PKG_LIBRARIES = link flag for the w32 sockets if(MSYS) set(SOCKET_PKG_LIBRARIES "ws2_32") set(SOCKET_PKG_FOUND TRUE) # ----------------------------------------------------- # handle the QUIETLY and REQUIRED arguments and set LFC_FOUND to TRUE if # all listed variables are TRUE # ----------------------------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(SOCKET_PKG DEFAULT_MSG SOCKET_PKG_LIBRARIES) mark_as_advanced(SOCKET_PKG_LIBRARIES) endif(MSYS) davix-R_0_5_0/cmake/modules/FindgSOAP.cmake000066400000000000000000000060741257152637300205400ustar00rootroot00000000000000# # This module detects if gsoap is installed and determines where the # include files and libraries are. # # This code sets the following variables: # # GSOAP_LIBRARIES = full path to the gsoap libraries # GSOAP_SSL_LIBRARIES = full path to the gsoap ssl libraries # GSOAP_INCLUDE_DIR = include dir to be used when using the gsoap library # GSOAP_WSDL2H = wsdl2h binary # GSOAP_SOAPCPP2 = soapcpp2 binary # GSOAP_FOUND = set to true if gsoap was found successfully # # GSOAP_LOCATION # setting this enables search for gsoap libraries / headers in this location # ----------------------------------------------------- # GSOAP Libraries # ----------------------------------------------------- find_library(GSOAP_LIBRARIES NAMES gsoap HINTS ${GSOAP_LOCATION}/lib ${GSOAP_LOCATION}/lib64 ${GSOAP_LOCATION}/lib32 DOC "The main gsoap library" ) find_library(GSOAP_SSL_LIBRARIES NAMES gsoapssl HINTS ${GSOAP_LOCATION}/lib ${GSOAP_LOCATION}/lib64 ${GSOAP_LOCATION}/lib32 DOC "The ssl gsoap library" ) # ----------------------------------------------------- # GSOAP Include Directories # ----------------------------------------------------- find_path(GSOAP_INCLUDE_DIR NAMES stdsoap2.h HINTS ${GSOAP_LOCATION} ${GSOAP_LOCATION}/include ${GSOAP_LOCATION}/include/* DOC "The gsoap include directory" ) # ----------------------------------------------------- # GSOAP Binaries # ----------------------------------------------------- find_program(GSOAP_WSDL2H NAMES wsdl2h HINTS ${GSOAP_LOCATION}/bin DOC "The gsoap bin directory" ) find_program(GSOAP_SOAPCPP2 NAMES soapcpp2 HINTS ${GSOAP_LOCATION}/bin DOC "The gsoap bin directory" ) # ----------------------------------------------------- # GSOAP_276_COMPAT_FLAGS and GSOAPVERSION # try to determine the flagfor the 2.7.6 compatiblity, break with 2.7.13 and re-break with 2.7.16 # ---------------------------------------------------- message(STATUS " - wsdlh : ${GSOAP_WSDL2H}") message(STATUS " - SOAPCPP2 : ${GSOAP_SOAPCPP2}") execute_process(COMMAND ${GSOAP_SOAPCPP2} "-v" OUTPUT_VARIABLE GSOAP_STRING_VERSION ERROR_VARIABLE GSOAP_STRING_VERSION ) string(REGEX MATCH "[0-9]*\\.[0-9]*\\.[0-9]*" GSOAP_VERSION ${GSOAP_STRING_VERSION}) message(STATUS " - GSOAP VERSION : ${GSOAP_VERSION}") if( "${GSOAP_VERSION}" VERSION_LESS "2.7.6") set(GSOAP_276_COMPAT_FLAGS "") elseif ( "${GSOAP_VERSION}" VERSION_LESS "2.7.14") set(GSOAP_276_COMPAT_FLAGS "-z") else ( "${GSOAP_VERSION}" VERSION_LESS "2.7.14") set(GSOAP_276_COMPAT_FLAGS "-z1 -z2") endif ( "${GSOAP_VERSION}" VERSION_LESS "2.7.6") # ----------------------------------------------------- # handle the QUIETLY and REQUIRED arguments and set GSOAP_FOUND to TRUE if # all listed variables are TRUE # ----------------------------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(gsoap DEFAULT_MSG GSOAP_LIBRARIES GSOAP_INCLUDE_DIR GSOAP_WSDL2H GSOAP_SOAPCPP2) mark_as_advanced(GSOAP_INCLUDE_DIR GSOAP_LIBRARIES GSOAP_WSDL2H GSOAP_SOAPCPP2) davix-R_0_5_0/cmake/modules/MacroAddDoxygen.cmake000066400000000000000000000010611257152637300220250ustar00rootroot00000000000000## ## Doxygen macro, allow Doxygen generation from cmake ## do a ""make doc" for the generation macro(addDoxyGeneration DOXYFILE_LOCATION) find_package(Doxygen) if(DOXYGEN_FOUND) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${DOXYFILE_LOCATION} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM ) endif(DOXYGEN_FOUND) endmacro(addDoxyGeneration DOXYFILE_LOCATION) davix-R_0_5_0/cmake/modules/PortabilityGNUCheck.cmake000066400000000000000000000046241257152637300226370ustar00rootroot00000000000000# # This module setup common portability variables INCLUDE (CheckIncludeFiles) include(CheckIncludeFileCXX) INCLUDE (CheckFunctionExists) INCLUDE (CheckSymbolExists) INCLUDE (CheckLibraryExists) INCLUDE (CheckTypeSize) ## C func CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H) CHECK_INCLUDE_FILES (string.h HAVE_STRING_H) CHECK_INCLUDE_FILES (strings.h HAVE_STRINGS_H) CHECK_INCLUDE_FILES (locale.h HAVE_LOCALE_H) CHECK_INCLUDE_FILES(errno.h HAVE_ERRNO_H) CHECK_INCLUDE_FILES(stdlib.h HAVE_STDLIB_H) ## C++ header files CHECK_INCLUDE_FILE_CXX(ext/algorithm HAVE_EXT_ALGORITHM) ## SYSTEM CHECK_INCLUDE_FILES(sys/time.h HAVE_SYSTIME_H) CHECK_INCLUDE_FILES(sys/socket.h HAVE_SYSSOCKET_H) CHECK_INCLUDE_FILES(sys/poll.h HAVE_POLL_H) CHECK_INCLUDE_FILES(sys/select.h HAVE_SYS_SELECT_H) CHECK_FUNCTION_EXISTS(setsockopt HAVE_SETSOCKOPT) ## size type CHECK_TYPE_SIZE(int DEF_SIZEOF_INT) CHECK_TYPE_SIZE(long DEF_SIZEOF_LONG) CHECK_TYPE_SIZE(size_t DEF_SIZEOF_SIZE_T) CHECK_TYPE_SIZE(ssize_t DEF_SIZEOF_SSIZE_T) CHECK_TYPE_SIZE(off_t DEF_SIZEOF_OFF_T) ## POSIX CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) CHECK_INCLUDE_FILES(signal.h HAVE_SIGNAL_H) CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H) CHECK_INCLUDE_FILES(termios.h HAVE_TERMIOS_H) CHECK_FUNCTION_EXISTS(getpass HAVE_GETPASS) CHECK_FUNCTION_EXISTS(gmtime_r HAVE_GMTIME_R) CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY) CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME) ## Windows SET(CMAKE_EXTRA_INCLUDE_FILES "windows.h") CHECK_SYMBOL_EXISTS(SetConsoleMode "windows.h" HAVE_SETCONSOLEMODE) SET(CMAKE_EXTRA_INCLUDE_FILES) ## BSD ##GNU EXT #CHECK_FUNCTION_EXISTS(mempcpy HAVE_MEMPCPY_H) CHECK_FUNCTION_EXISTS(strptime HAVE_STRPTIME_H) #NET CHECK_INCLUDE_FILES(netdb.h HAVE_NETDB_H) CHECK_INCLUDE_FILES(arpa/inet.h HAVE_ARPA_INET_H) CHECK_INCLUDE_FILES(netinet/in.h HAVE_NETINET_IN_H) CHECK_INCLUDE_FILES(netinet/tcp.h HAVE_NETINET_TCP_H) SET(CMAKE_EXTRA_INCLUDE_FILES "arpa/inet.h") CHECK_TYPE_SIZE(in_addr_t DEF_SIZEOF_IN_ADDR_T) if(DEF_SIZEOF_IN_ADDR_T) set(HAVE_IN_ADDR_T 1) endif(DEF_SIZEOF_IN_ADDR_T) CHECK_TYPE_SIZE(socklen_t DEF_SIZEOF_SOCKLEN_T) if(DEF_SIZEOF_SOCKLEN_T) set(HAVE_SOCKLEN_T 1) endif(DEF_SIZEOF_SOCKLEN_T) CHECK_FUNCTION_EXISTS(getaddrinfo HAVE_GETADDRINFO_H) SET(CMAKE_EXTRA_INCLUDE_FILES) davix-R_0_5_0/cmake/modules/ReleaseDebugAutoFlags.cmake000066400000000000000000000005471257152637300231620ustar00rootroot00000000000000## debug / release autoManagement set(CMAKE_C_FLAGS_RELEASE "-O2") set(CMAKE_C_FLAGS_DEBUG "-g -Wall -Wextra -pedantic -fstack-protector-all") set(CMAKE_C_FLAGS_RELWITHDEBINFO " -Wall -g -O2") set(CMAKE_CXX_FLAGS_RELEASE "-O2") set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra -fstack-protector-all ") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO " -Wall -g -O2") davix-R_0_5_0/cmake_uninstall.cmake.in000066400000000000000000000016551257152637300200540ustar00rootroot00000000000000IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) STRING(REGEX REPLACE "\n" ";" files "${files}") FOREACH(file ${files}) MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") IF(EXISTS "$ENV{DESTDIR}${file}") EXEC_PROGRAM( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) IF(NOT "${rm_retval}" STREQUAL 0) MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") ENDIF(NOT "${rm_retval}" STREQUAL 0) ELSE(EXISTS "$ENV{DESTDIR}${file}") MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") ENDIF(EXISTS "$ENV{DESTDIR}${file}") ENDFOREACH(file) davix-R_0_5_0/deps/000077500000000000000000000000001257152637300142205ustar00rootroot00000000000000davix-R_0_5_0/deps/CMakeLists.txt000066400000000000000000000025101257152637300167560ustar00rootroot00000000000000### ## compile dependencies of davix IF(NOT HAVE_STRPTIME_H) SET(SRC_STRPTIME "${CMAKE_CURRENT_SOURCE_DIR}/strptime/strptime.c" PARENT_SCOPE) ELSE(NOT HAVE_STRPTIME_H) SET(SRC_STRPTIME "" PARENT_SCOPE) ENDIF(NOT HAVE_STRPTIME_H) SET(SRC_SIMPLE_GET_PASS "${CMAKE_CURRENT_SOURCE_DIR}/simple_getpass/simple_get_pass.cpp" PARENT_SCOPE) SET(SRC_STRING_UTILS_CPP "${CMAKE_CURRENT_SOURCE_DIR}/string_utils/stringutils.cpp" PARENT_SCOPE) #json parser SET(HEADER_RAPIDJSON "${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/include" PARENT_SCOPE) ## boost if(NOT Boost_FOUND) SET(Boost_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/boost_intern" PARENT_SCOPE) add_subdirectory(boost_intern/src) set(Boost_LIBRARIES boost_static_internal PARENT_SCOPE) endif(NOT Boost_FOUND) add_subdirectory(libneon) if(NOT HAVE_SYSSOCKET_H) set(SOCKET_PKG_LIBRARIES "ws2_32") endif(NOT HAVE_SYSSOCKET_H) SET(HTTPLIB_PKG_VERSION "0.29.0" PARENT_SCOPE) SET(HTTPLIB_PKG_STATIC_LIB_PATH "${CMAKE_CURRENT_BINARY_DIR}/libneon/src/libneon.a") SET(HTTPLIB_PKG_LIBRARIES ${HTTPLIB_PKG_STATIC_LIB_PATH} ${LIBSSL_PKG_LIBRARIES} ${LIBGSSAPI_PKG_LIBRARIES} ${LIBXML2_LIBRARIES} ${SOCKET_PKG_LIBRARIES} PARENT_SCOPE) SET(HTTPLIB_PKG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/libneon/src/ ${LIBXML2_INCLUDE_DIRS} ${LIBSSL_PKG_INCLUDE_DIRS} ${LIBGSSAPI_PKG_INCLUDE_DIRS} PARENT_SCOPE) davix-R_0_5_0/deps/boost_intern/000077500000000000000000000000001257152637300167255ustar00rootroot00000000000000davix-R_0_5_0/deps/http_util/000077500000000000000000000000001257152637300162345ustar00rootroot00000000000000davix-R_0_5_0/deps/http_util/http_util.cpp000066400000000000000000000000001257152637300207420ustar00rootroot00000000000000davix-R_0_5_0/deps/http_util/http_util.hpp000066400000000000000000000003711257152637300207620ustar00rootroot00000000000000#ifndef HTTP_UTIL_HPP #define HTTP_UTIL_HPP inline bool isValidHeaderChar(const char* p){ return (*p != '\0' && *p != '\n' && *p != '\r' && *p != ' ' && *p != '\t' ); } #endif // HTTP_UTIL_HPP davix-R_0_5_0/deps/libneon/000077500000000000000000000000001257152637300156465ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/.package000066400000000000000000000000501257152637300172350ustar00rootroot00000000000000announce-list=neon@lists.manyfish.co.uk davix-R_0_5_0/deps/libneon/.release.sh000077500000000000000000000014351257152637300177060ustar00rootroot00000000000000#!/bin/sh set -ex major=`echo $1 | awk -F. '{print $1;}'` minor=`echo $1 | awk -F. '{print $2;}'` release=`echo $1 | awk -F. '{print $3;}'` version=$1 for f in config.hw; do in=$f.in out=$f sed -e "s/@VERSION@/$version/g" \ -e "s/@MAJOR@/$major/g" \ -e "s/@MINOR@/$minor/g" \ -e "s/@RELEASE@/$release/g" \ -e "s,@top_srcdir@,`pwd`,g" < $in > $out done echo $1 > .version # for the documentation: date +"%e %B %Y" | tr -d '\n' > doc/date.xml echo -n $1 > doc/version.xml ALL_LINGUAS=`echo po/*.po | sed 's,po/,,g;s,\.po,,g'` # Try to create a valid Makefile tmp=`mktemp /tmp/neon-XXXXXX` sed -e 's,@SET_MAKE@,,;s,@SHELL@,/bin/sh,' \ -e "s,@top_srcdir@,`pwd`," \ -e "s,@ALL_LINGUAS@,${ALL_LINGUAS}," \ < Makefile.in > $tmp make -f $tmp docs compile-gmo rm -f $tmp davix-R_0_5_0/deps/libneon/.version000066400000000000000000000000071257152637300173310ustar00rootroot000000000000000.29.6 davix-R_0_5_0/deps/libneon/AUTHORS000066400000000000000000000007241257152637300167210ustar00rootroot00000000000000neon is Copyright (C) 1999-2007 Joe Orton Portions are: Copyright (C) 1999-2000 Tommi Komulainen Copyright (C) 1999-2000 Peter Boos Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. Copyright (C) 2004 Aleix Conchillo Flaque Copyright (C) 2004 Jiang Lei Copyright (C) 2004-2005 Vladimir Berezniker @ http://public.xdi.org/=vmpn davix-R_0_5_0/deps/libneon/BUGS000066400000000000000000000031521257152637300163320ustar00rootroot00000000000000 Known problems/bugs in neon -*- text -*- --------------------------- * several reports of issues with long-lived sessions causing problems with GSSAPI auth using mod_auth_kerb. May be a server problem, but needs further investigation to be sure. * 2818 requires that a on rejection of the SSL server cert, a "bad certificate" message should be sent - this is not being done currently (and can probably only be done with OpenSSL by actually doing cert verification in the verify callback) * ne_lock_discover does not handle multiple (shared) locks on a single resource. * SSL session caching issues; only cache for clean shutdowns, and only cache on shutdown, since the SSL_SESSION may change during an ne_session? * perhaps allow a per-Server-header hack for "Darwin Streaming Server 4.0" which doesn't terminate the response headers: http://bugzilla.gnome.org/show_bug.cgi?id=366331 HTTP/1.1 200 OK Server: Darwin Streaming Server 4.0 Content-Type: audio/mpeg Cache-Control: no-cache Pragma: no-cache Connection: close W8޳����s0�� * for a server with multiple A addresses, a successful connect() will "pin" that address for future attempts to connect. If subsequently a connect() fails, neon should at least iterate through the entire address list and at best should do the DNS lookup again. * should 207 code strclean the error string from the response body? * load_client_cert fails with: load_client_cert: (did not fail to load clicert without pkey) on RHEL4 openssl. * --with-ca-bundle only allows trusting a PEM bundle; support by directory as well davix-R_0_5_0/deps/libneon/CMakeLists.txt000066400000000000000000000020531257152637300204060ustar00rootroot00000000000000project(libneon-tuned) cmake_minimum_required (VERSION 2.6) # main file for src set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") # load module include(ReleaseDebugAutoFlags REQUIRED) include(PortabilityGNUCheck REQUIRED) set(OUTPUT_NAME_DAVIX "neon") set(VERSION_MAJOR 0) set(VERSION_MINOR 0) set(VERSION_PATCH 29) set(VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) find_package(SOCKET) find_package(LibXml2) if(LIBXML2_INCLUDE_DIR) set(HAVE_LIBXML 1) endif(LIBXML2_INCLUDE_DIR) set(HAVE_IPV6 ${ENABLE_IPV6}) set(TCP_NODELAY ${ENABLE_TCP_NODELAY}) configure_file(config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../ ${LIBXML2_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR}) add_definitions( -std=gnu99 -fPIC -DNEON_VERSION="${VERSION_STRING}" -DNE_VERSION_MAJOR=${VERSION_MAJOR} -DNE_VERSION_MINOR=${VERSION_MINOR} -Wno-unused-parameter) add_definitions( -fvisibility=hidden) add_subdirectory(src) davix-R_0_5_0/deps/libneon/ChangeLog000066400000000000000000007751011257152637300174330ustar00rootroot00000000000000------------------------------------------------------------------------ r1843 | joe | 2011-05-03 13:15:08 +0100 (Tue, 03 May 2011) | 1 line Tag release 0.29.6. ------------------------------------------------------------------------ r1842 | joe | 2011-05-03 13:14:56 +0100 (Tue, 03 May 2011) | 2 lines * macros/neon.m4: Bump to .6. ------------------------------------------------------------------------ r1841 | joe | 2011-05-03 13:09:46 +0100 (Tue, 03 May 2011) | 2 lines * NEWS: Tweak ordering. ------------------------------------------------------------------------ r1840 | joe | 2011-05-03 13:09:18 +0100 (Tue, 03 May 2011) | 2 lines * More news. ------------------------------------------------------------------------ r1839 | joe | 2011-05-03 13:07:08 +0100 (Tue, 03 May 2011) | 22 lines Merge r1836, r1837, r1838 from trunk: * src/ne_gnutls.c (ne__ssl_init): Fix for GnuTLS with Nettle. * src/ne_auth.c (get_cnonce): Likewise. Submitted by: Arfrever Frehtes Taifersar Arahesis * src/ne_auth.c (ah_post_send): Clear SSPI context only after successful authentication. Submitted by: Ivan Zhakov Fix some errors flagged by a Coverity scan: * src/ne_auth.c (verify_negotiate_response): Check for NULL pointer. * src/ne_gnutls.c (check_certificate): Initiatialize 'failures'. (pkcs12_parse): Check for _crt_init failure. * src/ne_session.c (ne__ssl_set_verify_err): Pass size-1 to strncat. ------------------------------------------------------------------------ r1835 | joe | 2011-03-01 13:28:28 +0000 (Tue, 01 Mar 2011) | 2 lines * NEWS: Update. ------------------------------------------------------------------------ r1834 | joe | 2011-03-01 13:26:04 +0000 (Tue, 01 Mar 2011) | 6 lines Merge r1833 from trunk: * src/ne_request.c (ne_request_create): Pass copied method to pre_send hooks to avoid lifetime issues (Patrick Ohly). ------------------------------------------------------------------------ r1832 | joe | 2010-11-11 12:32:11 +0000 (Thu, 11 Nov 2010) | 2 lines * macros/neon.m4: Really bump to -dev. ------------------------------------------------------------------------ r1831 | joe | 2010-11-11 12:31:39 +0000 (Thu, 11 Nov 2010) | 2 lines * macros/neon.m4, NEWS: Bump to .6-dev. ------------------------------------------------------------------------ r1830 | joe | 2010-11-11 12:29:51 +0000 (Thu, 11 Nov 2010) | 5 lines Merge r1827 from trunk: * doc/ref/iaddr.xml: Update ne_iaddr_* docs. ------------------------------------------------------------------------ r1829 | joe | 2010-11-11 12:26:45 +0000 (Thu, 11 Nov 2010) | 7 lines Merge r1828 from trunk: * src/ne_gnutls.c (provide_client_cert): Return success with no cert if no cert is available; match behaviour with OpenSSL. Thanks to Patrick Ohly. ------------------------------------------------------------------------ r1825 | joe | 2010-10-14 16:04:44 +0100 (Thu, 14 Oct 2010) | 2 lines * NEWS: Tweak. ------------------------------------------------------------------------ r1824 | joe | 2010-10-14 16:03:02 +0100 (Thu, 14 Oct 2010) | 2 lines * NEWS: Update with GnuTLS fix. ------------------------------------------------------------------------ r1823 | joe | 2010-10-14 16:02:41 +0100 (Thu, 14 Oct 2010) | 10 lines Merge r1818 from trunk: * test/socket.c (addr_reverse) [HAVE_GETHOSTNAME]: Accept system hostname as reverse of 127.0.0.1. * macros/neon-test.m4 (NEON_TEST): Check for gethostname(). Submitted by: joe Reviewed by: jorton ------------------------------------------------------------------------ r1822 | joe | 2010-10-14 16:01:53 +0100 (Thu, 14 Oct 2010) | 2 lines * NEWS, macros/neon.m4: Prepare for 0.29.5. ------------------------------------------------------------------------ r1821 | joe | 2010-10-14 16:00:53 +0100 (Thu, 14 Oct 2010) | 6 lines Merge r1797 from trunk: * src/ne_auth.c: Add handling of 2xx responses in SSPI code. (Danil Shopyrin ) ------------------------------------------------------------------------ r1820 | joe | 2010-10-09 17:07:17 +0100 (Sat, 09 Oct 2010) | 6 lines Merge r1819 from trunk: * src/ne_socket.c (ne_sock_connect_ssl): Ignore TLS warnings during handshake (Bryan Cain). ------------------------------------------------------------------------ r1816 | joe | 2010-10-01 13:00:02 +0100 (Fri, 01 Oct 2010) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1814 | joe | 2010-09-28 13:02:37 +0100 (Tue, 28 Sep 2010) | 2 lines * NEWS: Update. ------------------------------------------------------------------------ r1813 | joe | 2010-09-28 13:00:48 +0100 (Tue, 28 Sep 2010) | 10 lines Merge r1811 from trunk: * src/ne_session.c (ne__ssl_match_hostname): Deny a wildcard match against anything which parses as an IP address. * test/ssl.c (fail_wildcard_ip): Add test case. * test/makekeys.sh: Generate test wildcard IP cert. ------------------------------------------------------------------------ r1812 | joe | 2010-09-28 12:57:26 +0100 (Tue, 28 Sep 2010) | 8 lines Merge r1809 from trunk: * src/ne_request.c (open_connection): If SOCKS proxy fails, set return value to NE_ERROR. * test/request.c (socks_fail): Add test case. ------------------------------------------------------------------------ r1808 | joe | 2010-09-22 21:42:08 +0100 (Wed, 22 Sep 2010) | 2 lines * NEWS: Update for 0.29.4. ------------------------------------------------------------------------ r1807 | joe | 2010-09-22 20:33:36 +0100 (Wed, 22 Sep 2010) | 9 lines Merge r1801 from trunk: * src/ne_request.c (body_fd_send): Handle read() errors; thanks to Lou Montulli. * test/request.c (serve_mirror, send_length): Add test case. * test/Makefile.in (foobar.txt): Create test file. ------------------------------------------------------------------------ r1806 | joe | 2010-09-22 20:25:52 +0100 (Wed, 22 Sep 2010) | 8 lines Merge r1802, r1805 from trunk: * macros/neon.m4 (NE_CHECK_FUNCS): Fix AI_ADDRCONFIG detection. * src/ne_auth.c (ah_post_send): Always clear the SSPI context. (Danil Shopyrin) ------------------------------------------------------------------------ r1800 | joe | 2010-05-05 09:13:00 +0100 (Wed, 05 May 2010) | 5 lines Merge r1794 from trunk: * src/ne_session.c (ne_session_create): Fix to enable SNI by default again. (Tobias Gruetzmacher) ------------------------------------------------------------------------ r1796 | joe | 2010-03-29 10:19:04 +0100 (Mon, 29 Mar 2010) | 9 lines Merge r1792, r1793, r1795 from trunk: * src/ne_request.c (do_connect): Tweak debugging. * doc/ref/: Fix some refpurposes. * doc/ref/reqflags.xml: Doc tweak. ------------------------------------------------------------------------ r1790 | joe | 2010-02-08 09:52:54 +0000 (Mon, 08 Feb 2010) | 2 lines * macros/neon-test.m4: Test for signal.h ------------------------------------------------------------------------ r1787 | joe | 2010-01-11 22:59:31 +0000 (Mon, 11 Jan 2010) | 2 lines * macros/neon.m4, NEWS: Missed a backport :( ------------------------------------------------------------------------ r1786 | joe | 2010-01-11 22:57:34 +0000 (Mon, 11 Jan 2010) | 6 lines Merge r1777 from trunk: * src/ne_defs.h: Only define NE_PRIVATE if undefined. * configure.in: Define NE_PRIVATE to 'extern' for a static build. ------------------------------------------------------------------------ r1784 | joe | 2010-01-11 20:21:21 +0000 (Mon, 11 Jan 2010) | 2 lines * macros/neon.m4: Bump to 0.29.3. ------------------------------------------------------------------------ r1783 | joe | 2010-01-11 20:21:06 +0000 (Mon, 11 Jan 2010) | 2 lines * NEWS: Tweaks. ------------------------------------------------------------------------ r1782 | joe | 2010-01-11 10:40:42 +0000 (Mon, 11 Jan 2010) | 2 lines * NEWS: Document ne_sock_close() changes. ------------------------------------------------------------------------ r1781 | joe | 2010-01-11 10:36:14 +0000 (Mon, 11 Jan 2010) | 8 lines Merge r1780 from trunk: * src/ne_socket.c (ne_sock_close): Do not wait for the peer's close_notify alert with either GnuTLS or OpenSSL. [HAVE_GNUTLS]: Fix memory leak: free the session object. * src/ne_socket.h (ne_sock_close): Clarify close_notify handling. ------------------------------------------------------------------------ r1775 | joe | 2009-12-30 21:31:55 +0000 (Wed, 30 Dec 2009) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1774 | joe | 2009-12-30 21:31:30 +0000 (Wed, 30 Dec 2009) | 2 lines * macros/neon.m4: Bump version. ------------------------------------------------------------------------ r1773 | joe | 2009-12-30 21:30:55 +0000 (Wed, 30 Dec 2009) | 2 lines * NEWS: 0.29.2 news. ------------------------------------------------------------------------ r1772 | joe | 2009-12-30 21:29:30 +0000 (Wed, 30 Dec 2009) | 10 lines Merge r1748 from trunk: Clear sspi_token buffer after each request. * src/ne_auth.c (request_sspi): Return NULL if sspi_token is not present. * src/ne_auth.c (ah_post_send): Clear the buffered sspi_token. Submitted by: Danil Shopyrin ------------------------------------------------------------------------ r1771 | joe | 2009-12-30 21:28:48 +0000 (Wed, 30 Dec 2009) | 7 lines Merge r1770 from trunk: * src/ne_openssl.c (verify_callback): Handle OpenSSL error code X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT as an untrusted cert. Submitted by: Tom C ------------------------------------------------------------------------ r1767 | joe | 2009-12-15 22:24:26 +0000 (Tue, 15 Dec 2009) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1753 | joe | 2009-12-14 20:45:16 +0000 (Mon, 14 Dec 2009) | 2 lines * macros/neon.m4, NEWS: Prepare for 0.29.1. ------------------------------------------------------------------------ r1751 | joe | 2009-12-02 21:40:41 +0000 (Wed, 02 Dec 2009) | 4 lines Merge r1750 from trunk: * src/ne_gnutls.c (map_verify_failures): Fix build for GnuTLS < 2.8. ------------------------------------------------------------------------ r1749 | joe | 2009-12-02 21:27:34 +0000 (Wed, 02 Dec 2009) | 13 lines Merge r1739, r1744, r1746, r1747 from trunk: * config.hw.in: Fix socklen_t with recent SDKs, thanks to Stefan Kung. * src/ne_socket.c: Fixed 'missing symbol' win2k runtime problem. * src/ne_ntlm.c (ne__ntlm_authenticate) * src/ne_auth.c (ntlm_challenge): In case of session timeout, do not call auth callback; use existing credentials. * src/ne_ntlm.c (mkhash): Fix buffer overflow (basic@mozdev.org). ------------------------------------------------------------------------ r1743 | joe | 2009-10-25 11:25:24 +0000 (Sun, 25 Oct 2009) | 5 lines Merge r1742 from trunk: * src/ne_session.c (ne_session_create): Only enable SNI by default if the server hostname does not parse as a numeric IP address. ------------------------------------------------------------------------ r1740 | joe | 2009-09-26 20:58:08 +0100 (Sat, 26 Sep 2009) | 9 lines Merge r1738, r1739 from trunk: * src/ne_socket.c (ne_iaddr_parse): Fix Win32 build for both USE_GETADDRINFO and !USE_GETADDRINFO cases. * config.hw.in: Fix socklen_t with recent SDKs, thanks to Stefan Kung. Reviewed by: jorton ------------------------------------------------------------------------ r1735 | joe | 2009-09-13 13:12:27 +0100 (Sun, 13 Sep 2009) | 2 lines * macros/neon.m4: Don't ABI-tag LFS builds. ------------------------------------------------------------------------ r1733 | joe | 2009-09-13 12:57:58 +0100 (Sun, 13 Sep 2009) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1732 | joe | 2009-09-13 12:57:18 +0100 (Sun, 13 Sep 2009) | 2 lines * test/ssl.c (simple_sslv2): Skip better. ------------------------------------------------------------------------ r1731 | joe | 2009-09-13 12:56:25 +0100 (Sun, 13 Sep 2009) | 2 lines * test/ssl.c (simple_sslv2): Skip for OpenSSL. ------------------------------------------------------------------------ r1730 | joe | 2009-09-13 12:56:10 +0100 (Sun, 13 Sep 2009) | 2 lines * macros/neon.m4: Prep for 0.29.0. ------------------------------------------------------------------------ r1729 | joe | 2009-09-13 12:43:01 +0100 (Sun, 13 Sep 2009) | 2 lines * NEWS: Tweak wording. ------------------------------------------------------------------------ r1728 | joe | 2009-09-13 12:41:22 +0100 (Sun, 13 Sep 2009) | 2 lines * NEWS: Note OpenSSL 1.0 beta build fix. ------------------------------------------------------------------------ r1727 | joe | 2009-09-13 12:40:59 +0100 (Sun, 13 Sep 2009) | 5 lines Merge r1726 from trunk: * src/ne_socket.c (ne_sock_close) [HAVE_OPENSSL]: Ensure SSL connection is shut down cleanly. ------------------------------------------------------------------------ r1725 | joe | 2009-09-13 12:26:52 +0100 (Sun, 13 Sep 2009) | 10 lines Merge r1724 from trunk: * src/ne_openssl.c: Include opensslv.h. (SSL_SESSION_cmp): Define if not available, for OpenSSL >= 1.0. * src/ne_socket.c (ne_sock_accept_ssl): Add debug log output if session is resumed. * macros/neon.m4 (NEON_SSL): Check for SSL_SESSION_cmp. ------------------------------------------------------------------------ r1723 | joe | 2009-09-04 08:36:26 +0100 (Fri, 04 Sep 2009) | 6 lines Merge r1722 from trunk: * Makefile.in, README: Collect copyright notices from po/*. * po/: Update copyright notices. ------------------------------------------------------------------------ r1721 | joe | 2009-09-04 08:29:23 +0100 (Fri, 04 Sep 2009) | 2 lines * po/pl.po, NEWS: Update Polish translation (Arfrever Frehtes Taifersar Arahesis). ------------------------------------------------------------------------ r1720 | joe | 2009-09-04 08:27:49 +0100 (Fri, 04 Sep 2009) | 2 lines * NEWS: Update. ------------------------------------------------------------------------ r1717 | joe | 2009-09-02 21:44:08 +0100 (Wed, 02 Sep 2009) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1716 | joe | 2009-09-02 21:43:09 +0100 (Wed, 02 Sep 2009) | 2 lines * NEWS: Update. ------------------------------------------------------------------------ r1715 | joe | 2009-09-02 21:29:42 +0100 (Wed, 02 Sep 2009) | 10 lines Merge r1713, r1714 from trunk: * src/ne_request.c (socks_origin_lookup): New function. (open_connection): Use it to fix support for SOCKSv4 servers. * test/request.c (socks_v4_proxy): Add test case. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Require inet_pton for getaddrinfo support. ------------------------------------------------------------------------ r1712 | joe | 2009-09-02 20:43:05 +0100 (Wed, 02 Sep 2009) | 22 lines Merge r1709, r1710, r1711 from trunk: * test/util-socks.c (read_socks_0string): Pass through context string. (socks_server): Fail for v4 server without expected address. Don't write "ok" message for v4 server without say_hello flag. * src/ne_socket.c (ne_iaddr_parse): New function. * test/socket.c (check_is_raw127): Factored out from addr_make_v4. (parse_v4): New function. (addr_make_v6): Test ne_iaddr_parse for IPv6 addresses. (socks_proxy): Fix for non-v6-enabled builds. * src/ne_socket.c (ne_iaddr_parse) [!USE_GETADDRINFO]: Fail for IPv6 addresses. * test/socket.c (addr_make_v6) [!TEST_IPV6]: Test for failure. Also: * src/neon.vers: Add ne_iaddr_parse. ------------------------------------------------------------------------ r1708 | joe | 2009-09-02 15:51:26 +0100 (Wed, 02 Sep 2009) | 2 lines * macros/neon.m4: Set libtool versions as backwards-compat to 0.27.x. ------------------------------------------------------------------------ r1707 | joe | 2009-09-02 15:50:59 +0100 (Wed, 02 Sep 2009) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1706 | joe | 2009-09-02 15:40:47 +0100 (Wed, 02 Sep 2009) | 2 lines Branch for 0.29.x. ------------------------------------------------------------------------ r1705 | joe | 2009-09-02 15:40:13 +0100 (Wed, 02 Sep 2009) | 2 lines * macros/neon.m4: Import from gnulib. ------------------------------------------------------------------------ r1704 | joe | 2009-09-02 15:39:40 +0100 (Wed, 02 Sep 2009) | 5 lines * configure.in: Use a GNU linker script if supported, to enable symbol versioning. * src/neon.vers: Add linker script. ------------------------------------------------------------------------ r1703 | joe | 2009-09-02 15:04:43 +0100 (Wed, 02 Sep 2009) | 5 lines * src/ne_defs.h: Define NE_PRIVATE. * src/ne_privssl.h, src/ne_ntlm.h, src/ne_private.h: Mark all functions with NE_PRIVATE. ------------------------------------------------------------------------ r1702 | joe | 2009-09-02 14:51:05 +0100 (Wed, 02 Sep 2009) | 2 lines * NEWS: Update. ------------------------------------------------------------------------ r1701 | joe | 2009-09-01 21:49:56 +0100 (Tue, 01 Sep 2009) | 12 lines Minor cleanups to NTLM code: * src/ne_ntlm.c: Rename ne_ntlm_* to ne__ntlm_*. (mkhash): Use ne_malloc/ne_free. Avoid shadowing MD4 global. (ne_output_ntlm): Use ne_snprintf; cast size to size_t. (ne__ntlm_create_context): Return context pointer, don't fail. (ne__ntlm_destroy_context): Remove error path. (ne__ntlm_getRequestToken): Reflow. (ne_ntlm_clear_context): Remove noop function. * src/ne_ntlm.h, src/ne_auth.c: Adjust accordingly. ------------------------------------------------------------------------ r1700 | joe | 2009-09-01 21:13:12 +0100 (Tue, 01 Sep 2009) | 7 lines Split NE_AUTH_NEGOTIATE into NE_AUTH_GSSAPI and NE_AUTH_NTLM: * src/ne_auth.h (NE_AUTH_GSSAPI, NE_AUTH_NTLM): New constants. * src/ne_auth.c (auth_register): Map NE_AUTH_NEGOTIATE into NE_AUTH_GSSAPI | NE_AUTH_NTLM. ------------------------------------------------------------------------ r1699 | joe | 2009-09-01 16:09:13 +0100 (Tue, 01 Sep 2009) | 3 lines * src/ne_auth.c (digest_challenge): Simpler check for initial challenge. ------------------------------------------------------------------------ r1698 | joe | 2009-09-01 15:56:59 +0100 (Tue, 01 Sep 2009) | 2 lines * macros/neon.m4 (NEON_SSL): Define NTLM for OpenSSL builds. ------------------------------------------------------------------------ r1697 | joe | 2009-09-01 15:56:18 +0100 (Tue, 01 Sep 2009) | 2 lines * src/Makefile.in: Build ne_ntlm.c. ------------------------------------------------------------------------ r1696 | joe | 2009-09-01 15:44:59 +0100 (Tue, 01 Sep 2009) | 2 lines * src/ne_auth.c: Whitespace changes. ------------------------------------------------------------------------ r1695 | joe | 2009-09-01 15:27:20 +0100 (Tue, 01 Sep 2009) | 2 lines * NEWS: Update. ------------------------------------------------------------------------ r1694 | joe | 2009-09-01 15:27:02 +0100 (Tue, 01 Sep 2009) | 2 lines * README: Remove dupe. ------------------------------------------------------------------------ r1693 | joe | 2009-09-01 15:26:32 +0100 (Tue, 01 Sep 2009) | 9 lines Fix handling of stale=true in a RFC2069-style Digest challenge: * src/ne_auth.c (digest_challenge): Relax check for stale=true to cover 2069-style Digest auth. * test/auth.c (make_digest_header, digest_failure): Check for handling of stale=true with 2069 Digest. ------------------------------------------------------------------------ r1692 | joe | 2009-08-19 14:19:41 +0100 (Wed, 19 Aug 2009) | 2 lines * doc/security.xml: Wording fix. ------------------------------------------------------------------------ r1687 | joe | 2009-08-18 15:18:53 +0100 (Tue, 18 Aug 2009) | 12 lines Security fix for CVE-2009-2473: prevent the "billion laughs" attack against expat: * src/ne_xml.c (ne_xml_create) [HAVE_EXPAT]: Register entity decl handler. [HAVE_LIBXML]: Use xmlCtxtUseOptions interface. (entity_declaration): New function. * test/xml.c (fail_parse): Add billion laughs test case. * test/run.sh: Limit run-time CPU use to 120 seconds. ------------------------------------------------------------------------ r1686 | joe | 2009-08-18 14:50:29 +0100 (Tue, 18 Aug 2009) | 2 lines * test/ssl.c (fail_nul_*): Fix for VPATH builds. ------------------------------------------------------------------------ r1681 | joe | 2009-08-18 14:12:29 +0100 (Tue, 18 Aug 2009) | 27 lines Security fix for CVE-2009-2474, handling of "NUL" bytes in certificate names: * src/ne_private.h (ne__ssl_match_hostname): Take cn len, make cn const. * src/ne_session.c (ne__ssl_match_hostname): Drop handling of unqualified hostnames; check CN length matches. * src/ne_gnutls.c (check_identity): Adjust accordingly. * src/ne_openssl.c (append_dirstring): Use a quoted append for ASCII data. Check for embedded NUL bytes in UTF-8 data. (dup_ia5string): Use quoted append. * test/ssl.c (struct ssl_server_args): Add key field. (ssl_server): Use key field from args. (fail_ssl_request_with_error2): Rename from fail_ssl_request_with_error, add host, fakehost parameters. (fail_ssl_request_with_error): Reimplement using fail_ssl_request_with_error2. (fail_nul_cn, fail_nul_san, nulcn_identity): New tests. * test/nulca.pem, test/nulcn.pem, test/nulsan.pem, test/nulsrv.key: Add test cases, thanks to Tomas Hoger . ------------------------------------------------------------------------ r1680 | joe | 2009-08-11 16:50:33 +0100 (Tue, 11 Aug 2009) | 8 lines * src/ne_string.c (qappend_count, quoted_append): Factor out from ne_buffer_qappend. (ne_strnqdup): New function. * src/ne_string.h (ne_strnqdup): New prototype. * test/string-tests.c (qappend): Test for it. ------------------------------------------------------------------------ r1679 | joe | 2009-08-11 15:15:33 +0100 (Tue, 11 Aug 2009) | 6 lines * src/ne_string.c (ne_buffer_qappend): New function. * src/ne_string.h (ne_buffer_qappend): New prototype. * test/string-tests.c (qappend): New test case. ------------------------------------------------------------------------ r1678 | joe | 2009-08-11 15:08:20 +0100 (Tue, 11 Aug 2009) | 2 lines * Makefile.in: Avoid dupes in copyright notices. ------------------------------------------------------------------------ r1677 | joe | 2009-08-07 10:54:36 +0100 (Fri, 07 Aug 2009) | 2 lines * test/openssl.conf: Sign certs using SHA1 since GnuTLS fails MD5-signed certs. ------------------------------------------------------------------------ r1676 | joe | 2009-08-05 14:58:52 +0100 (Wed, 05 Aug 2009) | 6 lines * src/ne_string.c (ne_buffer_qappend): New function. * src/ne_string.h (ne_buffer_qappend): New prototype. * test/string-tests.c (qappend): New test case. ------------------------------------------------------------------------ r1675 | joe | 2009-08-05 14:01:26 +0100 (Wed, 05 Aug 2009) | 2 lines * src/ne_socket.c (ne_sock_peer): Fix strict-aliasing issue. ------------------------------------------------------------------------ r1671 | joe | 2009-07-02 22:15:24 +0100 (Thu, 02 Jul 2009) | 2 lines * README: "make update-copyright" ------------------------------------------------------------------------ r1670 | joe | 2009-07-02 22:14:33 +0100 (Thu, 02 Jul 2009) | 3 lines * src/ne_session.c: Updata copyright notices; Tommi's code was long-since replaced. ------------------------------------------------------------------------ r1669 | joe | 2009-07-02 22:12:36 +0100 (Thu, 02 Jul 2009) | 3 lines * src/ne_openssl.c, src/ne_socket.c: Update copyright notices; Tommi's code was long-since replaced. ------------------------------------------------------------------------ r1668 | joe | 2009-07-02 22:03:44 +0100 (Thu, 02 Jul 2009) | 2 lines * macros/neon.m4 (NEON_LIBPROXY): Correctly handle --without-libproxy. ------------------------------------------------------------------------ r1667 | joe | 2009-07-02 22:01:16 +0100 (Thu, 02 Jul 2009) | 2 lines * test/util-socks.c: Remove unnecessary #include. ------------------------------------------------------------------------ r1666 | joe | 2009-07-02 10:07:18 +0100 (Thu, 02 Jul 2009) | 3 lines * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Silence warnings with autoconf 2.6x; use AC_USE_SYSTEM_EXTENSIONS. ------------------------------------------------------------------------ r1665 | joe | 2009-07-02 10:05:48 +0100 (Thu, 02 Jul 2009) | 2 lines * configure.in: Reorder to prevent autoconf 2.6x warnings. ------------------------------------------------------------------------ r1662 | joe | 2009-06-09 14:30:51 +0100 (Tue, 09 Jun 2009) | 6 lines * src/ne_socket.c (timed_connect): Only enable O_NONBLOCK if it is not already enabled. (ne_sock_connect): Use SOCK_NONBLOCK if available, and use of SOCK_CLOEXEC has not previously failed, and a connect timeout is configured. ------------------------------------------------------------------------ r1661 | joe | 2009-06-09 11:33:43 +0100 (Tue, 09 Jun 2009) | 2 lines * README, Makefile.in: Update copyright-notice-collector. ------------------------------------------------------------------------ r1658 | joe | 2009-06-09 11:17:55 +0100 (Tue, 09 Jun 2009) | 3 lines * src/ne_socket.c (raw_connect): New function. (timed_connect): Use it to correctly handle EINTR. ------------------------------------------------------------------------ r1657 | joe | 2009-06-09 11:01:42 +0100 (Tue, 09 Jun 2009) | 2 lines * src/ne_socket.c (ne_sock_connect): Fix FD_CLOEXEC for !SOCK_CLOEXEC builds. ------------------------------------------------------------------------ r1656 | joe | 2009-06-09 10:54:54 +0100 (Tue, 09 Jun 2009) | 5 lines * src/ne_socket.c (ne_sock_connect): Fix forward compat with new-glibc/ old kernel cases - use SOCK_CLOEXEC only if no previous socket() call has failed with EINVAL. Retry such a failed socket() call. ------------------------------------------------------------------------ r1655 | joe | 2009-05-29 15:18:03 +0100 (Fri, 29 May 2009) | 9 lines * src/ne_session.c (ne__ssl_set_verify_err): Add error strings for NE_SSL_BADCHAIN, NE_SSL_REVOKED. * test/ssl.c (fail_ssl_request_with_error): Renamed from fail_ssl_request; take error string and test for it. (fail_ssl_request): Reimplment as wrapper for above. (fail_expired, fail_wrongCN, fail_untrusted_ca, fail_ca_expired): Use _with_error to test error strings. ------------------------------------------------------------------------ r1654 | joe | 2009-05-29 15:09:21 +0100 (Fri, 29 May 2009) | 3 lines * src/ne_gnutls.c (ne_ssl_context_create): Enable support for X.509v1 CA certs. ------------------------------------------------------------------------ r1653 | joe | 2009-04-30 14:44:52 +0100 (Thu, 30 Apr 2009) | 3 lines * test/makekeys.sh: Fix to ensure the "bad CAs" do assert the CA constraint as true. ------------------------------------------------------------------------ r1652 | joe | 2009-04-30 14:34:20 +0100 (Thu, 30 Apr 2009) | 3 lines * src/ne_gnutls.c (check_certificate): Correctly check validity times of certs within chain. ------------------------------------------------------------------------ r1651 | joe | 2009-04-30 14:19:59 +0100 (Thu, 30 Apr 2009) | 2 lines * test/ssl.c: Fix typos, no functional change. ------------------------------------------------------------------------ r1650 | kso | 2009-03-26 12:24:32 +0000 (Thu, 26 Mar 2009) | 1 line initial support for platform-independent NTLM auth ------------------------------------------------------------------------ r1648 | joe | 2009-03-11 13:08:34 +0000 (Wed, 11 Mar 2009) | 3 lines * macros/neon.m4 (NEON_LIBPROXY): Mark feature as disabled if built with --without-libproxy. ------------------------------------------------------------------------ r1647 | joe | 2009-03-05 11:49:54 +0000 (Thu, 05 Mar 2009) | 2 lines * test/uri-tests.c (resolve): Test API guarantee for resolved ->path. ------------------------------------------------------------------------ r1646 | joe | 2009-03-05 11:48:42 +0000 (Thu, 05 Mar 2009) | 2 lines * src/ne_ssl.h: Improve ne_ssl_clicert_* docs, specify object state. ------------------------------------------------------------------------ r1645 | joe | 2009-03-05 11:48:02 +0000 (Thu, 05 Mar 2009) | 9 lines Be strict in parsing C-L response header: * src/ne_request.c (ne_begin_request): Fail for a C-L with trailing non-numeric chars, or is an empty string. * test/request.c (no_body_empty_clength, no_body_bad_clength): Remove tests. (fail_on_invalid): Add tests for invalid C-L. ------------------------------------------------------------------------ r1644 | joe | 2009-03-04 14:31:40 +0000 (Wed, 04 Mar 2009) | 2 lines * test/common/tests.c: Remove sys/signal.h include. ------------------------------------------------------------------------ r1643 | joe | 2009-03-03 21:50:21 +0000 (Tue, 03 Mar 2009) | 3 lines * src/ne_session.h: Define NE_SSL_REVOKED; bump NE_SSL_FAILMASK, reflow NE_SSL_* text. ------------------------------------------------------------------------ r1642 | joe | 2009-03-03 21:45:19 +0000 (Tue, 03 Mar 2009) | 2 lines * test/: Ignore more. ------------------------------------------------------------------------ r1641 | joe | 2009-03-03 21:44:05 +0000 (Tue, 03 Mar 2009) | 23 lines Expose the cert verification failure case where a cert higher in the validation chain is outside its validity-period; test cases and thanks to Ludwig Nussel: * src/ne_session.h (NE_SSL_BADCHAIN): New constant. (NE_SSL_FAILMASK): Bumped up. * src/ne_gnutls.c (check_certificate): Check validity period of all certs in the chain; flag NE_SSL_BADCHAIN appropriately. * src/ne_openssl.c (verify_cert): New function. (check_certificate): Rely on failure bits collected via verify_cert invocations. (ne_ssl_context_create): Install verify_cert as OpenSSL verify callback. (ne__negotiate_ssl): Clear ctx->failures. * test/makekeys.sh, test/openssl.conf: Create ca[1-3] with ca1, ca3 being expired and not-yet-valid respectively; create ca[13]server.cert signed by these CAs. * test/ssl.c (fail_ca_notyetvalid, fail_ca_expired): New test cases. ------------------------------------------------------------------------ r1640 | joe | 2009-03-03 21:34:25 +0000 (Tue, 03 Mar 2009) | 2 lines * NEWS: Sync with 0.28.x. ------------------------------------------------------------------------ r1639 | joe | 2009-03-03 21:33:34 +0000 (Tue, 03 Mar 2009) | 2 lines * doc/feat.xml: Update for trunk. ------------------------------------------------------------------------ r1633 | joe | 2009-02-25 14:04:42 +0000 (Wed, 25 Feb 2009) | 3 lines * doc/man.xsl, doc/manual.xml: Fix and quieten newer docbook-xsl man page generation. ------------------------------------------------------------------------ r1630 | joe | 2009-02-25 13:50:12 +0000 (Wed, 25 Feb 2009) | 2 lines * install-sh: Remove; rely on provided version. ------------------------------------------------------------------------ r1628 | joe | 2009-02-25 13:45:09 +0000 (Wed, 25 Feb 2009) | 7 lines Fix ne_forget_auth(): * src/ne_auth.c (clean_session): Clear ->protocol field; patch frm Kai Sommerfeld. * test/auth.c (serve_forgotten, forget): New test case. ------------------------------------------------------------------------ r1626 | joe | 2009-01-29 01:18:00 +0000 (Thu, 29 Jan 2009) | 2 lines * macros/neon.m4: Add the hash back into PKCS#11 in output messages. ------------------------------------------------------------------------ r1622 | joe | 2009-01-29 01:13:07 +0000 (Thu, 29 Jan 2009) | 2 lines * doc/ref/neon.xml: Add pakchois and libproxy namespaces. ------------------------------------------------------------------------ r1621 | joe | 2009-01-29 01:06:30 +0000 (Thu, 29 Jan 2009) | 3 lines * doc/ref/neon.xml: Add note on lack of async-signal-safety, and fix a typo. ------------------------------------------------------------------------ r1620 | joe | 2009-01-21 14:01:22 +0000 (Wed, 21 Jan 2009) | 3 lines * src/ne_socket.c (read_gnutls): Perform a new handshake if required and indicated by a gnutls_record_recv() failure. ------------------------------------------------------------------------ r1619 | joe | 2009-01-21 13:39:44 +0000 (Wed, 21 Jan 2009) | 2 lines * src/ne_basic.h: Docs updates. ------------------------------------------------------------------------ r1618 | joe | 2009-01-14 15:17:11 +0000 (Wed, 14 Jan 2009) | 2 lines * THANKS: Convert to UTF-8. ------------------------------------------------------------------------ r1617 | joe | 2008-12-10 08:22:49 +0000 (Wed, 10 Dec 2008) | 3 lines * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Check for socket functions in -lnetwork, for Haiku. ------------------------------------------------------------------------ r1616 | joe | 2008-11-21 20:45:48 +0000 (Fri, 21 Nov 2008) | 2 lines * Makefile.in: Fix Makefile/neon-config generation in VPATH builds. ------------------------------------------------------------------------ r1614 | joe | 2008-11-20 21:42:44 +0000 (Thu, 20 Nov 2008) | 2 lines * src/ne_pkcs11.c (pk11_provide): Fix memory leak. ------------------------------------------------------------------------ r1613 | joe | 2008-11-20 21:30:25 +0000 (Thu, 20 Nov 2008) | 2 lines * NEWS: More news is good news. ------------------------------------------------------------------------ r1612 | joe | 2008-11-20 21:28:54 +0000 (Thu, 20 Nov 2008) | 2 lines * configure.in: Add notice for forced PIC usage. ------------------------------------------------------------------------ r1611 | joe | 2008-11-20 21:27:24 +0000 (Thu, 20 Nov 2008) | 2 lines * macros/neon.m4: Drop SOCKS tests. ------------------------------------------------------------------------ r1610 | joe | 2008-11-20 20:59:09 +0000 (Thu, 20 Nov 2008) | 2 lines * NEWS: Synch with 0.28.x, update to trunk. ------------------------------------------------------------------------ r1609 | joe | 2008-11-20 20:56:15 +0000 (Thu, 20 Nov 2008) | 3 lines * src/ne_alloc.c, src/ne_alloc.h (ne_free): Implement as function on Win32, thanks to Helge Hess. ------------------------------------------------------------------------ r1599 | joe | 2008-11-04 20:49:35 +0000 (Tue, 04 Nov 2008) | 3 lines * src/ne_socket.c (ne_sock_connect): Use SOCK_CLOEXEC in place of setting the O_CLOEXEC flag, where available. ------------------------------------------------------------------------ r1597 | joe | 2008-11-04 18:24:19 +0000 (Tue, 04 Nov 2008) | 2 lines * test/request.c (status, status_chunked): Fix memory leak. ------------------------------------------------------------------------ r1594 | joe | 2008-10-31 08:59:02 +0000 (Fri, 31 Oct 2008) | 3 lines * macros/neon.m4 (NEON_SSL): Configure GnuTLS support via pkg-config data if possible. ------------------------------------------------------------------------ r1589 | joe | 2008-10-30 20:10:40 +0000 (Thu, 30 Oct 2008) | 6 lines * src/ne_gnutls.c (pkcs12_parse): Ignore any but the first key or cert encountered. Should fix issues with PKCS#12 files with embedded CA certs, see Debian bug 480041. * test/ssl.c (client_cert_ca): Add test case. ------------------------------------------------------------------------ r1587 | joe | 2008-10-28 20:56:16 +0000 (Tue, 28 Oct 2008) | 3 lines * src/ne_session.c (ne_session_sysproxy): Don't use ne_free for memory not allocated by neon. ------------------------------------------------------------------------ r1586 | joe | 2008-10-24 16:14:40 +0100 (Fri, 24 Oct 2008) | 5 lines * test/makekeys.sh, test/openssl.conf: Missed in previous commit; update for new altname test cases. Submitted by: Ludwig Nussel ------------------------------------------------------------------------ r1585 | joe | 2008-10-24 16:13:11 +0100 (Fri, 24 Oct 2008) | 4 lines * test/ssl.c (wildcard_match_altname, fail_wildcard): New test cases. Submitted by: Ludwig Nussel ------------------------------------------------------------------------ r1584 | joe | 2008-10-24 16:10:44 +0100 (Fri, 24 Oct 2008) | 4 lines * test/makekeys.sh: Create useful certs for standalone testing. Submitted by: Ludwig Nussel ------------------------------------------------------------------------ r1583 | joe | 2008-10-24 16:09:35 +0100 (Fri, 24 Oct 2008) | 2 lines * test/common/tests.c (print_prefix): Fix for non-quiet mode. ------------------------------------------------------------------------ r1582 | joe | 2008-10-24 16:06:30 +0100 (Fri, 24 Oct 2008) | 3 lines * test/common/tests.c (print_prefix): New function, factored out of main. (main): Use it. ------------------------------------------------------------------------ r1581 | joe | 2008-10-24 12:54:23 +0100 (Fri, 24 Oct 2008) | 2 lines * src/ne_session.c (ne_session_sysproxy): Free returned proxy array. ------------------------------------------------------------------------ r1579 | joe | 2008-10-24 11:01:33 +0100 (Fri, 24 Oct 2008) | 3 lines * doc/ref/sessflags.xml: Document _EXPECT100 flag, add xref to reqflags document. ------------------------------------------------------------------------ r1578 | joe | 2008-10-24 10:56:37 +0100 (Fri, 24 Oct 2008) | 7 lines * src/ne_session.h (ne_session_flag_e): Add NE_SESSFLAG_EXPECT100. * src/ne_request.c (build_request): Only add Expect header if req->body_length is non-zero. (ne_request_create): Set NE_REQFLAG_EXPECT100 according to NE_SESSFLAG_EXPECT100 value. ------------------------------------------------------------------------ r1570 | joe | 2008-10-14 21:50:24 +0100 (Tue, 14 Oct 2008) | 2 lines * src/ne_acl.h: Add deprecation notice. ------------------------------------------------------------------------ r1569 | joe | 2008-10-14 20:53:52 +0100 (Tue, 14 Oct 2008) | 2 lines * test/: Ignore more. ------------------------------------------------------------------------ r1568 | joe | 2008-10-14 20:21:04 +0100 (Tue, 14 Oct 2008) | 2 lines * Makefile.in (DIST_HEADERS): Add new ACL interface. ------------------------------------------------------------------------ r1567 | joe | 2008-10-14 20:19:41 +0100 (Tue, 14 Oct 2008) | 23 lines Introduce new ACL interface under separate header, function name, and restore API/ABI backwards-compat with old ACL interface: * src/ne_acl3744.c, src/ne_acl3744.h: Renamed from ne_acl.c, ne_acl.h. (ne_acl3744_set): Renamed from ne_acl_set. * src/ne_oldacl.c, src/ne_acl.h: Copied from old ne_acl.c, ne_acl.h on 0.28.x branch. * src/Makefile.in: Update deps. * test/acl3744.c: Renamed from acl.c. (test_acl): Call new function name. * test/oldacl.c: Copied from acl.c on 0.28.x branch. * test/Makefile.in: Update accordingly. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Update for new source file names. * neon.mak: Update for new source file names. ------------------------------------------------------------------------ r1561 | joe | 2008-10-10 08:35:16 +0100 (Fri, 10 Oct 2008) | 2 lines * src/ne_session.c (ne_session_system_proxy): Fix "direct" proxy. ------------------------------------------------------------------------ r1560 | joe | 2008-10-09 21:58:58 +0100 (Thu, 09 Oct 2008) | 11 lines Add support for use of a system-provided default set of proxy servers; implemented using libproxy: * macros/neon.m4 (NEON_LIBPROXY): New macro. (LIBNEON_SOURCE_CHECKS): Use it. (NE_PKG_CONFIG): Fix for non-alpha characters. * src/ne_session.c (ne_session_system_proxy): New function. * src/ne_session.h (ne_session_system_proxy): New prototype. ------------------------------------------------------------------------ r1559 | joe | 2008-10-09 21:18:52 +0100 (Thu, 09 Oct 2008) | 14 lines Add support for configuring a SOCKS proxy for the HTTP session: * src/ne_request.c (open_connection): Fix non-proxy error path. Establish connection via SOCKS proxy. * src/ne_session.c (ne_session_socks_proxy): New function. * src/ne_session.h (ne_session_socks_proxy): New prototype. * src/ne_private.h (struct ne_session_s): Add socks_ver, socks_user, socks_password fields. * test/request.c (socks_session, socks_proxy): New functions. ------------------------------------------------------------------------ r1558 | joe | 2008-10-09 21:10:50 +0100 (Thu, 09 Oct 2008) | 17 lines Factor SOCKS server out test/socket.c to be usable throughout test suite: * test/util-socks.c: New file, extracted from socket.c. * test/utils.h (socks_server, full_write): New prototypes. (struct socks_server): Moved here from socket.c; added say_hello flag. * test/utils.c (full_write): Moved here from socket.c. * test/socket.c (full_write, read_socks_string, read_socks_byte, expect_socks_byte, read_socks_0string, socks_server): Removed. (begin_socks): Set say_hello flag. * test/Makefile.in: Build util-socks.lo. ------------------------------------------------------------------------ r1557 | joe | 2008-10-09 19:48:31 +0100 (Thu, 09 Oct 2008) | 40 lines Add support for multiple proxies and differentiate between a SOCKS and HTTP proxy (though the former cannot yet be configured or used). Reimplement addrlist support as a "direct" proxy type. * src/ne_private.h (struct host_info): Add proxy enum, network field, next pointer. (struct ne_session_s): Remove addrlist, numaddr, curaddr. Remove proxy field, add proxies, prev_proxy, nexthop fields. Remove use_proxy, add any_proxy_http flag. * src/ne_session.c (free_hostinfo, free_proxies): New functions. (ne_session_destroy): Use the above. (set_hostinfo): Take type argument, set in structure. (ne_session_create): Pass PROXY_NONE to set_hostinfo. (ne_session_proxy): Call free_proxies, set sess->any_proxy_http flag, and adjust for new sess->proxies structure. (ne_set_addrlist): Adjust to set up a "direct" proxy. (ne_fill_proxy_uri): Adjust for proxies structure. (ne_close_connection): Use nexthop hostname for disconnect notifier. * src/ne_session.h (ne_session_proxy, ne_set_addrlist, ne_fill_proxy_uri): Adjust for multi-proxy semantics. * src/ne_request.c (aborted): Use sess->nexthop. (add_fixed_headers): Use new any_proxy_http flag. Reflow code. Set Host header here. (ne_request_create): Use any_proxy_http flag. (build_request): Don't add Host header here. (lookup_host): Don't check addrlist. (ne_begin_request): Use sess->nexthop in place of proxy flag. (resolve_first, resolve_next): Use ->network in place of addrlist; drop session paramater. (do_connect): Do DNS lookup here; adjust for resolve_*; set error message appropriately based on host type, drop error parameter. (open_connection): Support multiple proxies; adjust to use sess->nexthop. * test/request.c (addrlist): New test case. ------------------------------------------------------------------------ r1556 | joe | 2008-10-06 10:43:06 +0100 (Mon, 06 Oct 2008) | 2 lines * src/ne_gnutls.c (make_peers_chain): Fix potential segfault. ------------------------------------------------------------------------ r1544 | joe | 2008-09-11 15:39:43 +0100 (Thu, 11 Sep 2008) | 3 lines * src/ne_pkcs11.c (pk11_rsa_method): Remove redundant flag from the RSA_METHOD flags bitfield, and update comment. ------------------------------------------------------------------------ r1543 | joe | 2008-09-08 20:20:22 +0100 (Mon, 08 Sep 2008) | 2 lines * macros/neon.m4 (NEON_SSL): Fix pakchois/GnuTLS support. ------------------------------------------------------------------------ r1542 | joe | 2008-09-01 09:31:52 +0100 (Mon, 01 Sep 2008) | 2 lines * src/ne_pkcs11.c: Revert debugging change in previous commit. ------------------------------------------------------------------------ r1541 | joe | 2008-08-31 10:56:10 +0100 (Sun, 31 Aug 2008) | 13 lines Support PKCS#11 in OpenSSL builds: * src/ne_openssl.c (ne__ssl_clicert_exkey_import): New function. * src/ne_privssl.h (ne__ssl_clicert_exkey_import): New prototype. * src/ne_pkcs11.c [HAVE_OPENSSL] (pk11_rsa_sign, pk11_rsa_init, pk11_rsa_finish, pk11_rsa_method): New functions. (pk11_find_pkey): Ignore DSA privkeys if using OpenSSL. (ne_ssl_set_pkcs11_provider): Omit GnuTLS code for OpenSSL. * macros/neon.m4 (NEON_SSL): Support pakchois with OpenSSL too. ------------------------------------------------------------------------ r1540 | joe | 2008-08-22 12:43:28 +0100 (Fri, 22 Aug 2008) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1539 | joe | 2008-08-22 12:40:26 +0100 (Fri, 22 Aug 2008) | 2 lines * po/pl.po: Update from Arfrever Frehtes Taifersar Arahesis. ------------------------------------------------------------------------ r1532 | joe | 2008-08-20 19:45:19 +0100 (Wed, 20 Aug 2008) | 11 lines SECURITY (CVE-2008-3746): Fix a possible NULL pointer dereference in the Digest domain parameter support, which allows a malicious server to crash the library, resulting in a possible denial of service attack. * src/ne_auth.c (parse_domain): Ensure that URI ->path fields passed to ne_uri_resolve are non-NULL. * test/auth.c (CVE_2008_3746): Add test case. ------------------------------------------------------------------------ r1531 | joe | 2008-08-08 14:26:10 +0100 (Fri, 08 Aug 2008) | 2 lines * test/request.c (send_bad_offset): Tweak error message. ------------------------------------------------------------------------ r1530 | joe | 2008-08-07 10:03:37 +0100 (Thu, 07 Aug 2008) | 3 lines * test/request.c (status_chunked, status): Cope with systems where 'localhost' resolves to ::1 not 127.0.0.1. ------------------------------------------------------------------------ r1529 | joe | 2008-08-06 11:00:07 +0100 (Wed, 06 Aug 2008) | 3 lines * test/common/child.c (await_server): Describe failure better. (spawn_server_addr): Print exit code to debug log. ------------------------------------------------------------------------ r1528 | joe | 2008-08-06 10:53:38 +0100 (Wed, 06 Aug 2008) | 2 lines * doc/security.xml: Update intro and auth sections. ------------------------------------------------------------------------ r1527 | joe | 2008-08-05 16:32:47 +0100 (Tue, 05 Aug 2008) | 3 lines * src/ne_uri.h (ne_uri_parse, ne_uri_resolve): Clarify API constraints and guarantees on path being non-NULL on success. ------------------------------------------------------------------------ r1524 | joe | 2008-08-05 13:19:30 +0100 (Tue, 05 Aug 2008) | 2 lines * src/ne_session.h: Clarify that progress increments. ------------------------------------------------------------------------ r1522 | joe | 2008-08-03 20:17:23 +0100 (Sun, 03 Aug 2008) | 10 lines * src/ne_socket.c (struct iofns): Add swritev member. (writev_raw, writev_dummy, ne_sock_fullwritev): New functions. * src/ne_socket.h (struct ne_iovec): New structure. (ne_sock_fullwritev): New prototype. * test/socket.c (full_writev, large_writev): New test case. Submitted by: Julien.Reichel@spinetix.com, Joe ------------------------------------------------------------------------ r1517 | joe | 2008-07-25 16:37:27 +0100 (Fri, 25 Jul 2008) | 2 lines * BUGS: Note ca-bundle feature/bug. ------------------------------------------------------------------------ r1514 | joe | 2008-07-25 00:02:36 +0100 (Fri, 25 Jul 2008) | 7 lines * src/ne_session.c [NE_HAVE_SSL] (ne__ssl_match_hostname): New function, merged from duplicate copies in ne_openssl.c/ne_gnutls.c. * src/ne_private.h (ne__ssl_match_hostname): New prototype. * src/ne_openssl.c, src/ne_gnutls.c (match_hostname): Remove function. ------------------------------------------------------------------------ r1513 | joe | 2008-07-24 16:42:24 +0100 (Thu, 24 Jul 2008) | 4 lines * src/ne_request.c (body_fd_send): Fix compiler warnings. Submitted by: Henrik Holst ------------------------------------------------------------------------ r1512 | joe | 2008-07-20 21:10:11 +0100 (Sun, 20 Jul 2008) | 5 lines * src/ne_gnutls.c (provide_client_cert): Set ssl_cc_requested flag if no client cert is provided. (ne__negotiate_ssl): Give useful error message if handshake fails and ssl_cc_requested flag is set. ------------------------------------------------------------------------ r1509 | joe | 2008-07-19 22:52:35 +0100 (Sat, 19 Jul 2008) | 4 lines Update mailing list address throughout. * doc/using-neon.txt: Remove stale doc. ------------------------------------------------------------------------ r1507 | joe | 2008-07-19 22:40:57 +0100 (Sat, 19 Jul 2008) | 6 lines * src/ne_auth.c (tokenize): NUL terminate at a closing quote, ignore any trailing characters. * test/auth.c (basic): Add test case for trailing characters after quoted value token. ------------------------------------------------------------------------ r1506 | joe | 2008-07-19 22:29:57 +0100 (Sat, 19 Jul 2008) | 4 lines * src/ne_openssl.c (ne__negotiate_ssl), src/ne_gnutls.c (ne__negotiate_ssl): Use phrase "handshake" rather than "negotiation" in error message. ------------------------------------------------------------------------ r1505 | joe | 2008-07-19 22:23:13 +0100 (Sat, 19 Jul 2008) | 16 lines Fail with a useful error message in the case where a client cert is requested during handshake, none can be provided, and the handshake fails: * src/ne_private.h (struct ne_session_s): Add ssl_cc_requested field. * src/ne_openssl.c (provide_client_cert): Set ssl_cc_requested if no cert is provided. (ne__negotiate_ssl): Clear ssl_cc_requested before handshake. Use different, more useful error message if handshake fails and flag is now set. * test/ssl.c (struct ssl_server_args): Add fail_silently flag. (ssl_server): Exit with success if handshake fails and above flag set. (no_client_cert): New test case. ------------------------------------------------------------------------ r1500 | joe | 2008-07-19 21:06:06 +0100 (Sat, 19 Jul 2008) | 4 lines * src/ne_defs.h (ne_attribute_sentinel): New macro. * src/ne_string.h (ne_concat, ne_buffer_concat): Use it. ------------------------------------------------------------------------ r1497 | joe | 2008-07-19 13:13:10 +0100 (Sat, 19 Jul 2008) | 9 lines * src/ne_session.h (ne_set_notifier, ne_set_progress): Document existing and previous (respectively) API guarantee that a NULL callback deregisters an existing callback. * src/ne_session.c (ne_set_progress): Fix regression in 0.27, support NULL progress callback correctly. * test/request.c (dereg_progress): Add regression test. ------------------------------------------------------------------------ r1480 | joe | 2008-07-10 22:00:05 +0100 (Thu, 10 Jul 2008) | 2 lines * test/auth.c (check_digest): Fix compiler warnings with gcc 4.3. ------------------------------------------------------------------------ r1479 | joe | 2008-07-10 21:56:54 +0100 (Thu, 10 Jul 2008) | 2 lines * test/common/tests.c (main): More cosmetic fixes. ------------------------------------------------------------------------ r1478 | joe | 2008-07-10 21:35:59 +0100 (Thu, 10 Jul 2008) | 4 lines Merge from 0.28.x branch: * src/ne_auth.c (parse_domain): Fix debug output. ------------------------------------------------------------------------ r1477 | joe | 2008-07-10 09:31:28 +0100 (Thu, 10 Jul 2008) | 3 lines * test/ssl.c: Use P12_PASSPHRASE for client*.p12 passphrase. (init): Fail gracefully if client cert decrypt fails. ------------------------------------------------------------------------ r1476 | joe | 2008-07-09 23:01:35 +0100 (Wed, 09 Jul 2008) | 4 lines * tests/common/tests.c (main): Fixes for non-quiet mode. * test/run.sh: Enable quiet mode by default. ------------------------------------------------------------------------ r1475 | joe | 2008-07-09 22:56:50 +0100 (Wed, 09 Jul 2008) | 3 lines * tests/common/tests.c (main): More cosmetic tweaks for quiet mode. ------------------------------------------------------------------------ r1474 | joe | 2008-07-09 21:50:39 +0100 (Wed, 09 Jul 2008) | 2 lines * test/common/tests.c (main): Fix compiler warnings. ------------------------------------------------------------------------ r1473 | joe | 2008-07-09 21:46:11 +0100 (Wed, 09 Jul 2008) | 2 lines * test/common/tests.c (main): Cosmetic tweaks to quiet mode. ------------------------------------------------------------------------ r1472 | joe | 2008-07-09 21:38:01 +0100 (Wed, 09 Jul 2008) | 3 lines * test/common/tests.c (main): Implement a "quiet mode" if $TEST_QUIET is set in the environment. ------------------------------------------------------------------------ r1471 | joe | 2008-07-09 21:12:25 +0100 (Wed, 09 Jul 2008) | 3 lines * test/socket.c (socks_proxy, fail_socks): Destroy allocated addresses. ------------------------------------------------------------------------ r1470 | joe | 2008-07-09 21:04:56 +0100 (Wed, 09 Jul 2008) | 2 lines * src/Makefile.in: Factor out LT_COMPILE macro. ------------------------------------------------------------------------ r1466 | joe | 2008-07-09 10:46:30 +0100 (Wed, 09 Jul 2008) | 3 lines * src/ne_openssl.c (ne_ssl_context_keypair): Load entire chain from cert file specified. ------------------------------------------------------------------------ r1465 | joe | 2008-07-09 10:37:09 +0100 (Wed, 09 Jul 2008) | 11 lines Add test case with use of intermediary CA. * test/ssl.c (intermediary): New test case. * test/openssl.conf: Add neonca2 section. * test/makekeys.sh: Create an intermediary cert and EE cert signed by that. * test/Makefile.in (clean, ca-stamp): Clean up the ca2 directory. ------------------------------------------------------------------------ r1462 | joe | 2008-07-04 21:09:08 +0100 (Fri, 04 Jul 2008) | 2 lines * BUGS: Note test suite issue on RHEL4. ------------------------------------------------------------------------ r1460 | joe | 2008-07-03 12:59:46 +0100 (Thu, 03 Jul 2008) | 3 lines * test/makekeys.sh: Fix for versions of OpenSSL where ca fails if cert subjects are not unique. ------------------------------------------------------------------------ r1459 | joe | 2008-07-03 11:37:24 +0100 (Thu, 03 Jul 2008) | 2 lines * doc/ref/opts.xml: Remove old example, add xrefs. ------------------------------------------------------------------------ r1458 | joe | 2008-07-03 11:33:55 +0100 (Thu, 03 Jul 2008) | 2 lines * doc/ref/opts.xml: Document ne_set_connect_timeout and drop ne_set_persist. ------------------------------------------------------------------------ r1457 | joe | 2008-07-03 11:29:00 +0100 (Thu, 03 Jul 2008) | 2 lines * doc/ref/sessflags.xml: Document NE_SESSFLAG_TLS_SNI. ------------------------------------------------------------------------ r1455 | joe | 2008-07-03 11:06:08 +0100 (Thu, 03 Jul 2008) | 6 lines * src/ne_socket.c (raw_poll): Work around broken FD_SET on Netware. * src/ne_defs.h: Pick up time_t on Netware. Submitted by: Guenter Knauf ------------------------------------------------------------------------ r1454 | joe | 2008-06-27 17:22:53 +0100 (Fri, 27 Jun 2008) | 4 lines * README: Update copyright notices. * Makefile.in (update-copyright): New target. ------------------------------------------------------------------------ r1453 | joe | 2008-06-27 17:12:24 +0100 (Fri, 27 Jun 2008) | 2 lines * BUGS: Note some issues. ------------------------------------------------------------------------ r1452 | joe | 2008-06-27 17:04:46 +0100 (Fri, 27 Jun 2008) | 3 lines * src/ne_socket.c (ne_sock_connect): Disable Nagle on Windows even if TCP_NODELAY is not defined as a macro. ------------------------------------------------------------------------ r1451 | joe | 2008-06-17 15:59:49 +0100 (Tue, 17 Jun 2008) | 3 lines * configure.in: Build PIC objects in default configuration, unless non-PIC explicitly requested. ------------------------------------------------------------------------ r1449 | joe | 2008-04-17 11:04:34 +0100 (Thu, 17 Apr 2008) | 4 lines * doc/man.xsl: New file. * Makefile.in: Use man.xsl to customize man page output. ------------------------------------------------------------------------ r1445 | joe | 2008-04-03 12:38:04 +0100 (Thu, 03 Apr 2008) | 2 lines * src/ne_gnutls.c: Unbreak ts-ssl build. ------------------------------------------------------------------------ r1443 | joe | 2008-04-03 12:36:44 +0100 (Thu, 03 Apr 2008) | 2 lines * src/ne_gnutls.c: Enable quick-random in gcrypt unconditionally. ------------------------------------------------------------------------ r1442 | joe | 2008-04-03 12:34:20 +0100 (Thu, 03 Apr 2008) | 2 lines * src/ne_gnutls.c (ne__ssl_init): Enable fast initialization for GnuTLS. ------------------------------------------------------------------------ r1439 | joe | 2008-04-03 11:59:30 +0100 (Thu, 03 Apr 2008) | 5 lines * test/utils.c (double_serve_sstring): New function. * test/compress.c (retry_notcompress, retry_compress_helper, retry_compress):Use double_serve_sstring. ------------------------------------------------------------------------ r1435 | joe | 2008-03-29 20:54:27 +0000 (Sat, 29 Mar 2008) | 2 lines * test/ssl.c (parse_chain): Use CA_CERT constant. ------------------------------------------------------------------------ r1434 | joe | 2008-03-29 20:54:04 +0000 (Sat, 29 Mar 2008) | 3 lines * src/ne_gnutls.c (ne_ssl_dname_cmp): Fix compiler warning without new-DN suport. ------------------------------------------------------------------------ r1433 | joe | 2008-03-28 20:38:51 +0000 (Fri, 28 Mar 2008) | 2 lines * test/makekeys.sh: Be quieter on stdout. ------------------------------------------------------------------------ r1431 | joe | 2008-03-28 19:55:34 +0000 (Fri, 28 Mar 2008) | 2 lines * src/ne_gnutls.c (read_to_datum): Fix fd leak. ------------------------------------------------------------------------ r1430 | joe | 2008-03-28 16:20:29 +0000 (Fri, 28 Mar 2008) | 3 lines * test/ssl.c (ssl_server): Pass configured CA list as CA names and verification CAs, to unbreak OpenSSL tests. ------------------------------------------------------------------------ r1429 | joe | 2008-03-28 16:17:51 +0000 (Fri, 28 Mar 2008) | 10 lines Fix issues with CA list handling in the SSL server, for GnuTLS: * test/makekeys.sh: Generate wrongcn.cert signed by the CA. * test/ssl.c (struct ssl_server_args): Remove send_ca field. (check_cert): Update to expect the wrongcn subject name. (parse_chain, fail_wrongCN): Update to use the wrongcn cert, and to trust the CA cert. (cc_provided_dnames): Stop using the send_ca server args field. ------------------------------------------------------------------------ r1428 | joe | 2008-03-28 15:05:53 +0000 (Fri, 28 Mar 2008) | 4 lines * src/ne_gnutls.c (provide_client_cert) [HAVE_NEW_DN_API]: Properly map the CA names into ne_ssl_dname objects and pass these through to the provided callback. ------------------------------------------------------------------------ r1427 | joe | 2008-03-28 14:56:55 +0000 (Fri, 28 Mar 2008) | 11 lines Rebuild the peer cert chain correctly, with suitable GnuTLS support: * macros/neon.m4 (NEON_SSL): Check for gnutls_certificate_get_x509_cas. * src/ne_gnutls.c [HAVE_GNUTLS_CERTIFICATE_GET_X509_CAS] (find_issuer): New function. (make_peers_chain): Take creds object. [HAVE_GNUTLS_CERTIFICATE_GET_X509_CAS]: Rebuild the cert chain from list of trusted CAs. (ne__negotiate_ssl): Pass creds object to make_peers_chain. ------------------------------------------------------------------------ r1426 | joe | 2008-03-28 13:40:45 +0000 (Fri, 28 Mar 2008) | 6 lines * src/ne_gnutls.c: Define HAVE_NEW_DN_API for GnuTLS >= 2.3.2. (struct ne_ssl_dname_s) [HAVE_NEW_DN_API]: Represent as gnutls_x509_dn_t. (ne_ssl_readable_dname, ne_ssl_dname_cmp, populate_cert) [HAVE_NEW_DN_API]: Adjust to use new GnuTLS DN interfaces ------------------------------------------------------------------------ r1425 | joe | 2008-03-28 13:08:08 +0000 (Fri, 28 Mar 2008) | 3 lines * src/ne_pkcs11.c (pk11_find_pkey): Fix logic to reject non-DSA/RSA keys. ------------------------------------------------------------------------ r1424 | joe | 2008-03-28 13:06:08 +0000 (Fri, 28 Mar 2008) | 4 lines * src/ne_pkcs11.c (pk11_find_pkey): Don't require RSA keys; retrieve the key type. (pk11_sign_callback): Use mechanism appropriate to the key type. ------------------------------------------------------------------------ r1423 | joe | 2008-03-28 12:50:48 +0000 (Fri, 28 Mar 2008) | 7 lines * test/ssl.c (nss_pkcs11_test): Factor out from pkcs11. (pkcs11): Reimplement. (pkcs11_dsa): New XFAIL test case. * test/makekeys.sh: Create a client cert with a DSA key, and create a second separate NSS database using this. ------------------------------------------------------------------------ r1422 | joe | 2008-03-27 10:51:49 +0000 (Thu, 27 Mar 2008) | 2 lines * test/socket.c: Drop trailing commas in initializers. ------------------------------------------------------------------------ r1421 | joe | 2008-03-27 10:49:13 +0000 (Thu, 27 Mar 2008) | 13 lines Add support for initiating a proxy connection via SOCKS v4/v4a/v5 proxy, at socket layer: * src/ne_socks.c: New file. * src/ne_socket.h (ne_sock_proxy): New prototype. * src/Makefile.in, neon.mak: Build ne_socks.c. * test/socket.c (read_socks_string, read_socks_byte, expect_socks_byte, read_socks_0string, socks_server, begin_socks, socks_proxy, fail_socks): Add test cases. ------------------------------------------------------------------------ r1420 | joe | 2008-03-27 10:26:01 +0000 (Thu, 27 Mar 2008) | 3 lines * src/ne_socket.c: Include ne_privssl.h unconditionally, now it is safe to do so. ------------------------------------------------------------------------ r1419 | joe | 2008-03-26 15:44:28 +0000 (Wed, 26 Mar 2008) | 8 lines Add interface to set socket error string: * src/ne_socket.c (ne_sock_set_error): New function. * src/ne_socket.h (ne_sock_set_error): New prototype. * test/socket.c (error): New test case. ------------------------------------------------------------------------ r1418 | joe | 2008-03-17 21:08:01 +0000 (Mon, 17 Mar 2008) | 2 lines * src/Makefile.in (update-deps): Update for gnutls/pkcs11. ------------------------------------------------------------------------ r1417 | joe | 2008-03-17 21:05:21 +0000 (Mon, 17 Mar 2008) | 2 lines * src/Makefile.in (update-deps): Fix for generated SSL/etc deps. ------------------------------------------------------------------------ r1416 | joe | 2008-03-17 21:01:51 +0000 (Mon, 17 Mar 2008) | 2 lines * src/ne_privssl.h: Make safe for inclusion in non-SSL build. ------------------------------------------------------------------------ r1415 | joe | 2008-03-17 14:45:11 +0000 (Mon, 17 Mar 2008) | 2 lines * autogen.sh: Use libtoolize --install where supported. ------------------------------------------------------------------------ r1414 | joe | 2008-03-17 12:02:49 +0000 (Mon, 17 Mar 2008) | 4 lines * install-sh: Update to version from libtool 2.2. Submitted by: Arfrever Frehtes Taifersar Arahesis ------------------------------------------------------------------------ r1413 | joe | 2008-03-17 12:01:46 +0000 (Mon, 17 Mar 2008) | 4 lines * src/ne_pkcs11.c: Fix typo. Submitted by: Arfrever Frehtes Taifersar Arahesis ------------------------------------------------------------------------ r1412 | joe | 2008-03-17 12:01:06 +0000 (Mon, 17 Mar 2008) | 4 lines * configure.in, autogen.sh: Support libtool 2.2. Submitted by: Arfrever Frehtes Taifersar Arahesis ------------------------------------------------------------------------ r1411 | joe | 2008-03-14 17:09:30 +0000 (Fri, 14 Mar 2008) | 6 lines * src/ne_socket.h (ne_iaddr_raw): New prototype. * src/ne_socket.c (ne_iaddr_raw): New function. * test/socket.c (addr_make_v4, addr_make_v6): Test ne_iaddr_raw. ------------------------------------------------------------------------ r1410 | joe | 2008-03-13 23:31:54 +0000 (Thu, 13 Mar 2008) | 2 lines * doc/security.xml: Grammar fixes. ------------------------------------------------------------------------ r1407 | joe | 2008-03-13 20:07:46 +0000 (Thu, 13 Mar 2008) | 3 lines * src/ne_request.c (add_fixed_headers): Do not send "Keep-Alive" in the Connection header to a potentially-1.0 proxy, per 2616 rules. ------------------------------------------------------------------------ r1406 | joe | 2008-03-13 19:55:26 +0000 (Thu, 13 Mar 2008) | 17 lines Fix use of NTLM with some borked proxies which require use of a persistent connection but don't advertise such support in an HTTP-compliant manner: * src/ne_request.c (add_fixed_headers): Add the request header "Proxy-Connection: Keep-Alive" for a non-HTTP/1.1 next-hop, iff a proxy is configured. (ne_begin_request): Where the next-hop is non-HTTP/1.1, a proxy is configured, *and* the conn-auth flag is enabled, enable use of persistent connections if the next-hop sends the response header "Proxy-Connection: Keep-Alive". * test/request.c (test_persist_p): Renamed from test_persist. Take proxy flag and enable proxy and conn-auth if set. (test_persist): New function. (persist_proxy_http10): New test case. ------------------------------------------------------------------------ r1405 | joe | 2008-03-10 16:37:38 +0000 (Mon, 10 Mar 2008) | 2 lines * doc/xml.xml, doc/ssl.xml: Use id on footnotes for stable doc generation. ------------------------------------------------------------------------ r1404 | joe | 2008-03-10 16:32:23 +0000 (Mon, 10 Mar 2008) | 2 lines * doc/security.xml: Fix markup. ------------------------------------------------------------------------ r1403 | joe | 2008-03-10 16:28:31 +0000 (Mon, 10 Mar 2008) | 4 lines * doc/security.xml: New file. * doc/manual.xml: Include security section. ------------------------------------------------------------------------ r1398 | joe | 2008-03-03 13:31:04 +0000 (Mon, 03 Mar 2008) | 3 lines * macros/neon-xml-parser.m4 (NEON_XML_PARSER): Define NE_FMT_XML_SIZE for Subversion-bundled-expat build. ------------------------------------------------------------------------ r1393 | joe | 2008-03-03 09:02:53 +0000 (Mon, 03 Mar 2008) | 6 lines * configure.in: zh -> zh_CN in ALL_LINGUAS. * po/zh_CN.po: New translation, from Dongsheng Song. * po/zh.po: Renamed to above. ------------------------------------------------------------------------ r1389 | joe | 2008-02-29 16:22:18 +0000 (Fri, 29 Feb 2008) | 5 lines * src/ne_auth.c (inside_domain): Fix to treat domain as a prefix, as required by 2617. * test/auth.c (domains): Tweak test case to cover this. ------------------------------------------------------------------------ r1388 | joe | 2008-02-29 16:19:00 +0000 (Fri, 29 Feb 2008) | 2 lines * test/request.c: Wrap any_request() calls in ONREQ not CALL, throughout. ------------------------------------------------------------------------ r1387 | joe | 2008-02-29 16:18:18 +0000 (Fri, 29 Feb 2008) | 2 lines * test/makekeys.sh: Print OpenSSL version for diagnostic purposes. ------------------------------------------------------------------------ r1382 | joe | 2008-02-28 14:59:57 +0000 (Thu, 28 Feb 2008) | 2 lines * test/openssl.conf: Fix makekeys for some versions of OpenSSL. ------------------------------------------------------------------------ r1380 | joe | 2008-02-28 13:17:55 +0000 (Thu, 28 Feb 2008) | 2 lines * test/socket.c: Fail more gracefully. ------------------------------------------------------------------------ r1379 | joe | 2008-02-28 12:45:43 +0000 (Thu, 28 Feb 2008) | 3 lines * src/ne_socket.c (ne_sock_peer): Fix for !AF_INET6 && USE_GAI case; thanks to Nico Kadel-Garcia. ------------------------------------------------------------------------ r1378 | joe | 2008-02-28 11:06:15 +0000 (Thu, 28 Feb 2008) | 8 lines Fix build on systems with getaddrinfo but without AF_INET6. * src/ne_socket.c (ipv6_disabled) [!AF_INET6]: Define as 1. (ne_addr_resolve) [AF_INET6]: Make handling of v6 literals conditional. (do_bind) [AF_INET6]: Likewise for local bind address. (ne_iaddr_typeof, ne_iaddr_cmp): Likewise for address types. ------------------------------------------------------------------------ r1377 | joe | 2008-02-28 10:48:59 +0000 (Thu, 28 Feb 2008) | 3 lines * src/ne_pkcs11.c (pk11_login): Succeed if login fails with CKR_USER_ALREADY_LOGGED_IN. ------------------------------------------------------------------------ r1376 | joe | 2008-02-26 20:36:41 +0000 (Tue, 26 Feb 2008) | 2 lines * src/ne_pkcs11.c: Add a laundry list. ------------------------------------------------------------------------ r1375 | joe | 2008-02-21 20:48:17 +0000 (Thu, 21 Feb 2008) | 2 lines * test/ssl.c (pkcs11): Fix typo. ------------------------------------------------------------------------ r1374 | joe | 2008-02-21 20:46:33 +0000 (Thu, 21 Feb 2008) | 13 lines Add test case for PKCS#11 support using NSS software token: * configure.in: Check for pk12util, certutil. Generate test/makekeys. * test/ssl.c (pkcs11, pkcs11_pin): New functions. * test/makekeys.sh: Use configure-determined paths for openssl, and NSS tools. Generate nssdb for PKCS#11 testing if NSS tools present. * test/Makefile.in (ca-stamp): Run generated makekeys in builddir. (makekeys): Generate using config.status. (clean): Clean nssdb. ------------------------------------------------------------------------ r1373 | joe | 2008-02-20 13:41:43 +0000 (Wed, 20 Feb 2008) | 2 lines * doc/ref/neon.xml: Fix braino. ------------------------------------------------------------------------ r1372 | joe | 2008-02-19 21:09:43 +0000 (Tue, 19 Feb 2008) | 3 lines * src/ne_request.c (do_connect): Fail with NE_TIMEOUT for a timed-out connect() call. ------------------------------------------------------------------------ r1371 | joe | 2008-02-14 22:34:10 +0000 (Thu, 14 Feb 2008) | 3 lines * src/ne_gnutls.c (check_identity): Ensure that strings are NUL terminated since this is not explicitly guaranteed by the GnuTLS API. ------------------------------------------------------------------------ r1370 | joe | 2008-02-14 22:20:36 +0000 (Thu, 14 Feb 2008) | 3 lines * src/ne_openssl.c (provide_client_cert): Simplify slightly to use an array of dname structures. ------------------------------------------------------------------------ r1369 | joe | 2008-02-14 22:11:57 +0000 (Thu, 14 Feb 2008) | 4 lines * test/makekeys.sh: Prepend the real CA to the calist.pem. * test/ssl.c (cc_check_dnames): Update for the above. ------------------------------------------------------------------------ r1368 | joe | 2008-02-11 20:13:47 +0000 (Mon, 11 Feb 2008) | 2 lines * src/ne_socket.h: Pick up size_t definition on Win32. ------------------------------------------------------------------------ r1367 | joe | 2008-02-11 12:37:26 +0000 (Mon, 11 Feb 2008) | 2 lines * src/ne_string.c: Fix typo in comment. (Arfrever) ------------------------------------------------------------------------ r1366 | joe | 2008-02-11 12:36:19 +0000 (Mon, 11 Feb 2008) | 4 lines * macros/neon.m4: Bump to 0.29. Submitted by: Arfrever Frehtes Taifersar Arahesis ------------------------------------------------------------------------ r1354 | joe | 2008-02-11 09:29:48 +0000 (Mon, 11 Feb 2008) | 3 lines * macros/neon.m4: Define NE_FMT_NE_OFF_T for external-neon library builds. ------------------------------------------------------------------------ r1352 | joe | 2008-02-11 07:52:47 +0000 (Mon, 11 Feb 2008) | 4 lines * macros/neon.m4 (NEON_SSL): Add --without-pakchois. Submitted by: Arfrever Frehtes Taifersar Arahesis ------------------------------------------------------------------------ r1348 | joe | 2008-02-08 16:55:35 +0000 (Fri, 08 Feb 2008) | 3 lines * src/ne_session (ne_session_destroy): Destroy close_conn hooks to avoid memory leak (thanks, --enable-memleak mode). ------------------------------------------------------------------------ r1344 | joe | 2008-02-08 14:47:40 +0000 (Fri, 08 Feb 2008) | 13 lines Add a close-connection hook (thanks to Robert J. van der Boon): * src/ne_private.h (struct ne_session_s): Add close_conn_hooks. * src/ne_session.c (ne_hook_close_conn, ne_unhook_close_conn): New functions. (ne_close_connection): Run close_conn hooks. * src/ne_request.h (ne_hook_close_conn, ne_unhook_close_conn): New prototypes. * test/request.c (hook_close_conn, hooks): Add tests. ------------------------------------------------------------------------ r1341 | joe | 2008-02-08 10:16:32 +0000 (Fri, 08 Feb 2008) | 2 lines * NEWS: No news like good news. ------------------------------------------------------------------------ r1340 | joe | 2008-02-08 10:14:23 +0000 (Fri, 08 Feb 2008) | 3 lines * neon.mak: Removes quotes around $(MAKE) since nmake quotes this internally. ------------------------------------------------------------------------ r1338 | joe | 2008-02-07 22:22:07 +0000 (Thu, 07 Feb 2008) | 9 lines * src/ne_basic.h: Deprecate ne_options API. Add NE_CAP_* constants, ne_options2 prototype. * src/ne_basic.c (options_map): Add options mapping table. (parse_dav_header): Adjust to use mapping table and capabilities bitmask. (ne_options2): New function; renamed from ne_options. (ne_options): Re-implement on top of ne_options2. ------------------------------------------------------------------------ r1337 | joe | 2008-02-07 17:18:42 +0000 (Thu, 07 Feb 2008) | 2 lines * Makefile.in: Install ne_pkcs11.h. ------------------------------------------------------------------------ r1336 | joe | 2008-02-07 13:53:47 +0000 (Thu, 07 Feb 2008) | 2 lines * src/ne_pkcs11.h: Further doc tweaks. ------------------------------------------------------------------------ r1335 | joe | 2008-02-07 13:45:07 +0000 (Thu, 07 Feb 2008) | 5 lines * src/ne_pkcs11.h: Add interface description for attempt parameter. * src/ne_pkcs11.c (pk11_login): Start attempt at 1 as per auth callbacks. ------------------------------------------------------------------------ r1334 | joe | 2008-02-07 13:40:30 +0000 (Thu, 07 Feb 2008) | 2 lines * src/ne_pkcs11.c: Clean up debugging. ------------------------------------------------------------------------ r1333 | joe | 2008-02-07 11:06:13 +0000 (Thu, 07 Feb 2008) | 18 lines Adjust PKCS#11 interfaces to allow a single provider to be shared between sessions: * src/ne_session.c (ne_ssl_set_pkcs11_pin): Removed function. * src/ne_private.h (struct ne_session_s): Remove PKCS#11 pin callback. * src/ne_pkcs11.c (pk11_find_x509): Take provider object and set client cert. (pk11_find_pkey): Take provider object and set private key. (find_client_cert): Take provider object and pass through. (pk11_sign_callback, pk11_login, pk11_provide): Take provider object, adjust accordingly. (pk11_init, ne_ssl_pkcs11_provider_init, ne_ssl_nsspk11_provider_init, ne_ssl_pkcs11_provider_destroy, ne_ssl_pkcs11_provider_pin): New functions. ------------------------------------------------------------------------ r1332 | joe | 2008-02-07 08:31:51 +0000 (Thu, 07 Feb 2008) | 3 lines * src/ne_gnutls.c (match_hostname, check_identity): Tone down the debugging output. ------------------------------------------------------------------------ r1331 | joe | 2008-02-07 08:24:05 +0000 (Thu, 07 Feb 2008) | 4 lines * src/ne_gnutls.c (ne_ssl_clicert_read): Fail if missing cert or key. (ne__ssl_clicert_exkey_import): Set decrypted flag on imported keyless clicert. ------------------------------------------------------------------------ r1330 | joe | 2008-02-06 21:37:26 +0000 (Wed, 06 Feb 2008) | 2 lines * src/Makefile.in: Regenerate deps. ------------------------------------------------------------------------ r1329 | joe | 2008-02-06 21:31:30 +0000 (Wed, 06 Feb 2008) | 22 lines Initial support for PKCS#11, based on the pakchois PKCS#11 library: * src/ne_pkcs11.c, src/ne_pkcs11: New files. * src/ne_gnutls.c (struct ne_ssl_client_cert_s): Add keyless flag. (dup_client_cert): Support keyless clicerts. (ne__ssl_clicert_exkey_import): New function. (provide_client_cert): Use proper GnuTLS error codes in failure cases. * src/ne_privssl.h (ne__ssl_clicert_exkey_import) [HAVE_GNUTLS]: Add prototype. * src/ne_private.h: Include ne_pkcs11.h. (struct ne_session_s): Add pin callback and userdata. * src/ne_session.c (ne_ssl_set_pkcs11_pin): New function. * src/Makefile.in, neon.mak: Build ne_pkcs11.c. * macros/neon.m4 (NEON_SSL): Check for pakchois. ------------------------------------------------------------------------ r1328 | joe | 2008-02-06 21:29:44 +0000 (Wed, 06 Feb 2008) | 3 lines * macros/neon.m4 (NEON_WITH_LIBS): Adjust PKG_CONFIG_PATH appropriately. ------------------------------------------------------------------------ r1327 | joe | 2008-02-06 21:19:35 +0000 (Wed, 06 Feb 2008) | 3 lines * src/ne_alloc.h: Include stdlib.h on all platforms to pick up free() definition. ------------------------------------------------------------------------ r1326 | joe | 2008-02-06 11:30:41 +0000 (Wed, 06 Feb 2008) | 11 lines Restore parts of r1315: * macros/neon.m4 (NEON_SSL): Check for gnutls_sign_callback_set. * src/ne_privssl.h (struct ne_ssl_context_s): Add sign_func, sign_data fields. * src/ne_socket.c (ne_sock_connect_ssl): Set up the sign_func callback if non-NULL. ------------------------------------------------------------------------ r1325 | joe | 2008-02-06 11:27:38 +0000 (Wed, 06 Feb 2008) | 8 lines Re-apply r1317, portion of r1316: * src/ne_gnutls.c (ne_ssl_clicert_read): Fail if cert or key is missing. * src/ne_openssl.c (ne_ssl_clicert_read): Fail if private key lacks cert or pkey. ------------------------------------------------------------------------ r1324 | joe | 2008-02-06 11:17:54 +0000 (Wed, 06 Feb 2008) | 3 lines * test/ssl.c, test/makekeys.sh: Restore test cases for PKCS#12 clicerts with missing halves. ------------------------------------------------------------------------ r1323 | joe | 2008-02-06 11:12:09 +0000 (Wed, 06 Feb 2008) | 2 lines Revert diff r1320:r1314. ------------------------------------------------------------------------ r1322 | joe | 2008-02-06 10:13:42 +0000 (Wed, 06 Feb 2008) | 2 lines * src/ne_socket.c (ne_sock_cipher): Fix non-SSL build. ------------------------------------------------------------------------ r1321 | joe | 2008-02-06 09:51:54 +0000 (Wed, 06 Feb 2008) | 2 lines * NEWS: News so far. ------------------------------------------------------------------------ r1320 | joe | 2008-01-31 15:22:13 +0000 (Thu, 31 Jan 2008) | 2 lines * src/ne_ssl.h: Update docco for ne_ssl_clicert*_read. ------------------------------------------------------------------------ r1319 | joe | 2008-01-31 15:08:53 +0000 (Thu, 31 Jan 2008) | 6 lines * test/makekeys.sh: Generate clicert without cert, and encrypted clicert without pkey. * test/ssl.c (load_client_cert): Add tests for more clicert variations. ------------------------------------------------------------------------ r1318 | joe | 2008-01-31 12:12:16 +0000 (Thu, 31 Jan 2008) | 3 lines * src/Makefile.in, Makefile.in: Fix for NE_SSL_LIBNAME for non-GnuTLS build. ------------------------------------------------------------------------ r1317 | joe | 2008-01-31 11:49:36 +0000 (Thu, 31 Jan 2008) | 3 lines * src/ne_openssl.c (ne_ssl_clicert_read): Fail if private key lacks cert or pkey. ------------------------------------------------------------------------ r1316 | joe | 2008-01-31 11:46:32 +0000 (Thu, 31 Jan 2008) | 21 lines Add support for PKCS#12 client certs which don't include a private key: * src/ne_gnutls.c (struct ne_ssl_client_cert_s): Add keyless flag. (dup_client_cert): Support keyless clicerts. (pkcs12_parse): Make pkey handling optional. (read_client_cert): Factor out from ne_ssl_clicert_read; take additional key_required flag; fail if cert or key is required and not supplied; initialize keyless flag. (ne_ssl_clicert_read): Reimplement using read_client_cert. (ne_ssl_clicert_exkey_read): New function. (ne_ssl_clicert_decrypt): Handle keyless failure case. * src/ne_openssl.c (ne_ssl_clicert_exkey_read): Add stub. * src/ne_stubssl.c (ne_ssl_clicert_exkey_read): Add stub. * test/ssl.c (load_client_cert): Test ne_ssl_clicert_exkey_read. * test/makekeys.sh: Generate keyless ccert. ------------------------------------------------------------------------ r1315 | joe | 2008-01-31 11:40:22 +0000 (Thu, 31 Jan 2008) | 27 lines Add libneon-gnutls support library to allow use of external signing callback with GnuTLS: * src/lib_gnutls.c, src/ne_gnutls.h, neon-gnutls.pc.in: New files. * src/ne_privssl.h (struct ne_ssl_context_s): Add sign_func, sign_data fields. * macros/neon.m4 (NEON_SSL): Define NE_SSL_LIBNAME; check for gnutls_sign_callback_set, add new exports NE_SSL_CFLAGS and NE_LIBSSL_LTFLAGS. Export NEON_LIBEXT in place of NEON_TARGET, NE_LIBNEON_LTFLAGS in place of NEON_LINK_FLAGS; * src/Makefile.in: Add and adjust targets to build libneon-gnutls iff configured with GnuTLS support. * Makefile.in (install-lib-ssl-no, install-lib-ssl-gnutls): New targets. * neon-config.in: Add --la-file=gnutls, --cflags=gnutls support. * src/ne_socket.c (ne_sock_connect_ssl): Set up the sign_func callback if non-NULL. * configure.in: Adjust for NEON_LINK_FLAGS rename. Define NE_LIBSSL_LTFLAGS. Generate neon-gnutls.pc. ------------------------------------------------------------------------ r1314 | joe | 2008-01-31 09:54:15 +0000 (Thu, 31 Jan 2008) | 3 lines * src/ne_socket.c (ne_sock_accept_ssl, ne_sock_connect_ssl): Fix compiler warnings on LP64 platforms. ------------------------------------------------------------------------ r1313 | joe | 2008-01-31 09:43:11 +0000 (Thu, 31 Jan 2008) | 4 lines * src/ne_session.c (ne_get_error): Don't "clean" the error string again here, since it may have been localised and hence not be 7-bit ASCII. ------------------------------------------------------------------------ r1312 | joe | 2008-01-31 09:09:03 +0000 (Thu, 31 Jan 2008) | 2 lines * Makefile.in: Add datarootdir to silence autoconf/config.status warning. ------------------------------------------------------------------------ r1311 | joe | 2008-01-31 08:58:21 +0000 (Thu, 31 Jan 2008) | 4 lines * src/ne_string.c (ascii_printable): Define array. (ne_strclean): Reimplement using above to be independent of locale. ------------------------------------------------------------------------ r1310 | joe | 2008-01-30 22:22:31 +0000 (Wed, 30 Jan 2008) | 3 lines * test/request.c (send_bad_offset): Use a pipe rather than a negative offset; better guarantee of failure. ------------------------------------------------------------------------ r1309 | joe | 2008-01-30 22:06:43 +0000 (Wed, 30 Jan 2008) | 2 lines * src/ne_gnutls.c: Remove now-redundant #includes. ------------------------------------------------------------------------ r1308 | joe | 2008-01-30 21:19:34 +0000 (Wed, 30 Jan 2008) | 2 lines * config.hw.in: Fix build with VS2008 (Stefan Kung). ------------------------------------------------------------------------ r1307 | joe | 2008-01-30 20:24:59 +0000 (Wed, 30 Jan 2008) | 2 lines * configure.in: Wording tweak, no functional change. ------------------------------------------------------------------------ r1306 | joe | 2008-01-30 16:59:35 +0000 (Wed, 30 Jan 2008) | 5 lines * src/ne_basic.c (dispatch_to_fd): Fix handling of ranged PUT with unspecified length. (Submitted by Henrik Holst ) * test/basic. (get_eof_range): New test case. ------------------------------------------------------------------------ r1305 | joe | 2008-01-30 16:40:14 +0000 (Wed, 30 Jan 2008) | 2 lines * src/ne_session.h: Docco update. ------------------------------------------------------------------------ r1304 | joe | 2008-01-30 16:38:19 +0000 (Wed, 30 Jan 2008) | 5 lines * src/ne_props.c (startelm): Include the namespaces for both element and attributes in flat property dumps. * test/props.c (propfind): Add test case for attribute handling. ------------------------------------------------------------------------ r1303 | joe | 2008-01-30 11:53:32 +0000 (Wed, 30 Jan 2008) | 8 lines * src/ne_dates.c (GMTOFF) [HAVE_TIMEZONE]: Add definition. (all callers of GMTOFF): Separate mktime from GMTOFF invocation to ensure a sequence point between the two. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Update timezone warning. Submitted by: Alessandro Vesely ------------------------------------------------------------------------ r1302 | joe | 2008-01-30 11:35:52 +0000 (Wed, 30 Jan 2008) | 11 lines * src/ne_private.h (struct ne_session_s): Add local_addr field. * src/ne_session.c (ne_set_localaddr): New prototype. * src/ne_session.c (ne_set_localaddr): New function. * src/ne_request.c (do_connect): Call ne_sock_prebind if local_addr is non-NULL. * test/request.c (local_addr): New test case. ------------------------------------------------------------------------ r1299 | joe | 2007-12-27 21:10:43 +0000 (Thu, 27 Dec 2007) | 2 lines * src/ne_ssl.h: Docco tweaks. ------------------------------------------------------------------------ r1298 | joe | 2007-12-27 21:08:25 +0000 (Thu, 27 Dec 2007) | 2 lines * test/request.c: Spelling fix. ------------------------------------------------------------------------ r1297 | joe | 2007-12-16 14:05:07 +0000 (Sun, 16 Dec 2007) | 2 lines * src/Makefile.in: Add deps for ne_gnutls.c. ------------------------------------------------------------------------ r1296 | joe | 2007-12-16 14:01:46 +0000 (Sun, 16 Dec 2007) | 2 lines * src/ne_session.h: Clarify when ne_session_proxy may be called. ------------------------------------------------------------------------ r1295 | joe | 2007-12-16 13:58:47 +0000 (Sun, 16 Dec 2007) | 10 lines * src/ne_acl.h (ne_acl_entry): Rename "apply" field "target", split out enums; rename "principal" to "tname"; add single "principles" bit-field. Add NE_ACL_* constants. * src/ne_acl.c (acl_body): Adjust accordingly. * test/acl.c: All tests updated accordingly. Submitted by: Henrik Holst, joe ------------------------------------------------------------------------ r1294 | joe | 2007-12-16 11:24:39 +0000 (Sun, 16 Dec 2007) | 3 lines * test/socket.c (ssl_session_id): Skip if given a zero-length session ID as recent OpenSSL seems to do. ------------------------------------------------------------------------ r1293 | joe | 2007-12-05 16:42:01 +0000 (Wed, 05 Dec 2007) | 2 lines * src/ne_ssl.h: Doc tweak; server is not a person. ------------------------------------------------------------------------ r1292 | joe | 2007-12-05 16:39:58 +0000 (Wed, 05 Dec 2007) | 11 lines * src/ne_auth.h (NE_AUTH_ALL, NE_AUTH_DEFAULT): Add new protocol codes. * src/ne_auth.c (auth_register): Interpret NE_AUTH_ALL and NE_AUTH_DEFAULT. (auth_register_default): Remove function. (ne_set_server_auth, ne_set_proxy_auth): Re-implement using auth_register. * test/auth.c (defaults): New test case. ------------------------------------------------------------------------ r1291 | joe | 2007-12-05 15:23:40 +0000 (Wed, 05 Dec 2007) | 2 lines * src/ne_socket.c (ne_sock_cipher): Fix non-SSL build. ------------------------------------------------------------------------ r1290 | joe | 2007-12-05 15:11:24 +0000 (Wed, 05 Dec 2007) | 10 lines Enable TLS SNI support for GnuTLS builds: * src/ne_privssl.h [HAVE_GNUTLS] (struct ne_ssl_context_s): Add hostname field. * src/ne_gnutls.c (ne__negotiate_ssl): Pass through hostname if SNI enabled. ,* src/ne_socket.c [HAVE_GNUTLS] (ne_sock_connect_ssl): Set hostname. ------------------------------------------------------------------------ r1289 | joe | 2007-12-05 15:04:51 +0000 (Wed, 05 Dec 2007) | 6 lines * src/ne_socket.c (ne_sock_cipher): New function. * src/ne_socket.h (ne_sock_cipher): Add prototype. * test/socket.c (cipher): Add test case. ------------------------------------------------------------------------ r1288 | joe | 2007-12-05 14:57:54 +0000 (Wed, 05 Dec 2007) | 6 lines * src/ne_auth.c (inside_domain): Parse request-URI to handle proxies correctly. * test/auth.c (verify_digest_header, serve_digest, domains): Test domain handling via proxy. ------------------------------------------------------------------------ r1287 | joe | 2007-12-05 14:31:19 +0000 (Wed, 05 Dec 2007) | 3 lines * src/ne_auth.c (parse_domain): Fix memory handling (fix tests with --enable-memleak). ------------------------------------------------------------------------ r1286 | joe | 2007-12-05 14:16:35 +0000 (Wed, 05 Dec 2007) | 5 lines * src/ne_auth.c (parse_domain): Fix to parse domain parameter as space-separated list. * test/auth.c (domains): Fix test case. ------------------------------------------------------------------------ r1285 | joe | 2007-12-05 14:14:37 +0000 (Wed, 05 Dec 2007) | 2 lines * src/ne_auth.c (get_cnonce): Reformat code; no functional change. ------------------------------------------------------------------------ r1284 | joe | 2007-12-05 14:10:57 +0000 (Wed, 05 Dec 2007) | 3 lines * src/ne_auth.c (get_cnonce): Use gcrypt to create the nonce if configured with GnuTLS. ------------------------------------------------------------------------ r1283 | joe | 2007-12-05 11:04:47 +0000 (Wed, 05 Dec 2007) | 2 lines * src/ne_uri.c (ne_path_unescape): Remove redundant \0 (Hannes Eder). ------------------------------------------------------------------------ r1282 | joe | 2007-12-04 22:02:27 +0000 (Tue, 04 Dec 2007) | 2 lines * src/ne_md5.c: Use ANSI C prototypes throughout (Hannes Eder). ------------------------------------------------------------------------ r1281 | joe | 2007-12-01 16:07:44 +0000 (Sat, 01 Dec 2007) | 15 lines Add TLS SNI support and enable by default: * src/ne_session.h (ne_session_flag_e): Add NE_SESSFLAG_TLS_SNI. * src/ne_session.c (ne_session_create): Enable the SNI flag by default. * src/ne_privssl.h (struct ne_ssl_context_s): Add hostname field. * src/ne_socket.c (ne_sock_connect_ssl) [HAVE_OPENSSL]: Enable SNI extension if hostname passed-through. * src/ne_openssl.c (ne__negotiate_ssl): Set hostname field in context, if SNI flag enbled. ------------------------------------------------------------------------ r1280 | joe | 2007-11-30 14:12:59 +0000 (Fri, 30 Nov 2007) | 3 lines * src/ne_socket.c (ne_sock_connect): Fix fd leak on connect() failure; regresion since 0.26 (Andrew Teirney). ------------------------------------------------------------------------ r1279 | joe | 2007-11-29 23:05:18 +0000 (Thu, 29 Nov 2007) | 3 lines * src/ne_openssl.c (ne_ssl_context_create): Enable client session cache if creating server context. ------------------------------------------------------------------------ r1278 | joe | 2007-11-26 20:42:08 +0000 (Mon, 26 Nov 2007) | 5 lines * src/ne_basic.c (ne_getmodtime): Set modtime to -1 if no header given. (Henrik Holst) * src/ne_basic.h (ne_getmodtime): Clarify interface. ------------------------------------------------------------------------ r1277 | joe | 2007-11-26 20:15:17 +0000 (Mon, 26 Nov 2007) | 6 lines Add Polish translation, from Arfrever Frehtes Taifersar Arahesis: * configure.in: Add pl locale. * po/pl.po: New file. ------------------------------------------------------------------------ r1276 | joe | 2007-11-26 20:07:39 +0000 (Mon, 26 Nov 2007) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1275 | joe | 2007-11-26 15:52:26 +0000 (Mon, 26 Nov 2007) | 4 lines * src/ne_compress.c (set_zlib_error), * src/ne_auth.c (challenge_error): Don't mark untranslateable strings as translatable (patch by Arfrever Frehtes Taifersar Arahesis). ------------------------------------------------------------------------ r1274 | joe | 2007-11-21 11:17:02 +0000 (Wed, 21 Nov 2007) | 3 lines * src/ne_socket.c (ne_sock_connect): Set the FD_CLOEXEC bit on the socket fd. ------------------------------------------------------------------------ r1273 | joe | 2007-11-19 15:55:30 +0000 (Mon, 19 Nov 2007) | 15 lines Add support for domain handling in Digest authentication: * src/ne_auth.c (struct auth_challenge): Add domain field. (auth_session): Add domains, ndomains fields. (free_domains, parse_domain, inside_domain): New functions. (clean_session): Call free_domains. (digest_challenge): Parse the domain parameter. (request_digest): Don't submit credentials if request falls outside the defined auth domain, if any. (auth_challenge): Capture the domain parameter. * test/auth.c (make_digest_header, serve_digest): Update for handling domains test. (domains): New test case. ------------------------------------------------------------------------ r1272 | joe | 2007-11-19 13:57:25 +0000 (Mon, 19 Nov 2007) | 3 lines * doc/: Add documentation for _set_*_flag interfaces, misc. updates to neon(3) main page. ------------------------------------------------------------------------ r1271 | joe | 2007-10-31 21:20:59 +0000 (Wed, 31 Oct 2007) | 2 lines * macros/neon.m4: Fix comment. ------------------------------------------------------------------------ r1270 | joe | 2007-10-24 17:37:35 +0100 (Wed, 24 Oct 2007) | 2 lines * src/ne_socket.c (ne_socket_s): Reorder for better packing. ------------------------------------------------------------------------ r1269 | joe | 2007-10-22 10:08:29 +0100 (Mon, 22 Oct 2007) | 2 lines * src/ne_socket.c (do_bind, ne_sock_peer): Fix for !USE_GETADDRINFO build. ------------------------------------------------------------------------ r1268 | joe | 2007-10-22 09:58:19 +0100 (Mon, 22 Oct 2007) | 15 lines * src/ne_socket.h (ne_sock_peer, ne_sock_prebind): Add prototypes. * src/ne_socket.c (ne_sock_peer, ne_sock_prebind, do_bind): New functions. (ne_sock_connect): Use do_bind. (struct ne_socket_s): Add laddr, lport fields. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Define socklen_t if not available. * config.hw.in: Define socklen_t. * test/socket.c (addr_peer, serve_ppeer, try_prebind, prebind): New tests. ------------------------------------------------------------------------ r1267 | joe | 2007-10-19 11:25:38 +0100 (Fri, 19 Oct 2007) | 3 lines * test-common/tests.c (t_context, in_child): Print failure messages to the child debug log as well as to stderr. ------------------------------------------------------------------------ r1266 | joe | 2007-10-19 11:24:35 +0100 (Fri, 19 Oct 2007) | 2 lines * src/ne_request.c (build_request): Use ne_buffer_czappend. ------------------------------------------------------------------------ r1264 | joe | 2007-10-19 11:13:02 +0100 (Fri, 19 Oct 2007) | 3 lines * test/auth.c (serve_digest): Inhibit "server child failure" messages when the server should quit. ------------------------------------------------------------------------ r1263 | joe | 2007-10-18 15:37:59 +0100 (Thu, 18 Oct 2007) | 6 lines * src/ne_socket.c (ne_sock_sessid): Don't copy from beyond ->session_id array. * test/socket.c (ssl_session_id): Test that only expected number of bytes are copied. ------------------------------------------------------------------------ r1262 | joe | 2007-10-18 15:33:15 +0100 (Thu, 18 Oct 2007) | 2 lines * src/Makefile.in (update-deps): Fix location of config.h. ------------------------------------------------------------------------ r1256 | joe | 2007-09-25 10:22:50 +0100 (Tue, 25 Sep 2007) | 3 lines * src/ne_auth.c (verify_negotiate_response): Fix crash in GSSAPI Negotiate response header verification. ------------------------------------------------------------------------ r1253 | joe | 2007-09-11 17:01:20 +0100 (Tue, 11 Sep 2007) | 2 lines * test/run.sh: Run all test suites despite failures. ------------------------------------------------------------------------ r1252 | joe | 2007-09-09 21:46:28 +0100 (Sun, 09 Sep 2007) | 2 lines * test/socket.c (serve_reset): Add delay before sending RST. ------------------------------------------------------------------------ r1251 | joe | 2007-09-09 21:44:38 +0100 (Sun, 09 Sep 2007) | 2 lines * test/request.c (status, status_chunked): Fix memory leak. ------------------------------------------------------------------------ r1250 | joe | 2007-09-09 21:40:11 +0100 (Sun, 09 Sep 2007) | 3 lines * src/ne_openssl.c: Update comments. (match_hostname): Remove debugging. ------------------------------------------------------------------------ r1249 | joe | 2007-09-07 13:24:54 +0100 (Fri, 07 Sep 2007) | 2 lines * src/Makefile.in (update-deps): New target; regenerate dependencies. ------------------------------------------------------------------------ r1248 | joe | 2007-09-02 21:27:57 +0100 (Sun, 02 Sep 2007) | 7 lines * configure.in: Set NEON_LINK_FLAGS later; also use -release if ABI variations are noted. * macros/neon.m4 (NE_ADD_ABITAG): New macro. (NE_LARGEFILE): Add LFS ABI tag if LFS is enabled. (NEON_COMMON_BUNDLED): Add NODAV ABI tag if DAV support is disabled. ------------------------------------------------------------------------ r1240 | joe | 2007-08-22 13:02:05 +0100 (Wed, 22 Aug 2007) | 2 lines * macros/neon-xml-parser.m4 (NE_XML_BUNDLED_EXPAT): Define NE_FMT_XML_SIZE. ------------------------------------------------------------------------ r1238 | joe | 2007-08-22 12:57:37 +0100 (Wed, 22 Aug 2007) | 2 lines * src/ne_session.h: Add forward-compat note for ne_session_status enum. ------------------------------------------------------------------------ r1237 | joe | 2007-08-22 12:55:38 +0100 (Wed, 22 Aug 2007) | 5 lines * src/ne_session.h: Fix description of total counter for response progress. * test/request.c (status_chunked): New test. ------------------------------------------------------------------------ r1235 | joe | 2007-08-22 12:42:13 +0100 (Wed, 22 Aug 2007) | 2 lines * src/ne_request.c (ne_read_response_block): Fix response progress counter. ------------------------------------------------------------------------ r1232 | joe | 2007-08-21 20:12:30 +0100 (Tue, 21 Aug 2007) | 2 lines * NEWS: Tweak more. ------------------------------------------------------------------------ r1231 | joe | 2007-08-21 20:09:07 +0100 (Tue, 21 Aug 2007) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1230 | joe | 2007-08-21 20:07:23 +0100 (Tue, 21 Aug 2007) | 2 lines * NEWS: Tweak. ------------------------------------------------------------------------ r1229 | joe | 2007-08-21 20:06:43 +0100 (Tue, 21 Aug 2007) | 2 lines * NEWS: Tweak, update. ------------------------------------------------------------------------ r1228 | joe | 2007-08-21 19:59:32 +0100 (Tue, 21 Aug 2007) | 4 lines * macros/neon.m4: Bump to 0.27. * NEWS: Update. ------------------------------------------------------------------------ r1227 | joe | 2007-08-21 19:59:07 +0100 (Tue, 21 Aug 2007) | 3 lines * BUGS: Note a broken HTTP server which would need some custom hack to be supported. ------------------------------------------------------------------------ r1226 | joe | 2007-08-21 19:56:40 +0100 (Tue, 21 Aug 2007) | 11 lines Make the notifier and progress interfaces mutually exclusive since the old interface is only kept for backwards-compatibility. * src/ne_request.c (notify_status): Don't invoke the progress callback. * src/ne_session.c (progress_notifier): New function. (ne_set_progress): Implement using a notifier callback. * src/ne_session.h: Note the mutual exclusivity. ------------------------------------------------------------------------ r1225 | joe | 2007-08-21 16:38:12 +0100 (Tue, 21 Aug 2007) | 3 lines * src/ne_gnutls.c [HAVE_ICONV && HAVE_GNUTLS_X509_DN_GET_RDN_AVA]: Include errno.h, fix build. ------------------------------------------------------------------------ r1224 | joe | 2007-08-19 09:56:45 +0100 (Sun, 19 Aug 2007) | 6 lines * src/ne_session.h (ne_ssl_trust_cert): Clarify use with non-SSL session. * src/ne_session.c (ne_ssl_trust_cert): Do nothing for non-SSL session. * test/ssl.c (nonssl_trust): New test case. ------------------------------------------------------------------------ r1223 | joe | 2007-08-18 14:28:22 +0100 (Sat, 18 Aug 2007) | 2 lines * test/socket.c (addr_reverse): Remove debugging code added in r1220. ------------------------------------------------------------------------ r1222 | joe | 2007-08-10 16:26:08 +0100 (Fri, 10 Aug 2007) | 5 lines Perform hostname canonicalization for SSPI, patch by Yves Martin: * src/ne_sspi.c (canonical_hostname): New function. (ne_sspi_create_context): Use the canonical hostname in the SPN. ------------------------------------------------------------------------ r1221 | joe | 2007-08-10 15:39:26 +0100 (Fri, 10 Aug 2007) | 2 lines * config.hw.in: Fix ne_xml.c build on Win32. ------------------------------------------------------------------------ r1220 | joe | 2007-08-10 14:05:10 +0100 (Fri, 10 Aug 2007) | 7 lines * src/ne_socket.h (ne_iaddr_reverse), src/ne_socket.c (ne_iaddr_reverse): New function. * test/socket.c (addr_reverse): New tests. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Check for getnameinfo too. ------------------------------------------------------------------------ r1219 | joe | 2007-08-10 11:29:26 +0100 (Fri, 10 Aug 2007) | 9 lines * src/ne_request.c (ne_begin_request): Ignore the "identity" transfer-coding since "privoxy" apparently sends it. Fail for unknown transfer-codings. * test/request.c (te_identity): New test, replacing any_te_header. (fail_on_invalid): Test for failure with unknown transfer-codings. * doc/using.xml: Update section on transfer-encoding interpretation. ------------------------------------------------------------------------ r1218 | joe | 2007-08-09 10:46:36 +0100 (Thu, 09 Aug 2007) | 11 lines Fix compiler warnings with expat 2.x API: * macros/neon.m4 (NEON_FORMAT): Fix use of headers passed to AC_CHECK_SIZEOF. * macros/neon-xml-parser.m4 (NE_XML_EXPAT): Check how to print the XML_Size type, if defined. * src/ne_xml.c (ne_xml_parse): Use correct format string for return value of XML_GetCurrentLineNumber. ------------------------------------------------------------------------ r1217 | joe | 2007-08-08 09:29:00 +0100 (Wed, 08 Aug 2007) | 10 lines * src/ne_session.h (ne_session_flag): Add NE_SESSFLAG_CONNAUTH. * src/ne_request.c (ne_begin_request): Ignore the IDEMPOTENT flag if the session CONNAUTH flag is set. * src/ne_auth.c: Define AUTH_FLAG_CONN_AUTH macro, use for Negotiate/NTLM schemes. (ah_pre_send): Remove non-functional hack to clear IDEMPOTENT flag. (ah_post_send): Set or clear session CONNAUTH flag appropriately. ------------------------------------------------------------------------ r1216 | joe | 2007-07-31 19:28:30 +0100 (Tue, 31 Jul 2007) | 4 lines * src/ne_uri.c (URI_FRAGMENT): Add macro. (ne_uri_parse): Add comments and use URI_FRAGMENT; no functional change. ------------------------------------------------------------------------ r1215 | joe | 2007-07-31 19:19:34 +0100 (Tue, 31 Jul 2007) | 5 lines * src/ne_session.h (ne_session_flag): Add NE_SESSFLAG_RFC4918. * src/ne_basic.c (copy_or_move): Use an abs_path in Destination header, rather than an absoluteURI, iff the 4918 flag is enabled. ------------------------------------------------------------------------ r1214 | joe | 2007-07-31 19:14:25 +0100 (Tue, 31 Jul 2007) | 2 lines * src/ne_session.h (ne_session_status): Clarify meaning of _recv/_sending. ------------------------------------------------------------------------ r1213 | joe | 2007-07-29 16:38:22 +0100 (Sun, 29 Jul 2007) | 2 lines Changes so far. ------------------------------------------------------------------------ r1212 | joe | 2007-07-26 13:33:58 +0100 (Thu, 26 Jul 2007) | 4 lines * src/ne_gnutls.c (check_identity): Take URI object as argument; handle URI subjectAltNames. (check_certificate, populate_cert): Adjust accordingly. ------------------------------------------------------------------------ r1211 | joe | 2007-07-20 12:52:33 +0100 (Fri, 20 Jul 2007) | 3 lines * doc/ref/neon.xml: Add a list of the functions using global state, for clarity. Add more symbol namespaces used by dependencies of neon. ------------------------------------------------------------------------ r1210 | joe | 2007-07-17 11:11:04 +0100 (Tue, 17 Jul 2007) | 2 lines * src/ne_session.h: Better docs for ne_session_status_info union. ------------------------------------------------------------------------ r1209 | joe | 2007-07-17 10:47:16 +0100 (Tue, 17 Jul 2007) | 2 lines * src/ne_session.h: Update ABI note for status union. ------------------------------------------------------------------------ r1208 | joe | 2007-07-16 11:25:10 +0100 (Mon, 16 Jul 2007) | 3 lines * macros/neon.m4 (NEON_SSL): Don't attempt to prevent incompatibility with future releases of GnuTLS. ------------------------------------------------------------------------ r1207 | joe | 2007-07-16 08:47:28 +0100 (Mon, 16 Jul 2007) | 2 lines * src/ne_xml.h, src/ne_socket.h: Documentation updates. ------------------------------------------------------------------------ r1206 | joe | 2007-07-16 08:39:43 +0100 (Mon, 16 Jul 2007) | 3 lines * src/ne_alloc.h (ne_realloc): Don't mark with malloc attribute, per GCC manual. ------------------------------------------------------------------------ r1205 | joe | 2007-07-16 07:54:57 +0100 (Mon, 16 Jul 2007) | 3 lines * src/ne_utils.h, src/ne_md5.h, src/ne_compress.h: Docs updates; use extern-C everywhere. No functional changes. ------------------------------------------------------------------------ r1204 | joe | 2007-07-16 07:40:03 +0100 (Mon, 16 Jul 2007) | 2 lines * src/ne_redirect.h: Cleanup docs; no functional change. ------------------------------------------------------------------------ r1203 | joe | 2007-07-16 07:35:17 +0100 (Mon, 16 Jul 2007) | 2 lines * src/ne_string.h: More docco cleanup; no functional changes. ------------------------------------------------------------------------ r1202 | joe | 2007-07-16 06:46:30 +0100 (Mon, 16 Jul 2007) | 2 lines * src/ne_string.h: Update docco for ne_buffer_*; no functional change. ------------------------------------------------------------------------ r1198 | joe | 2007-07-14 21:35:28 +0100 (Sat, 14 Jul 2007) | 2 lines Update credit roll, copyright notice. ------------------------------------------------------------------------ r1188 | joe | 2007-07-14 10:01:23 +0100 (Sat, 14 Jul 2007) | 2 lines * test/auth.c (multi_handler): Use any_request(). ------------------------------------------------------------------------ r1187 | joe | 2007-07-14 09:55:32 +0100 (Sat, 14 Jul 2007) | 4 lines * src/ne_auth.c (auth_register): Fix multiple handler use (Werner Baumann) * test/auth.c (multi_cb, multi_handler): New test case. ------------------------------------------------------------------------ r1185 | joe | 2007-07-14 09:05:02 +0100 (Sat, 14 Jul 2007) | 8 lines Make the backwards-compat break in the status notification interface more explicit by renaming the function: * src/ne_session.h, src/ne_session.c (ne_set_notifier): Renamed from ne_set_status. * test/request.c (status): Adjust accordingly. ------------------------------------------------------------------------ r1184 | joe | 2007-07-14 09:01:58 +0100 (Sat, 14 Jul 2007) | 2 lines * src/ne_ssl.h: Docs cleanup. ------------------------------------------------------------------------ r1183 | joe | 2007-07-12 21:37:51 +0100 (Thu, 12 Jul 2007) | 6 lines * src/ne_string.h (ne_buffer_snprintf): New prototype. * src/ne_string.c (ne_buffer_snprintf): New function. * test/string-tests.c (buf_print): New test case. ------------------------------------------------------------------------ r1182 | joe | 2007-07-12 11:38:00 +0100 (Thu, 12 Jul 2007) | 6 lines * src/ne_session.h: Add ne_status_disconnected status type. (ne_close_connection): Invoke the notifier callback. (ne_session_destroy): Close the connection earlier. * test/request.c (status_cb, status): Test ne_status_disconnected. ------------------------------------------------------------------------ r1181 | joe | 2007-07-11 23:23:02 +0100 (Wed, 11 Jul 2007) | 3 lines * src/ne_gnutls.c (ne__ssl_exit): Implement for recent versions of GnuTLS, per comment. ------------------------------------------------------------------------ r1180 | joe | 2007-07-03 13:01:39 +0100 (Tue, 03 Jul 2007) | 9 lines * src/ne_xml.h (ne_xml_resolve_nspace): New interface. * src/ne_xml.c (ne_xml_resolve_nspace): New function. * test/xml.c: Adjust all callbacks to take 'struct context' pointer. (parse_match): Pass a struct context pointer. (startelm): Add "eval-xmlns-" evaluators. (matches): Test namespace interfaces. ------------------------------------------------------------------------ r1179 | joe | 2007-07-03 10:14:52 +0100 (Tue, 03 Jul 2007) | 2 lines * doc/ref/err.xml: Update ne_get_error docs. ------------------------------------------------------------------------ r1178 | joe | 2007-07-02 17:34:33 +0100 (Mon, 02 Jul 2007) | 3 lines * doc/manual.xml: Split name and version to silence new docbook-xsl stylesheets. ------------------------------------------------------------------------ r1177 | joe | 2007-07-02 17:24:33 +0100 (Mon, 02 Jul 2007) | 2 lines * test/request.c (fail_statusline): Adjust for new error message. ------------------------------------------------------------------------ r1176 | joe | 2007-07-02 17:22:55 +0100 (Mon, 02 Jul 2007) | 9 lines * src/ne_openssl.c (check_identity): Take URI object as argument; handle URI subjectAltNames. (check_certificate, populate_cert): Adjust accordingly. * test/ssl.c (uri_altname, fail_bad_urialtname): Add tests. (cert_identities): Test the URI-altname cert. * test/openssl.conf, test/makekeys.sh: Create new test certs. ------------------------------------------------------------------------ r1175 | joe | 2007-07-02 17:17:32 +0100 (Mon, 02 Jul 2007) | 3 lines * src/ne_request.c, src/ne_redirect.c, src/ne_basic.c: Update error messages to omit trailing period. ------------------------------------------------------------------------ r1174 | joe | 2007-07-02 17:15:37 +0100 (Mon, 02 Jul 2007) | 3 lines * test/xml.c (parse_match): Give descriptive failures. (fail_parse): Enable tests for ill-formed UTF-8. ------------------------------------------------------------------------ r1173 | joe | 2007-06-27 14:43:32 +0100 (Wed, 27 Jun 2007) | 3 lines * src/ne_gnutls.c (ne_ssl_clicert_read): Update code/comment on friendly_name handling in encrypted c.certs. ------------------------------------------------------------------------ r1172 | joe | 2007-06-27 14:40:07 +0100 (Wed, 27 Jun 2007) | 3 lines * src/ne_gnutls.c (pkcs12_parse, ne_ssl_clicert_read): Remove now-redundant code on encrypted-cert path. ------------------------------------------------------------------------ r1171 | joe | 2007-06-27 14:39:10 +0100 (Wed, 27 Jun 2007) | 3 lines * src/ne_gnutls.c (pkcs12_parse, ne_ssl_clicert_read): Fix handling of PKCS#12 client certs with zero-length password. ------------------------------------------------------------------------ r1170 | joe | 2007-06-27 14:03:53 +0100 (Wed, 27 Jun 2007) | 7 lines * macros/neon.m4 (NEON_SSL): Check for gnutls_x509_dn_get_rdn_ava and iconv. * src/ne_gnutls.c [HAVE_GNUTLS_X509_DN_GET_RDN_AVA] (convert_dirstring, append_dirstring, ne_ssl_readable_dname): Implement better RDN handling using GnuTLS 1.7.x interfaces. ------------------------------------------------------------------------ r1169 | joe | 2007-06-17 22:20:30 +0100 (Sun, 17 Jun 2007) | 2 lines * doc/ref/alloc.xml: Fix prototype, thanks to Joshua Swink. ------------------------------------------------------------------------ r1165 | joe | 2007-04-03 21:25:13 +0100 (Tue, 03 Apr 2007) | 5 lines * src/ne_request.c (proxy_tunnel): Pass back error string and code for CONNECT failure. * test/ssl.c (auth_tunnel_fail): Add regression test for above. ------------------------------------------------------------------------ r1164 | joe | 2007-02-26 17:04:19 +0000 (Mon, 26 Feb 2007) | 3 lines * Makefile.in (install-nls-yes): Fix for VPATH builds, patch from Hans Meine. ------------------------------------------------------------------------ r1162 | joe | 2007-02-08 09:45:10 +0000 (Thu, 08 Feb 2007) | 2 lines * config.hw.in: Define NE_FMT_NE_OFF_T. ------------------------------------------------------------------------ r1161 | joe | 2007-02-07 17:45:05 +0000 (Wed, 07 Feb 2007) | 4 lines * src/ne_auth.c (ah_post_send): Fix for SSPI to avoid invoking the NULL response header verification callback (patch from dicuccio@comcast.net). ------------------------------------------------------------------------ r1160 | joe | 2007-02-07 17:38:50 +0000 (Wed, 07 Feb 2007) | 2 lines * src/ne_auth.c: Update comment. ------------------------------------------------------------------------ r1159 | joe | 2007-02-07 17:36:25 +0000 (Wed, 07 Feb 2007) | 7 lines * src/ne_string.c (ne_strerror): Handle failure cases for POSIX-style strerror_r; always use a temp buffer and copy back to truncate rather than fail for a short input buffer. * test/string-tests.c (str_errors): Test for handling of bogus errno values into too-short buffer. ------------------------------------------------------------------------ r1158 | joe | 2007-02-06 12:46:23 +0000 (Tue, 06 Feb 2007) | 3 lines * test/util-tests.c (digest_md5, md5): Meet alignment requirement of MD5 API. ------------------------------------------------------------------------ r1156 | joe | 2007-02-05 14:10:27 +0000 (Mon, 05 Feb 2007) | 3 lines * src/ne_socket.c (write_raw): Work around QNX issue passing large buffers to send() over loopback; send 8K at a time. ------------------------------------------------------------------------ r1155 | joe | 2007-02-05 13:11:00 +0000 (Mon, 05 Feb 2007) | 4 lines * src/ne_auth.c (verify_negotiate_response): Fix comparison of Negotiate response header token, and set error message on failure. ------------------------------------------------------------------------ r1154 | joe | 2007-02-05 13:07:09 +0000 (Mon, 05 Feb 2007) | 3 lines * src/ne_auth.c (ah_pre_send): Set request idempotent flag for SSPI to prevent connection closure. ------------------------------------------------------------------------ r1153 | joe | 2007-02-05 10:09:27 +0000 (Mon, 05 Feb 2007) | 2 lines * src/ne_locks.c (lk_pre_send): Terminate If header with CRLF not LF. ------------------------------------------------------------------------ r1152 | joe | 2007-01-26 00:00:59 +0000 (Fri, 26 Jan 2007) | 5 lines Build fixes for SSPI code on MingW from Gisle Vanem: * src/ne_sspi.c: Define SECURITY_ENTRYPOINT if missing. (base64ToBuffer): Fix cast. ------------------------------------------------------------------------ r1132 | joe | 2007-01-11 22:12:58 +0000 (Thu, 11 Jan 2007) | 13 lines Fix 0.26.x regression; ensure the "attempt" counter passed to creds callbacks reflects the number of invocation of that callback only per request: * src/ne_auth.c (struct auth_handler): Add attempt field. (get_credentials): Use per-handler attempt counter and post-increment same. (ah_create): Reset per-request attempt counters. (auth_register): Initialize attempt counter. * test/auth.c (fail_challenge): Add test for attempt handling regression. ------------------------------------------------------------------------ r1131 | joe | 2007-01-11 21:33:14 +0000 (Thu, 11 Jan 2007) | 5 lines * src/ne_uri.c (uri_lookup): Fix cast to prevent buffer under-read on non-ASCII characters (CVE-2007-0157, Laszlo Boszormenyi). * test/uri-tests.c (parse): Add test case. ------------------------------------------------------------------------ r1130 | joe | 2007-01-09 11:24:54 +0000 (Tue, 09 Jan 2007) | 2 lines * src/ne_auth.c (digest_challenge): Fix comment. ------------------------------------------------------------------------ r1129 | joe | 2007-01-06 14:27:18 +0000 (Sat, 06 Jan 2007) | 10 lines * src/ne_auth.c (digest_challenge): Fix to fail correctly for invalid case where stale=true is given with an initial challenge; fix to not leak sess->nonce for a valid stale challenge. * test/auth.c (struct digest_parms): Add stale field, enum value. (make_digest_header): Send stale=true as appropriate. (serve_digest): Adjust to serve challenges with stale=true. (digest): Add test for stale=true handling. (digest_failures): Add test for error stale=true failure case. ------------------------------------------------------------------------ r1128 | joe | 2007-01-05 11:07:32 +0000 (Fri, 05 Jan 2007) | 3 lines * src/ne_request.c (ne_begin_request): Move call to lookup_host from here... (open_connection): ...to here; and simplify slightly as a result. ------------------------------------------------------------------------ r1126 | joe | 2007-01-04 18:44:49 +0000 (Thu, 04 Jan 2007) | 13 lines Fix nextnonce handling in Digest auth: * src/ne_auth.c (verify_digest_response): Reset nonce-count on receipt of next-nonce parameter in A-I response header. * test/auth.c (struct digest_parms): Add send_nextnonce, num_requests fields. (make_authinfo_header): Invent new nonce if send_nextnonce field is set. (serve_digest, test_digest): Handle num_requests requests. (digest): Set new parameter fields; test for next-nonce handling. (digest_failure): Set new paramater fields. ------------------------------------------------------------------------ r1125 | joe | 2007-01-04 18:08:52 +0000 (Thu, 04 Jan 2007) | 3 lines * test/auth.c (make_authinfo_header, digest_failures): Add test for failure to parse the nc paramater in an A-I response header. ------------------------------------------------------------------------ r1124 | joe | 2007-01-03 22:13:05 +0000 (Wed, 03 Jan 2007) | 18 lines Give descriptive error messages for multiple-challenge authentication failures: * src/ne_auth.c (struct auth_class): Add error_noauth field. (struct auth_protocol): Pass errmsg buffers to challenge callback; specify error message location for verify callback. (challenge_error): New function. (get_credentials, basic_challenge, continue_negotiate, negotiate_challenge, digest_challenge): Take errmsg buffer; use challenge_error on failure. (verify_negotiate_response): Create errmsg buffer, pass to continue_negotiate, and set session error string on failure. (auth_challenge): Create error buffer and build error message during challenge parsing. * test/auth.c (digest_failures): Adjust for new error string. (fail_cb, fail_challenge): Add tests for challenge parse failures. ------------------------------------------------------------------------ r1123 | joe | 2006-12-29 23:34:09 +0000 (Fri, 29 Dec 2006) | 2 lines * test/socket.c (connect_timeout): Remove redundant code. ------------------------------------------------------------------------ r1121 | joe | 2006-12-28 23:41:31 +0000 (Thu, 28 Dec 2006) | 3 lines * src/ne_session.h (ne_ssl_set_clicert, ne_ssl_trust_cert): Clarify lack of lifetime requirement for passed-in objects. ------------------------------------------------------------------------ r1120 | joe | 2006-12-28 23:19:57 +0000 (Thu, 28 Dec 2006) | 2 lines * TODO: Remove features already added. ------------------------------------------------------------------------ r1119 | joe | 2006-12-28 23:12:18 +0000 (Thu, 28 Dec 2006) | 27 lines Add support for configurable socket connect timeouts: * src/ne_socket.h (ne_sock_connect_timeout): New function. (ne_sock_connect): Clarify timeout handling. * src/ne_socket.c: Define USE_NONBLOCKING_CONNECT if appropriate. Define NE_ISINPROGRESS. (struct ne_socket_s): Add cotimeout field. (timed_connect): New function. (connect_socket): Renamed from raw_connect; use timed_connect; takes socket structure and sets ->error string on failure. (ne_sock_connect): Adapt to use connect_socket. (ne_sock_connect_timeout): New function. * src/ne_private.h (struct ne_session_s): Add cotimeout field. * src/ne_session.h (ne_set_connect_timeout): New prototype... * src/ne_session.c (ne_set_connect_timeout): ...implement it. * src/ne_request.c (do_connect): Set socket timeout if appropriate. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Check for fcntl, getsockopt, fcntl.h and socklen_t. * test/socket.c (connect_timeout): Add test (disabled by default). ------------------------------------------------------------------------ r1118 | joe | 2006-12-28 23:04:28 +0000 (Thu, 28 Dec 2006) | 3 lines * src/ne_socket.c (raw_poll): Factor out from readable_raw. (readable_raw): Use it. ------------------------------------------------------------------------ r1109 | joe | 2006-12-28 17:20:56 +0000 (Thu, 28 Dec 2006) | 5 lines Merge r1106 from 0.25.x branch: * macros/neon-test.m4 (NE_FORMAT_TIMET): Factor out. (NEON_TEST): Use it. ------------------------------------------------------------------------ r1104 | joe | 2006-11-30 13:03:34 +0000 (Thu, 30 Nov 2006) | 3 lines * test/request.c (fail_double_lookup, proxy_no_resolve): Use hostname in the .invalid TLD, reserved by RFC2606. ------------------------------------------------------------------------ r1103 | joe | 2006-11-08 13:41:10 +0000 (Wed, 08 Nov 2006) | 3 lines * test/socket.c (write_reset): Warn rather than fail for a failure to elicit an RST. ------------------------------------------------------------------------ r1102 | joe | 2006-10-31 10:35:38 +0000 (Tue, 31 Oct 2006) | 2 lines Note the reports about a GSSAPI problem. ------------------------------------------------------------------------ r1098 | joe | 2006-10-30 12:35:21 +0000 (Mon, 30 Oct 2006) | 7 lines Fix real cause of h_errno problem on HP-UX (Albert Chin): * macros/neon.m4: Drop _XOPEN_SOURCE_EXTENDED definition for HP-UX. * src/ne_socket.c: Use HAVE_DECL_H_ERRNO macro correctly. ------------------------------------------------------------------------ r1097 | joe | 2006-10-30 12:33:34 +0000 (Mon, 30 Oct 2006) | 2 lines * src/ne_session.h: Remove trailing comma from new enum (Albert Chin). ------------------------------------------------------------------------ r1096 | joe | 2006-10-30 12:32:45 +0000 (Mon, 30 Oct 2006) | 2 lines * src/ne_session.h: Docs clarification for new notification interface. ------------------------------------------------------------------------ r1095 | joe | 2006-10-24 21:32:50 +0100 (Tue, 24 Oct 2006) | 3 lines * test/request.c (s_progress): Fix to use ne_off_t types and format strings. ------------------------------------------------------------------------ r1094 | joe | 2006-10-24 21:26:15 +0100 (Tue, 24 Oct 2006) | 20 lines Add add new type-safer notification/status API: * src/ne_session.h (ne_notify_status): Redefine callback type, passing pointer to ne_session_status_info structure. * src/ne_request.c (notify_status): Invoke notify callback, and progress callback as appropriate. (send_request_body, ne_read_response_block, lookup_host, ne_begin_request, do_connect): Adjust to set up and invoke the notify callback. * src/ne_openssl.c (ne__negotiate_ssl): Drop notify callback invocation. * src/ne_private.h (struct ne_session_s): Store status union. * macros/neon.m4: Define NE_FMT_NE_OFF_T. * test/request.c (status_cb, status): Add new test. ------------------------------------------------------------------------ r1093 | joe | 2006-10-24 20:45:01 +0100 (Tue, 24 Oct 2006) | 3 lines * src/ne_auth.c (ah_post_send): Correctly test ->flags against AUTH_FLAG_VERIFY_NON40x flag. ------------------------------------------------------------------------ r1092 | joe | 2006-10-24 20:40:09 +0100 (Tue, 24 Oct 2006) | 26 lines Simplify LFS support, drop *64 transition functions: * src/ne_defs.h: Add ne_off_t typedef. * src/ne_request.h (ne_set_request_body_fd64, ne_set_request_body_provider64): Removed. (ne_set_request_body_fd, ne_set_request_body_provider): Take ne_off_t arguments. * src/ne_internal.h: Move LFS definitions here... * src/ne_request.c: ...from here. (ne_set_request_body_fd64, ne_set_request_body_provider64): Removed. (ne_set_request_body_fd, ne_set_request_body_provider): Adjust for ne_off_t arguments. * src/ne_basic.h (ne_get_range64): Removed prototype. (ne_content_range): Use ne_off_t offsets. * src/ne_basic.c (ne_get_range64): Removed function. (ne_get_range): Adjust for ne_off_t offsets. * test/largefile.c (send_high_offset, read_large_response): Adjust to use normal interfaces. Save and restore debug mask. ------------------------------------------------------------------------ r1086 | joe | 2006-10-05 19:31:18 +0100 (Thu, 05 Oct 2006) | 9 lines * macros/neon.m4 (NE_CHECK_OS): Split out from NE_OS_*. Conditionally add _XOPEN_SOURCE_EXTENDED=1 to CPPFLAGS for HP-UXes. (LIBNEON_SOURCE_CHECKS): Remove _XOPEN_SOURCE_EXTENDED definition here. (NE_OS_MINGW, NE_MACOSX): Removed. (NE_SEARCH_LIBS): Adjust for ne_cv_os_uname. * src/ne_socket.c: Don't set _XOPEN_SOURCE_EXTENDED here. ------------------------------------------------------------------------ r1084 | joe | 2006-10-05 14:10:00 +0100 (Thu, 05 Oct 2006) | 7 lines * test/makekeys.sh: Remove hostname-based munging for wildcard cert; always use *.example.com. * test/ssl.c (tunnel_server): New function. (wildcard_match): Use a proxy to avoid using real hostnames. (wildcard_init): Removed function. ------------------------------------------------------------------------ r1080 | joe | 2006-10-05 13:33:33 +0100 (Thu, 05 Oct 2006) | 3 lines * macros/neon.m4 (NEON_I18N): Really disable i18n if libintl.h is not detected. ------------------------------------------------------------------------ r1079 | joe | 2006-10-03 22:03:31 +0100 (Tue, 03 Oct 2006) | 2 lines * test/request.c (fail_noheader): New regression test. ------------------------------------------------------------------------ r1078 | joe | 2006-10-03 21:31:28 +0100 (Tue, 03 Oct 2006) | 7 lines Fix error reported for LOCK responses which lack a Lock-Token header: * src/ne_locks.c (struct lock_ctx): Add parser pointer. (lk_startelm): Set XML parser error when failing parse. (ne_lock, ne_lock_refresh): Set parser in context; omit explicit XML parse error handling already done by ne_xml_dispatch_request. ------------------------------------------------------------------------ r1077 | joe | 2006-09-26 10:35:46 +0100 (Tue, 26 Sep 2006) | 14 lines * src/ne_xmlreq.h (ne_xml_dispatch_request): Update API semantics to constrain media type of parsed responses. * src/ne_xmlreq.c (media_type_is_xml): New function. (ne_xml_dispatch_request): Use it; only parse 2xx responses with XML media types. * test/xmlreq.c (startelm): New function. (success): Check XML is actually parsed. (types): New test. * test/lock.c (lock_timeout, lock_shared): Add content-type for XML responses. ------------------------------------------------------------------------ r1076 | joe | 2006-09-26 10:18:09 +0100 (Tue, 26 Sep 2006) | 2 lines * src/ne_request.c (ne_begin_request): Remove redundant test. ------------------------------------------------------------------------ r1075 | joe | 2006-09-26 10:13:42 +0100 (Tue, 26 Sep 2006) | 18 lines Add new hook which runs after the headers have been read: * src/ne_request.h (ne_post_headers_fn, ne_hook_post_headers): Add type, prototype. * src/ne_private.h (struct ne_session_s): Add post_headers_hooks field. * src/ne_request.c (ne_begin_request): Run post_headers hooks. * src/ne_session.c (ne_session_destroy): Destroy post_headers hooks. (ne_hook_post_headers, ne_unhook_post_headers): New functions. * test/request.c (status_to_string): New function. (hook_post_send): Use it. (hook_post_headers): New function. (hooks): Test post_headers hook. ------------------------------------------------------------------------ r1073 | joe | 2006-09-13 18:38:32 +0100 (Wed, 13 Sep 2006) | 2 lines * macros/neon.m4 (NE_OS_MINGW): Update comment, thanks to Matthias Miller. ------------------------------------------------------------------------ r1072 | joe | 2006-09-12 22:04:31 +0100 (Tue, 12 Sep 2006) | 7 lines Fix library detection on MinGW, based on patch by Matthias Miller: * macros/neon.m4 (NE_OS_MINGW): New macro. (NE_SEARCH_LIBS): Check for function using __stdcall calling convention if on MinGW and library to search is -lws2_32. (LIBNEON_SOURCE_CHECKS): Also check for gethostbyname in -lws2_32. ------------------------------------------------------------------------ r1071 | joe | 2006-09-12 21:54:17 +0100 (Tue, 12 Sep 2006) | 2 lines * src/ne_uri.c (ne_path_lower): Avoid use of min() (Matthias Miller). ------------------------------------------------------------------------ r1070 | joe | 2006-09-12 19:51:28 +0100 (Tue, 12 Sep 2006) | 4 lines * src/ne_acl.h (ne_acl_set): Take const entries array. * src/ne_acl.c (ne_acl_set, acl_body): Likewise. ------------------------------------------------------------------------ r1069 | joe | 2006-09-12 18:38:57 +0100 (Tue, 12 Sep 2006) | 7 lines Remove use of session-private interfaces in auth code: * src/ne_auth.c: Drop ne_private.h #include. (sspi_challenge) [HAVE_SSPI]: Use ne_fill_server_uri. (auth_register) [HAVE_GSSAPI]: Use ne_fill_proxy_uri or ne_fill_server_uri. ------------------------------------------------------------------------ r1068 | joe | 2006-09-12 18:36:41 +0100 (Tue, 12 Sep 2006) | 10 lines Update for bleeding-edge OpenSSL thread-safety interfaces: * macros/neon.m4 (NEON_SSL): Check for CRYPTO_set_idptr_callback. * src/ne_openssl.c (thread_id_neon): Update comments. (ID_CALLBACK_IS_OTHER, ID_CALLBACK_IS_NEON): New macros. (ne__ssl_init, ne__ssl_exit): Update to use avoid touching the "id" callback if the idptr interfaces exist, since the default will be sane. ------------------------------------------------------------------------ r1067 | joe | 2006-09-12 14:52:39 +0100 (Tue, 12 Sep 2006) | 2 lines * src/ne_string.h (ne_strnzcpy): Avoid expanding argument twice. ------------------------------------------------------------------------ r1065 | joe | 2006-09-05 08:39:48 +0100 (Tue, 05 Sep 2006) | 4 lines * src/ne_string.c (ascii_tolower): Use integer constants rather than character constants to fix warnings with Sun cc; patch from Peter O'Gorman. ------------------------------------------------------------------------ r1064 | joe | 2006-08-09 15:56:04 +0100 (Wed, 09 Aug 2006) | 2 lines * config.hw.in: Fixes for newer SDKs; patch from Kiyo Kelvin Lee. ------------------------------------------------------------------------ r1063 | joe | 2006-08-09 15:54:51 +0100 (Wed, 09 Aug 2006) | 2 lines * src/ne_sspi.c (resetContext): Fix build with older SDKs. ------------------------------------------------------------------------ r1062 | joe | 2006-08-09 15:49:12 +0100 (Wed, 09 Aug 2006) | 3 lines * src/ne_sspi.c (ne_sspi_clear_context): Add missing return statement; patch from Kiyo Kelvin Lee. ------------------------------------------------------------------------ r1058 | joe | 2006-07-17 12:52:11 +0100 (Mon, 17 Jul 2006) | 2 lines * config.hw.in: Enable debugging for Win32 build. ------------------------------------------------------------------------ r1057 | joe | 2006-06-29 16:02:03 +0100 (Thu, 29 Jun 2006) | 7 lines * src/ne_session.h (ne_fill_proxy_uri): New prototype. (ne_fill_server_uri): Clarify. * src/ne_session.c (ne_fill_proxy_uri): New function. * test/session.c (fill_proxy_uri): New test. ------------------------------------------------------------------------ r1056 | joe | 2006-06-29 15:44:37 +0100 (Thu, 29 Jun 2006) | 2 lines * src/ne_auth.c (auth_session): Remove unused fields. ------------------------------------------------------------------------ r1055 | joe | 2006-06-26 12:25:20 +0100 (Mon, 26 Jun 2006) | 3 lines * src/ne_openssl.c (ne__ssl_init): Call CRYPTO_malloc_init() first per dev@apr discussion. ------------------------------------------------------------------------ r1054 | joe | 2006-06-26 11:01:29 +0100 (Mon, 26 Jun 2006) | 4 lines * configure.in: Substitute NEON_PC_LIBS for neon.pc. * neon.pc.in: Define Libs.Private; use only NEON_PC_LIBS in Libs. ------------------------------------------------------------------------ r1049 | joe | 2006-05-23 21:17:41 +0100 (Tue, 23 May 2006) | 6 lines Readonly data fixes from Benoît Dejean: * src/ne_xml.c (empty_atts): Mark more const. * src/ne_dates.c (rfc1123_weekdays, short_months): Mark more const. ------------------------------------------------------------------------ r1046 | joe | 2006-05-11 10:43:43 +0100 (Thu, 11 May 2006) | 1 line * po/: make update-po. ------------------------------------------------------------------------ r1045 | joe | 2006-05-11 10:41:55 +0100 (Thu, 11 May 2006) | 3 lines * configure.in, po/zh.po: Add Simplified Chinese translation, from Dongsheng Song. ------------------------------------------------------------------------ r1044 | joe | 2006-05-09 08:02:43 +0100 (Tue, 09 May 2006) | 6 lines Win32 build fixes from D.J. Heap: * src/ne_auth.c: Move protocols[] array declaration up, remove forward-declaration. (request_sspi): Fix declaration. ------------------------------------------------------------------------ r1020 | joe | 2006-03-24 12:24:39 +0000 (Fri, 24 Mar 2006) | 2 lines * test/run.sh: Don't limit virtual memory use. ------------------------------------------------------------------------ r1016 | joe | 2006-03-14 16:57:43 +0000 (Tue, 14 Mar 2006) | 3 lines * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Make the timezone test match the code; fix OS X build. ------------------------------------------------------------------------ r1004 | joe | 2006-03-11 18:51:51 +0000 (Sat, 11 Mar 2006) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r1003 | joe | 2006-03-11 18:49:46 +0000 (Sat, 11 Mar 2006) | 18 lines * macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates.* macros/neon.m4: Bump to 0.26.0. * NEWS: Final updates. ------------------------------------------------------------------------ r1002 | joe | 2006-03-11 18:46:05 +0000 (Sat, 11 Mar 2006) | 2 lines * README, AUTHORS: Update copyright info. ------------------------------------------------------------------------ r1001 | joe | 2006-03-11 18:44:14 +0000 (Sat, 11 Mar 2006) | 4 lines * doc/manual.xml: s/GFDL/GPL/ for Debian policy compliance. * doc/fdl.sgml: Removed. ------------------------------------------------------------------------ r999 | joe | 2006-03-10 10:45:03 +0000 (Fri, 10 Mar 2006) | 2 lines * test/lock.c (fail_lockauth): Use many_serve_string. ------------------------------------------------------------------------ r998 | joe | 2006-03-10 10:23:54 +0000 (Fri, 10 Mar 2006) | 2 lines * doc/ref/neon.xml: Fix typo. ------------------------------------------------------------------------ r996 | joe | 2006-03-08 10:30:07 +0000 (Wed, 08 Mar 2006) | 3 lines * src/ne_auth.c (ah_post_send): Remove strdup which is now unnecessary. ------------------------------------------------------------------------ r995 | joe | 2006-03-08 10:22:18 +0000 (Wed, 08 Mar 2006) | 3 lines * src/ne_auth.c (negotiate_challenge): Renamed from gssapi_challenge. (request_negotiate): Renamed from request_gssapi. ------------------------------------------------------------------------ r994 | joe | 2006-03-07 21:38:21 +0000 (Tue, 07 Mar 2006) | 7 lines * src/ne_private.h (struct ne_session_s): Remove use of bitfields. * src/ne_auth.c (struct auth_session_s): Likewise. * src/ne_request.c (struct body_reader, struct ne_request_s): Likewise. ------------------------------------------------------------------------ r993 | joe | 2006-03-07 21:29:19 +0000 (Tue, 07 Mar 2006) | 3 lines * src/ne_basic.c (ne_put) [NE_LFS]: Use ne_set_request_body_fd64, fstat64. ------------------------------------------------------------------------ r992 | joe | 2006-03-07 21:25:41 +0000 (Tue, 07 Mar 2006) | 6 lines * src/ne_basic.h (ne_get_range64): Add prototype. * src/ne_basic.c (get_range_common): Factored out from ne_get_range. (ne_get_range): Use get_range_common. (ne_get_range64): Implement. ------------------------------------------------------------------------ r991 | joe | 2006-03-07 09:47:07 +0000 (Tue, 07 Mar 2006) | 2 lines * src/ne_request.c (read_status_line): Update comment. ------------------------------------------------------------------------ r990 | joe | 2006-03-07 09:36:43 +0000 (Tue, 07 Mar 2006) | 6 lines * src/ne_utils.h (NE_FEATURE_I18N): Add macro. * src/ne_utils.c (ne_has_support): Support NE_FEATURE_I18N. * test/util-tests.c (support): Test for NE_FEATURE_I18N. ------------------------------------------------------------------------ r989 | joe | 2006-03-07 09:34:43 +0000 (Tue, 07 Mar 2006) | 2 lines * src/ne_session.h: Fix typo. ------------------------------------------------------------------------ r980 | joe | 2006-03-01 20:31:52 +0000 (Wed, 01 Mar 2006) | 4 lines * src/ne_basic.c (dispatch_to_fd): Fix ne_get() regression. * test/basic.c (get): Add test case. ------------------------------------------------------------------------ r979 | joe | 2006-03-01 20:04:06 +0000 (Wed, 01 Mar 2006) | 4 lines * src/ne_basic.c (dispatch_to_fd): Fix content-range parsing. * test/basic.c (get_range, fail_range_*): Fix test cases. ------------------------------------------------------------------------ r978 | joe | 2006-03-01 19:53:59 +0000 (Wed, 01 Mar 2006) | 4 lines * src/ne_uri.c (URI_ESCAPE): Do path-escape "%". * test/uri-tests.c (escapes): Add test cases. ------------------------------------------------------------------------ r976 | joe | 2006-03-01 18:53:30 +0000 (Wed, 01 Mar 2006) | 3 lines * Makefile.in (update-po): Send output to /dev/null when checking format strings. ------------------------------------------------------------------------ r975 | joe | 2006-03-01 17:59:02 +0000 (Wed, 01 Mar 2006) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r974 | joe | 2006-03-01 17:57:45 +0000 (Wed, 01 Mar 2006) | 2 lines Clarify remaining GnuTLS issues. ------------------------------------------------------------------------ r973 | joe | 2006-03-01 17:49:53 +0000 (Wed, 01 Mar 2006) | 3 lines * macros/neon.m4 (NEON_USE_EXTERNAL): Check for TS_SSL feature. (NEON_SSL): Disable TS_SSL feature for non-SSL builds. ------------------------------------------------------------------------ r972 | joe | 2006-03-01 17:45:02 +0000 (Wed, 01 Mar 2006) | 3 lines * src/ne_session.c (ne_ssl_cert_validity): Handle ne_ssl_cert_validity_time()'s error cases. ------------------------------------------------------------------------ r971 | joe | 2006-03-01 17:40:44 +0000 (Wed, 01 Mar 2006) | 2 lines Document changes for 0.26.0. ------------------------------------------------------------------------ r970 | joe | 2006-03-01 17:28:58 +0000 (Wed, 01 Mar 2006) | 23 lines Move to opaque MD5 context, avoiding exposure of md5_uint32 type: * src/ne_md5.h: Make struct ne_md5_ctx opaque. (ne_md5_create_ctx, ne_md5_reset_ctx, ne_md5_destroy_ctx): New prototypes. (ne_md5_init_ctx): Removed prototype. * src/ne_md5.c: Add struct ne_md5_ctx definition; use simpler autoconf-based md5_uint32 definition. (ne_md5_create_ctx, ne_md5_destroy_ctx, ne_md5_reset_ctx): New functions. (ne_md5_init_ctx): Make static. * src/ne_auth.c (auth_session): Store a pointer to the MD5 context. (clean_session): Destroy stored MD5 context if necessary. (get_cnonce, digest_challenge, request_digest, verify_digest_response): Adjust to use opaque context constructor/destructor. * test/auth.c (make_digest): Adjust likewise. * test/util-test.c (digest_md5, md5_alignment): Adjust likewise. * config.hw.in: Define SIZEOF_INT, SIZEOF_LONG. ------------------------------------------------------------------------ r969 | joe | 2006-02-28 22:37:49 +0000 (Tue, 28 Feb 2006) | 2 lines * src/ne_md5.h: Remove support for non-C89 prototypes. ------------------------------------------------------------------------ r968 | joe | 2006-02-28 22:27:11 +0000 (Tue, 28 Feb 2006) | 20 lines Formalize the date formatting by ne_ssl_cert_validity and add ne_ssl_cert_validity_time, which is better for i18n: * src/ne_ssl.h (ne_ssl_cert_validity): Adopt a fixed format for returned date. (ne_ssl_cert_validity_time): New prototype. * src/ne_openssl.c (asn1time_to_timet, ne_ssl_cert_validity_time): New functions. * src/ne_gnutls.c (ne_ssl_cert_validity_time): New function. * src/ne_session.c (ne_ssl_cert_validity): New function. * src/ne_stubssl.c (ne_ssl_cert_validity_time): New stub. * test/ssl.c (cert_validity): Adjust for new date formatting. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Check for timezone global. ------------------------------------------------------------------------ r967 | joe | 2006-02-28 16:26:32 +0000 (Tue, 28 Feb 2006) | 10 lines Avoid most issues with misaligned md5 result buffers: * src/ne_md5.c (ne_md5_finish_ascii): New function. * src/ne_md5.h (ne_md5_finish_ascii): Add prototype. * src/ne_auth.c (get_cnonce, digest_challenge, request_digest, verify_digest_response): Use ne_md5_finish_ascii in place of ne_md5_finish_ctx/ne_md5_to_ascii. ------------------------------------------------------------------------ r965 | joe | 2006-02-27 18:12:31 +0000 (Mon, 27 Feb 2006) | 2 lines * doc/manual.xml: Include the ne_i18n_init refentry. ------------------------------------------------------------------------ r964 | joe | 2006-02-27 18:11:31 +0000 (Mon, 27 Feb 2006) | 5 lines * doc/ref/i18n.xml: New file. * doc/ref/init.xml, doc/ref/neon.xml: More process-global initialization stuff. ------------------------------------------------------------------------ r963 | joe | 2006-02-27 17:43:42 +0000 (Mon, 27 Feb 2006) | 2 lines * src/ne_props.c (ne_propfind_create): Use ne_buffer_czappend. ------------------------------------------------------------------------ r962 | joe | 2006-02-27 17:30:26 +0000 (Mon, 27 Feb 2006) | 2 lines * doc/ref/feat.xml: Fix id, use an xref, improve text, add see also. ------------------------------------------------------------------------ r961 | joe | 2006-02-27 17:29:18 +0000 (Mon, 27 Feb 2006) | 2 lines * doc/ref/reqbody.xml: Document ne_set_request_body_fd*. ------------------------------------------------------------------------ r960 | joe | 2006-02-27 17:28:34 +0000 (Mon, 27 Feb 2006) | 25 lines Add destructor callback to PROPFIND interface to guarantee cleanup of memory allocated by the creator callback: * src/ne_props.h (ne_propfind_set_private): Take destructor argument. * src/ne_props.c (struct ne_propfind_handler_s): Add destructor field, rename private_creator to creator and private_userdata to cd_userdata. (start_response): Adjust for field renames. (free_propset): Take handler argument; call destructor if necessary. (end_response, ne_propfind_destroy): Pass handler to free_propset. (ne_propfind_set_private): Adjust for field renames, store destructor. * src/ne_locks.c (discover_results): Don't destroy lock here. (ld_destroy): New function. (ne_lock_discover): Register the destructor. * test/lock.c: Mark fail_discover as no-longer-expected-to-leak. * test/props.c (diffcmp): Improve diagnostics. (pf_creator, pf_destructor): New functions. (run_propfind): Renamed from run_simple_propfind; enhanced to run non-simple PROPFIND requests too. (propfind): Renamed from pfind_simple; call run_propfind; test invocation of creator/destructor callbacks too. ------------------------------------------------------------------------ r959 | joe | 2006-02-27 11:36:54 +0000 (Mon, 27 Feb 2006) | 5 lines * macros/neon.m4 (NEON_SSL): Don't define HAVE_PTHREADS. * src/ne_gnutls.c, src/ne_openssl.c: Use NE_HAVE_TS_SSL feature macro in place of HAVE_PTHREADS. ------------------------------------------------------------------------ r958 | joe | 2006-02-27 11:33:53 +0000 (Mon, 27 Feb 2006) | 4 lines * src/ne_openssl.c (thread_id_neon): Revert previous change (which is more portable, but less safe), and replace with a rant on why OpenSSL is completely broken. ------------------------------------------------------------------------ r957 | joe | 2006-02-27 11:17:40 +0000 (Mon, 27 Feb 2006) | 3 lines * src/ne_openssl.c (thread_id_neon): Work regardless of whether pthread_t is a structure. ------------------------------------------------------------------------ r956 | joe | 2006-02-27 11:10:29 +0000 (Mon, 27 Feb 2006) | 2 lines * src/ne_session.c (ne__ssl_set_verify_err): Make array static const. ------------------------------------------------------------------------ r955 | joe | 2006-02-27 10:41:21 +0000 (Mon, 27 Feb 2006) | 9 lines * src/ne_session.c (ne__ssl_set_verify_err): Moved here... * src/ne_openssl.c (verify_err): ... from here. (check_certificate): Use it. * src/ne_gnutls.c (check_certificate): Use it on verification failure. * src/ne_private.h (ne__ssl_set_verify_err): Add prototype. ------------------------------------------------------------------------ r954 | joe | 2006-02-26 20:59:08 +0000 (Sun, 26 Feb 2006) | 3 lines * doc/ref/init.xml, doc/ref/neon.xml: Document thread-safe SSL handling. ------------------------------------------------------------------------ r953 | joe | 2006-02-26 20:55:43 +0000 (Sun, 26 Feb 2006) | 11 lines * macros/neon.m4 (NEON_SSL): Define a feature macro for thread-safe SSL support. * src/ne_utils.h: Add NE_FEATURE_TS_SSL feature code. * src/ne_utils.c (ne_has_support): Support it (or... not). * neon-config.in: Add feature code. * test/util-tests.c (support): Test for it. ------------------------------------------------------------------------ r952 | joe | 2006-02-26 20:52:58 +0000 (Sun, 26 Feb 2006) | 4 lines * doc/manual.xml: Add ne_has_support refentry. * doc/ref/feat.xml: New document. ------------------------------------------------------------------------ r951 | joe | 2006-02-26 10:11:31 +0000 (Sun, 26 Feb 2006) | 3 lines * test/request.c (hooks): Use many_serve_string to serve the three responses, to avoid spurious failures. ------------------------------------------------------------------------ r950 | joe | 2006-02-25 23:23:56 +0000 (Sat, 25 Feb 2006) | 3 lines * test/Makefile.in: Add some missing dependencies on the "random file", NEWS. ------------------------------------------------------------------------ r949 | joe | 2006-02-25 23:17:45 +0000 (Sat, 25 Feb 2006) | 4 lines * src/ne_basic.c (ne_post): Flag POST request as non-idempotent. * src/ne_locks.c (ne_lock): Flag LOCK request as non-idempotent. ------------------------------------------------------------------------ r948 | joe | 2006-02-25 23:16:51 +0000 (Sat, 25 Feb 2006) | 3 lines Interfaces to allow correct handling of non-idempotent requests done, and SSLv2-disabling done. ------------------------------------------------------------------------ r947 | joe | 2006-02-25 23:16:11 +0000 (Sat, 25 Feb 2006) | 17 lines Add per-request flags interface, and correct retry handling of non-idempotent methods: * src/ne_request.h (ne_set_request_flag, ne_get_request_flag): New prototypes. (ne_set_request_expect100): Remove prototype. * src/ne_request.c (struct ne_request_s): Add flags array, remove use_expect100 field. (ne_set_request_flag, ne_get_request_flag): New functions. (ne_set_request_expect100): Remove function. (build_request, send_request): Adapt to use expect100 flag. (ne_begin_request): I * test/request.c (expect_100_once, expect_100_nobody): Use ne_set_request_flag. ------------------------------------------------------------------------ r946 | joe | 2006-02-25 23:09:08 +0000 (Sat, 25 Feb 2006) | 3 lines * src/ne_openssl.c (ne_ssl_context_set_flag): Fix to actually respect the flag setting. ------------------------------------------------------------------------ r945 | joe | 2006-02-25 16:29:54 +0000 (Sat, 25 Feb 2006) | 10 lines Forward-port ICY protocol support from 0.25.x branch, conditional on NE_SESSFLAG_ICYPROTO. * src/ne_session.h: Add NE_SESSFLAG_ICYPROTO flag. * src/ne_request.c (read_status_line): Parse ICY responses if flag is set. * test/request.c (icy_protocol): Add test case. ------------------------------------------------------------------------ r944 | joe | 2006-02-25 16:26:50 +0000 (Sat, 25 Feb 2006) | 17 lines * src/ne_ssl.h (NE_SSL_CTX_SSLv2): New constant. (ne_ssl_context_set_flag): New prototype. * src/ne_stubssl.c (ne_ssl_context_set_flag): New stub. * src/ne_openssl.c (ne_ssl_context_set_flag): New function. * src/ne_gnutls.c (ne_ssl_context_set_flag): New stub. * src/ne_session.h: Add NE_SESSFLAG_SSLv2 flag (defaults to on). * src/ne_session.c (ne_session_create) [NE_HAVE_SSL]: Set the NE_SESSFLAG_SSLv2 flag. (ne_set_session_flag) [NE_HAVE_SSL]: Call ne_ssl_context_set_flag. * test/ssl.c (simple_sslv2): Enable SSLv2 support. ------------------------------------------------------------------------ r943 | joe | 2006-02-25 16:21:45 +0000 (Sat, 25 Feb 2006) | 19 lines * src/ne_session.h (ne_set_session_flag): New enum. (ne_set_session_flag, ne_get_session_flag): New prototypes. (ne_set_persist): Removed prototype. * src/ne_session.c (ne_set_session_flag, ne_get_session_flag): New functions. (ne_set_persist): Removed function. * src/ne_private.h (ne_session): Replace no_persist field with flags array. * src/ne_request.c (add_fixed_headers, ne_end_request): Use flags array. (ne_begin_request): Remove redunant check for no_persist flag; send_request() will only return NE_RETRY if a persistent connection was reused. * test/session.c (flags): New test case. ------------------------------------------------------------------------ r942 | joe | 2006-02-25 15:02:25 +0000 (Sat, 25 Feb 2006) | 11 lines Forward-port the compression-vs-retry fix by using the new ne_unhook_* functions: * src/ne_compress.c (gz_pre_send): New function. (ne_decompress_reader): Don't initialize all context state here; register pre_send hook. (ne_decompress_destroy): Unregister hook; move function lower in module. * test/compress.c: retry_compress is no longer XFAIL. ------------------------------------------------------------------------ r941 | joe | 2006-02-25 14:47:18 +0000 (Sat, 25 Feb 2006) | 2 lines * src/ne_request.h: Clarify exactly what is unsafe. ------------------------------------------------------------------------ r940 | joe | 2006-02-25 14:45:09 +0000 (Sat, 25 Feb 2006) | 9 lines * src/ne_request.h: Make behaviour undefined when unregistering hooks from a corresponding hook implementation, except for the destroy_request hook. * src/ne_request.c (ne_request_destroy): Make safe against the hook list changing under foot. * test/request.c (hook_self_destroy): New test. ------------------------------------------------------------------------ r939 | joe | 2006-02-25 14:10:05 +0000 (Sat, 25 Feb 2006) | 3 lines * src/ne_request.c (send_request): Set error string to socket error if sending request header fails. ------------------------------------------------------------------------ r938 | joe | 2006-02-25 13:52:31 +0000 (Sat, 25 Feb 2006) | 7 lines * src/ne_request.c (hash_and_lower, read_response_headers): Use ne_tolower. * src/ne_string.h (NE_ASC2HEX): Use ne_tolower. * src/ne_md5.c: Don't include ctype.h. ------------------------------------------------------------------------ r937 | joe | 2006-02-25 13:43:13 +0000 (Sat, 25 Feb 2006) | 4 lines * src/ne_string.h (ne_tolower, ne_tolower_array): New macro, function. * src/ne_string.c (ne_tolower_array): New function. ------------------------------------------------------------------------ r936 | joe | 2006-02-25 13:21:30 +0000 (Sat, 25 Feb 2006) | 3 lines * src/ne_string.c (ascii_tolower, TOLOWER): Use array-based lowercase conversion. ------------------------------------------------------------------------ r931 | joe | 2006-02-21 17:29:00 +0000 (Tue, 21 Feb 2006) | 6 lines * src/ne_locks.c (lk_pre_send, ne_lock): Use ne_buffer_czappend for constant strings; use "\n" not EOL macro. * src/ne_props.c (set_body, ne_propfind_allprop, ne_propfind_named, ne_proppatch, ne_propfind_create, ne_propnames): Likewise. ------------------------------------------------------------------------ r930 | joe | 2006-02-21 17:18:05 +0000 (Tue, 21 Feb 2006) | 6 lines * src/ne_request.h: Clarify what may be in the Request-URI passed to a create_request hook. * BUGS: create_request hook URI handling has been well-defined for a while; bug was fixed. ------------------------------------------------------------------------ r929 | joe | 2006-02-20 22:48:45 +0000 (Mon, 20 Feb 2006) | 2 lines * src/ne_session.c (remove_hook): Don't leak the hook structure. ------------------------------------------------------------------------ r928 | joe | 2006-02-20 22:46:32 +0000 (Mon, 20 Feb 2006) | 2 lines * test/request.c (hooks): Improve hook coverage some more. ------------------------------------------------------------------------ r927 | joe | 2006-02-20 22:26:47 +0000 (Mon, 20 Feb 2006) | 9 lines * src/ne_request.h (ne_unhook_pre_send, ne_unhook_post_send, ne_unhook_destroy_request, ne_unhook_destroy_session): Add prototypes. * src/ne_session.c (remove_hook, ne_unhook_pre_send, ne_unhook_post_send, ne_unhook_destroy_request, ne_unhook_destroy_session): New functions. * test/request.c (hooks): New test case. ------------------------------------------------------------------------ r926 | joe | 2006-02-20 21:55:55 +0000 (Mon, 20 Feb 2006) | 7 lines * src/ne_session.c (add_hook, ne_hook_create_request, ne_hook_pre_send, ne_hook_post_send, ne_hook_destroy_request, ne_hook_destroy_session, ne_set_session_private): Moved here... * src/ne_request.c: ...from here. (ne_set_request_private): Inline add_hook. ------------------------------------------------------------------------ r925 | joe | 2006-02-20 21:42:38 +0000 (Mon, 20 Feb 2006) | 2 lines * test/socket.c (multi_init): Update for refcounting init/exit. ------------------------------------------------------------------------ r924 | joe | 2006-02-20 21:42:24 +0000 (Mon, 20 Feb 2006) | 3 lines * src/ne_openssl.c (ne__ssl_exit): Don't use debugging calls in ne_sock_exit; debug stream may have been closed. ------------------------------------------------------------------------ r923 | joe | 2006-02-18 09:17:41 +0000 (Sat, 18 Feb 2006) | 3 lines * src/ne_gnutls.c: Fix --enable-threadsafe-ssl build; include pthread.h and errno.h, fix cpp syntax error. ------------------------------------------------------------------------ r922 | joe | 2006-02-17 22:16:24 +0000 (Fri, 17 Feb 2006) | 2 lines * TODO: Strike out stuff which is either done or out-of-scope. ------------------------------------------------------------------------ r921 | joe | 2006-02-17 17:27:32 +0000 (Fri, 17 Feb 2006) | 11 lines * macros/neon.m4 (NEON_SSL): Add --enable-threadsafe-ssl flag which requests thread-safety for the SSL library using POSIX mutexes. * src/ne_openssl.c [HAVE_PTHREADS] (thread_id_neon, thread_lock_neon): New functions. (ne__ssl_init, ne__ssl_exit) [HAVE_PTHREADS]: Register/unregister thread-safety callbacks, if safe to do so. * src/ne_gnutls.c (ne__ssl_init, ne__ssl_exit): Register libgcrypt POSIX thread support. ------------------------------------------------------------------------ r920 | joe | 2006-02-17 17:07:40 +0000 (Fri, 17 Feb 2006) | 2 lines * src/ne_auth.c: Fix typo. ------------------------------------------------------------------------ r919 | joe | 2006-02-17 17:07:03 +0000 (Fri, 17 Feb 2006) | 10 lines * src/ne_privssl.h (ne__ssl_init, ne__ssl_exit): Add prototypes. * src/ne_socket.c (init_ssl): Removed. (ne_sock_init, ne_sock_init): Call ne__ssl_init, ne__ssl_exit to handle process-global init/exit of the SSL library. * src/ne_openssl.c (ne__ssl_init, ne__ssl_exit): New functions. * src/ne_gnutls.c (ne__ssl_init, ne__ssl_exit): New functions. ------------------------------------------------------------------------ r917 | joe | 2006-02-16 18:38:25 +0000 (Thu, 16 Feb 2006) | 3 lines * src/ne_socket.c, src/ne_socket.h (ne_sock_init, ne_sock_exit): Refcount to allow multiple calls per process. ------------------------------------------------------------------------ r916 | joe | 2006-02-16 09:37:40 +0000 (Thu, 16 Feb 2006) | 3 lines * test/common/tests.h (ONCMP): Show expected/unexpected string in failure message if other is NULL. ------------------------------------------------------------------------ r915 | joe | 2006-02-16 09:36:57 +0000 (Thu, 16 Feb 2006) | 2 lines * test/common/tests.c (TEST_DEBUG): Add NE_DBG_HTTPPLAIN. ------------------------------------------------------------------------ r913 | joe | 2006-02-15 21:00:39 +0000 (Wed, 15 Feb 2006) | 8 lines * test/auth.c (make_digest): Handle MD5-sess algorithm. (verify_digest_header): Verify that all expected fields are present, not that all present fields are as expected. (make_authinfo_header): Respect proxy parameter. (make_digest_header): New function. (serve_digest, test_digest): Respect proxy parameter. (digest): Factor out from digest_* functions. ------------------------------------------------------------------------ r912 | joe | 2006-02-15 20:57:28 +0000 (Wed, 15 Feb 2006) | 3 lines * src/ne_auth.c (digest_challenge): Give useful error messages for malformed challenges. ------------------------------------------------------------------------ r911 | joe | 2006-02-15 16:48:05 +0000 (Wed, 15 Feb 2006) | 2 lines * test/lock.c (fail_lockauth): Set lock token. ------------------------------------------------------------------------ r909 | joe | 2006-02-15 09:16:09 +0000 (Wed, 15 Feb 2006) | 13 lines * src/ne_auth.c: Remove unnecessary forward declaration of struct auth_protocol. (verify_digest_response): Reflow to give useful errors; drop conditional which was needed for qop=auth-int. * test/auth.c (make_digest): Factored out from check_digest. (check_digest): Use make_digest. (make_authinfo_header): New function. (serve_digest): Add Authentication-Info handling. (test_digest): Factored out from digest_rfc2617/digest_rfc2069. (digest_rfc2617, digest_rfc2069): Use test_digest. (digest_auth_info, digest_failures): New test cases. ------------------------------------------------------------------------ r897 | joe | 2006-02-14 12:17:49 +0000 (Tue, 14 Feb 2006) | 4 lines * src/ne_auth.c (struct auth_request): Remove unused response_body field and pointless will_handle field. (verify_digest_response, ah_pre_send): Remove will_handle flag. ------------------------------------------------------------------------ r896 | joe | 2006-02-14 12:10:01 +0000 (Tue, 14 Feb 2006) | 13 lines * src/ne_auth.c (struct auth_request): Move attempt field here from auth_session. (struct auth_protocol): Pass attempt counter to challenge callback. (get_credentials): Take attempt counter as parameter. (basic_challenge, digest_challenge): Pass through attempt counter to get_credentials accordingly. (gssapi_challenge): Only respect a Negotiate challenge if it is an initial challenge, with no input token, or a continuation, with an input token. (auth_challenge): Pass through attempt counter. (ah_create): Don't reset session->attempt. (ah_post_send): Pass and increment attempt counter here. ------------------------------------------------------------------------ r895 | joe | 2006-02-14 11:51:03 +0000 (Tue, 14 Feb 2006) | 3 lines * src/ne_auth.c: Clean up debugging output a little; no functional change. ------------------------------------------------------------------------ r890 | joe | 2006-02-12 22:24:03 +0000 (Sun, 12 Feb 2006) | 3 lines * test/auth.c (dup_header, check_digest, verify_digest_header, serve_digest, digest_rfc2617, digest_rfc2069): New functions. ------------------------------------------------------------------------ r889 | joe | 2006-02-12 12:05:14 +0000 (Sun, 12 Feb 2006) | 6 lines * src/ne_sspi.c, src/ne_sspi.h (ne_sspi_get_mechanism): Remove function. * src/ne_auth.c (request_sspi): Use protocol name rather than jumping through SSPI code. ------------------------------------------------------------------------ r888 | joe | 2006-02-12 10:14:42 +0000 (Sun, 12 Feb 2006) | 2 lines * doc/ref/auth.xml: Fix callback type name. ------------------------------------------------------------------------ r885 | joe | 2006-02-11 23:56:58 +0000 (Sat, 11 Feb 2006) | 2 lines * doc/ref/ssltrust.xml: Fix typo. ------------------------------------------------------------------------ r883 | joe | 2006-02-11 23:46:47 +0000 (Sat, 11 Feb 2006) | 2 lines * NEWS: Remove completed TODO list item. ------------------------------------------------------------------------ r882 | joe | 2006-02-11 17:03:16 +0000 (Sat, 11 Feb 2006) | 2 lines * src/ne_auth.c (free_auth): Free the handlers when the session is destroyed. ------------------------------------------------------------------------ r881 | joe | 2006-02-11 16:30:27 +0000 (Sat, 11 Feb 2006) | 3 lines * test/run.sh: Set MALLOC_PERTURB_ to enable glibc malloc randomization. ------------------------------------------------------------------------ r880 | joe | 2006-02-11 13:29:34 +0000 (Sat, 11 Feb 2006) | 20 lines Allow control over which auth protocols are used: * src/ne_auth.h (ne_add_server_auth, ne_add_proxy_auth): New prototypes. * src/ne_auth.c (struct auth_handler): New structure. (auth_challenge): Store a pointer to a handler. (auth_session): Store a list of handlers. (auth_protocol): Make id type 'unsigned'. (get_credentials): Take challenge argument. (basic_challenge, digest): Pass challenge structure to get_credentials. (auth_register): Take protocol mask; allow multiple calls per session. Append a handler to list registered for the session. Only initialize GSSAPI fields if Negotiate is allowed. (auth_register_default): New function. (auth_challenge): Iterate through the session's handler list for each challenge; store a pointer to the handler in the challenge. (ne_set_server_auth, ne_set_proxy_auth): Use auth_register_default. (ne_add_server_auth, ne_add_proxy_auth): New functions. ------------------------------------------------------------------------ r879 | joe | 2006-02-11 11:37:32 +0000 (Sat, 11 Feb 2006) | 18 lines Refactor auth protocol support as first step to exposing protocols in the API: * src/ne_auth.c (struct auth_protocol): New structure; replaces auth_scheme enum. (struct auth_session, struct auth_challenge): Store pointer to protocol structure in place of scheme value. (request_basic, request_gssapi, verify_negotiate_response, gssapi_challenge, sspi_challenge): Adjust to use generic callback prototypes; don't set ->scheme, use ->protocol instead. (insert_challenge): New function. (auth_challenge): Adjust to construct a list of challenges, kept sorted by protocol strength field. Walk the list once until a protocol challenge callback succeeds. (ah_pre_send): Adjust to use the protocol response callback. (ah_post_send): Adjust to use the protocol verify callback. (protocols): Add global protocol definitions array. ------------------------------------------------------------------------ r878 | joe | 2006-02-11 11:15:32 +0000 (Sat, 11 Feb 2006) | 2 lines * src/ne_auth.h: Move hint on using attempt as return value. ------------------------------------------------------------------------ r869 | joe | 2006-02-08 23:04:03 +0000 (Wed, 08 Feb 2006) | 12 lines Patch from Stefan Küng to fix endless authentication loop if the authentication fails: * src/ne_sspi.c, src/ne_sspi.h: New public function to tell the lib that an authentication was successful. Return an error if the authentication is restarted without a successful authentication before. * src/ne_auth.c: Call the new public function to tell the library about a successful authentication. ------------------------------------------------------------------------ r842 | joe | 2006-01-11 12:10:50 +0000 (Wed, 11 Jan 2006) | 3 lines * test/uri-tests.c (parse): Add some more test cases and make failure messages clearer. ------------------------------------------------------------------------ r840 | joe | 2006-01-10 23:19:39 +0000 (Tue, 10 Jan 2006) | 2 lines * src/ne_auth.c (ah_post_send): Fix non-SSPI build. ------------------------------------------------------------------------ r839 | joe | 2006-01-10 23:19:01 +0000 (Tue, 10 Jan 2006) | 6 lines Apply other half of Stefan's patch which got lost in the wash somewhere: * src/ne_sspi.c: Return an error if the authentication is restarted without a successful authentication before. ------------------------------------------------------------------------ r838 | joe | 2006-01-10 22:59:47 +0000 (Tue, 10 Jan 2006) | 7 lines Fix build on some AIX systems: * src/ne_request.c: Include sys/limits.h if available. Define LONG_LONG_MAX to LONGLONG_MAX if necessary. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Check for sys/limits.h. ------------------------------------------------------------------------ r837 | joe | 2006-01-10 22:51:39 +0000 (Tue, 10 Jan 2006) | 12 lines Patch from Stefan Küng to fix endless authentication loop if the authentication fails: * src/ne_sspi.c, src/ne_sspi.h: New public function to tell the lib that an authentication was successful. Return an error if the authentication is restarted without a successful authentication before. * src/ne_auth.c: Call the new public function to tell the library about a successful authentication. ------------------------------------------------------------------------ r836 | joe | 2006-01-10 13:50:45 +0000 (Tue, 10 Jan 2006) | 8 lines Fix ne_lock_discover() regression: * src/ne_locks.c (struct discover_ctx): Add reference to the PROPFIND handler. (end_element_ldisc): Use it to retrieve current lock. (ne_lock_discover): Store pointer to the PROPFIND handler in the context; pass the context as userdata to the XML parser callbacks. ------------------------------------------------------------------------ r835 | joe | 2006-01-10 13:39:59 +0000 (Tue, 10 Jan 2006) | 2 lines * src/ne_uri.c (CMPWITH): M-x backslash-region. ------------------------------------------------------------------------ r834 | joe | 2006-01-10 13:27:52 +0000 (Tue, 10 Jan 2006) | 2 lines * src/ne_uri.h: Minor comment tweaks. ------------------------------------------------------------------------ r833 | joe | 2006-01-09 14:39:05 +0000 (Mon, 09 Jan 2006) | 2 lines Revert r832 per request from Stefan Küng. ------------------------------------------------------------------------ r832 | joe | 2006-01-07 17:36:42 +0000 (Sat, 07 Jan 2006) | 5 lines Patch from Stefan Küng: * src/ne_sspi.c: free allocated memory before returning with an error. ------------------------------------------------------------------------ r831 | joe | 2006-01-06 15:36:46 +0000 (Fri, 06 Jan 2006) | 4 lines * src/ne_gnutls.c, src/ne_openssl.c, src/ne_basic.c, src/ne_compress.c, src/ne_uri.c, src/ne_auth.c, src/ne_locks.c: Use ne_strcasecmp in favour of locale-dependent strcasecmp throughout. ------------------------------------------------------------------------ r830 | joe | 2006-01-06 14:54:32 +0000 (Fri, 06 Jan 2006) | 4 lines * src/ne_locks.c (CMPWITH): Simplify to reduce number of branches. * test/uri-tests.c (cmp): Test every comparison for reflexivity; ------------------------------------------------------------------------ r829 | joe | 2006-01-06 14:37:12 +0000 (Fri, 06 Jan 2006) | 8 lines * src/ne_uri.c (CMPWITH): New macro. (CMP, CASECMP): Implement using it. Use ne_strcasecmp. (ne_uri_cmp): Fix handling of empty paths; compare query, fragment and userinfo. * test/uri-tests.c (cmp): Rewrite and improve coverage. (cmp_differ): Remove function. ------------------------------------------------------------------------ r828 | joe | 2006-01-06 14:05:40 +0000 (Fri, 06 Jan 2006) | 2 lines * src/ne_i18n.h: Expand on use of ne_i18n_init a little. ------------------------------------------------------------------------ r827 | joe | 2006-01-06 12:26:46 +0000 (Fri, 06 Jan 2006) | 9 lines Add locale-independent implementations of strcasecmp/strncasecmp, from glibc: * src/ne_string.h (ne_strcasecmp, ne_strncasecmp): Add prototypes. * src/ne_string.c (ne_strcasecmp, ne_strncasecmp): New functions. * test/string-tests.c (casecmp, casencmp): Add test cases. ------------------------------------------------------------------------ r825 | joe | 2006-01-02 11:43:19 +0000 (Mon, 02 Jan 2006) | 40 lines * src/ne_207.h (ne_207_create): Take a base URI argument. (ne_207_start_response): Give parsed URI structure rather than raw string. * src/ne_207.c (struct ne_207_parser_s): Add URI base member. (end_element): Parse and resolve the href URI; pass resolved URI to start_response callback. (ne_207_create): Take a copy of given base URI. (ne_207_destroy): ... and free it. (start_response): Unparse the given URI. (ne_simple_request): Mock up a base URI. * src/ne_props.h (ne_props_result, ne_props_create_complex): Take URI structure rather than raw string. * src/ne_props.c (ne_prop_result_set_s): Store URI structure. (start_response): Take a copy of passed-in URI in propset; pass it back to creator callback. (free_propset): Free stored URI. (end_response): Pass stored URI to results callback. (ne_propfind_create): Create base URI to pass to ne_207_create. * src/ne_locks.h (ne_lock_result): Take a URI structure rather than raw string. * src/ne_locks.c (struct discover_ctx): Remove session member. (discover_results): Use given URI structure throughout. (ld_create): Copy URI structure directly to lock. (ne_lock_discover): No need to take a reference to the session. * src/Makefile.in: Update dependencies. * test/props.c (dummy_results, simple_results, tos_startresp): Adjust to take URI structure. (run_207_response): Initialize base URI to pass to ne_207_create. (pfind_simple): Only use URI path in result strings. * test/lock.c (discover_result, dummy_discover): Adjust to take URI structure. ------------------------------------------------------------------------ r824 | joe | 2006-01-02 10:28:10 +0000 (Mon, 02 Jan 2006) | 2 lines * src/ne_xmlreq.h: Fix typo in comment. ------------------------------------------------------------------------ r823 | joe | 2006-01-01 23:42:03 +0000 (Sun, 01 Jan 2006) | 4 lines * src/ne_uri.h, src/ne_uri.c (ne_uri_resolve): Return target pointer. * test/uri-tests.c (resolve): Test for such. ------------------------------------------------------------------------ r822 | joe | 2006-01-01 23:17:51 +0000 (Sun, 01 Jan 2006) | 3 lines * test/uri-tests.c (parse): Test for the slightly odd triple-slash case. ------------------------------------------------------------------------ r821 | joe | 2006-01-01 23:02:41 +0000 (Sun, 01 Jan 2006) | 3 lines * test/uri-tests.c (parse): Explicitly test for a URI with no path component. ------------------------------------------------------------------------ r820 | joe | 2006-01-01 22:37:50 +0000 (Sun, 01 Jan 2006) | 3 lines * src/ne_locks.c (ne_lock_using_parent): Zero-initalize lock structure. ------------------------------------------------------------------------ r819 | joe | 2006-01-01 22:35:38 +0000 (Sun, 01 Jan 2006) | 6 lines Fixes found by --enable-memleak build: * src/ne_uri.c (ne_uri_resolve): Fix double assignment of query component. (ne_uri_free): Free the query and fragment fields. ------------------------------------------------------------------------ r818 | joe | 2006-01-01 22:29:45 +0000 (Sun, 01 Jan 2006) | 3 lines * src/ne_uri.c (remove_dot_segments): malloc the correct size of output buffer rather than strdup'ing the input buffer. ------------------------------------------------------------------------ r817 | joe | 2006-01-01 22:22:07 +0000 (Sun, 01 Jan 2006) | 2 lines * src/ne_locks.c (ne_lock_copy): Use ne_uri_copy. ------------------------------------------------------------------------ r816 | joe | 2006-01-01 21:20:33 +0000 (Sun, 01 Jan 2006) | 6 lines * src/ne_uri.h (ne_uri_copy): Add prototype. * src/ne_uri.c (ne_uri_copy): New function. * test/uri-tests.c (copy): New test case. ------------------------------------------------------------------------ r815 | joe | 2006-01-01 21:19:25 +0000 (Sun, 01 Jan 2006) | 5 lines * src/ne_uri.c (ne_uri_unparse): Handle port correctly if scheme is undefined. * test/uri-tests.c (unparse): Add test case. ------------------------------------------------------------------------ r814 | joe | 2006-01-01 19:02:23 +0000 (Sun, 01 Jan 2006) | 2 lines * src/ne_uri.c (ne_uri_unparse): Fix missing NULL list terminator. ------------------------------------------------------------------------ r813 | joe | 2006-01-01 18:58:00 +0000 (Sun, 01 Jan 2006) | 7 lines * src/ne_uri.c (remove_dot_segments): Fix case 2.A. (copy_authority): Fix to duplicate userinfo if defined. (ne_uri_resolve): Fix to only copy scheme if defined. (ne_uri_unparse): Fix handling of URIs with authority but no scheme. * test/uri-tests.c (unparse, resolve): Add test cases for above. ------------------------------------------------------------------------ r812 | joe | 2006-01-01 17:22:11 +0000 (Sun, 01 Jan 2006) | 7 lines * src/ne_uri.h (ne_uri_resolve): Add prototype. * src/ne_uri.c (copy_authority, merge_paths, remove_dot_segments, ne_uri_resolve): New functions. * test/uri-tests.c (resolve): Add test cases. ------------------------------------------------------------------------ r811 | joe | 2006-01-01 17:10:57 +0000 (Sun, 01 Jan 2006) | 7 lines * src/ne_uri.c (ne_uri_parse): Empty string is a valid URI-reference, so allow it. (ne_uri_unparse): Handle URIs with undefined authority. * test/uri-tests.c (parse): Add test case for former. (unparse): Add test case for latter. ------------------------------------------------------------------------ r810 | joe | 2006-01-01 14:58:37 +0000 (Sun, 01 Jan 2006) | 2 lines * src/Makefile.in (neonreq): Depend on ne_uri.h. ------------------------------------------------------------------------ r809 | joe | 2006-01-01 14:57:28 +0000 (Sun, 01 Jan 2006) | 3 lines * test/uri-tests.c (escapes, failparse, unparse): Improve test coverage (100% of branches taken). ------------------------------------------------------------------------ r808 | joe | 2006-01-01 14:43:11 +0000 (Sun, 01 Jan 2006) | 15 lines * src/ne_uri.h (ne_uri): Rename authinfo field to userinfo. Add query and fragment fields. * src/ne_locks.c (ne_lock_using_parent): Adjust accordingly. * src/ne_uri.c (ne_uri_parse): Adjust for userinfo/authinfo rename. Parse fragment and query; parse path component strictly. (ne_uri_free): Adjust for authinfo rename. (ne_uri_unparse): Adjust for authinfo rename; handle query and fragment. * test/uri-tests.c (parse, unparse): Add tests for query/fragment handling. (failparse): Add some cases with invalid path segments. ------------------------------------------------------------------------ r807 | joe | 2006-01-01 13:37:56 +0000 (Sun, 01 Jan 2006) | 11 lines * src/ne_uri.h (ne_uri_parse): Redefine to take a URI-reference as input. * src/ne_uri.c (uri_chars): Redefine array giving more detailed character classes. (ne_uri_parse): Rewrite to properly parse a URI-reference. (ne_path_escape): Do respect the authinfo field. * test/uri-tests.c (just_hostname, just_path): Remove tests. (parse): Remove some non-URI-reference tests; add some more. ------------------------------------------------------------------------ r806 | joe | 2005-12-31 18:22:35 +0000 (Sat, 31 Dec 2005) | 2 lines * test/session.c (fill_uri): Use ONCMP. ------------------------------------------------------------------------ r775 | joe | 2005-11-29 20:58:08 +0000 (Tue, 29 Nov 2005) | 3 lines * src/ne_socket.c: Revert debugging code accidentally committed in r774. ------------------------------------------------------------------------ r774 | joe | 2005-11-29 20:54:50 +0000 (Tue, 29 Nov 2005) | 10 lines * macros/neon.m4 (NEON_SSL): Check for gnutls_session_get_data2. * src/ne_privssl.h (ne_ssl_context_s) [HAVE_GNUTLS && HAVE_GNUTLS_SESSION_GET_DATA2]: Just store a single gnutls_datum for the cache.client field. * src/ne_socket.c [HAVE_GNUTLS] (ne_sock_connect_ssl): Use gnutls_session_get_data2 if available; otherwise do check for errors from _get_data. ------------------------------------------------------------------------ r773 | joe | 2005-11-29 17:46:26 +0000 (Tue, 29 Nov 2005) | 3 lines * src/ne_gnutls.c (ne__negotiate_ssl): Skip verification of the cert if it's the same as last time; fixes the "cache_verify" test. ------------------------------------------------------------------------ r772 | joe | 2005-11-29 16:55:16 +0000 (Tue, 29 Nov 2005) | 9 lines * macros/neon.m4 (NEON_SSL): Add --with-ca-bundle flag to allow an (alternative) SSL CA bundle to be configured/used. * src/ne_openssl.c (ne_ssl_trust_default_ca): Honour NE_SSL_CA_BUNDLE if defined, in preference to use of OpenSSL-default CA bundle. * src/ne_gnutls.c (ne_ssl_trust_default_ca): Implement using NE_SSL_CA_BUNDLE. ------------------------------------------------------------------------ r771 | joe | 2005-11-29 16:07:48 +0000 (Tue, 29 Nov 2005) | 3 lines * macros/neon.m4 (NEON_SSL): Allow enabling GNUTLS support since it's mostly complete now. ------------------------------------------------------------------------ r770 | joe | 2005-11-29 16:04:01 +0000 (Tue, 29 Nov 2005) | 4 lines * src/ne_socket.c (ne_sock_sessid): Fail for non-SSL sockets. * test/socket.c (ssl_session_id): Fix for non-SSL build. ------------------------------------------------------------------------ r769 | joe | 2005-11-29 15:13:02 +0000 (Tue, 29 Nov 2005) | 4 lines * src/ne_socket.c (ne_sock_sessid): Fail for non-SSL sockets. * test/socket.c (ssl_session_id): Fix for non-SSL build. ------------------------------------------------------------------------ r768 | joe | 2005-11-29 15:09:06 +0000 (Tue, 29 Nov 2005) | 6 lines * src/ne_socket.c (ne_sock_sessid): New function. * src/ne_socket.h (ne_sock_sessid): Add prototype. * test/socket.c (ssl_session_id): New test. ------------------------------------------------------------------------ r767 | joe | 2005-11-29 13:17:49 +0000 (Tue, 29 Nov 2005) | 12 lines Implement session caching for GNUTLS: * src/ne_socket.c (copy_datum, store_sess, match_datum, retrieve_sess, remove_sess): New functions. (ne_sock_accept_ssl) [HAVE_GNUTLS]: Implement dummy session cache. (ne_sock_connect_ssl) [HAVE_GNUTLS]: Cache client session. * src/ne_gnutls.c (ne_ssl_context_destroy): Free session cache. * src/ne_privssl.h [HAVE_GNUTLS] (struct ne_ssl_context_s): Add session cache fields. ------------------------------------------------------------------------ r766 | joe | 2005-11-28 21:54:09 +0000 (Mon, 28 Nov 2005) | 2 lines * src/ne_207.h, src/ne_dates.h: Fix multiple-inclusion-safety symbols. ------------------------------------------------------------------------ r765 | joe | 2005-11-28 13:02:36 +0000 (Mon, 28 Nov 2005) | 2 lines * src/ne_gnutls.c (make_peers_chain): Don't leak if import fails. ------------------------------------------------------------------------ r764 | joe | 2005-11-28 11:47:06 +0000 (Mon, 28 Nov 2005) | 3 lines * src/ne_socket.c (error_gnutls): Distinguish between generic errors and receipt of an SSL alert. ------------------------------------------------------------------------ r763 | joe | 2005-11-28 11:44:41 +0000 (Mon, 28 Nov 2005) | 4 lines * src/ne_socket.c (error_gnutls): Improve error handling; always treat GNUTLS_E_UNEXPECTED_PACKET_LENGTH as a truncation, socket errors as a reset. ------------------------------------------------------------------------ r761 | joe | 2005-11-28 10:59:08 +0000 (Mon, 28 Nov 2005) | 3 lines * test/ssl.c (wildcard_init): Update error message now most hostname commands should work OK. ------------------------------------------------------------------------ r760 | joe | 2005-11-28 08:53:45 +0000 (Mon, 28 Nov 2005) | 7 lines * test/makekeys.sh: Create a PKCS#12 client cert with embedded CA cert. * test/Makefile.in (clean): Clean all PKCS#12 certs. * test/ssl.c (load_client_cert): Load the new cert. ------------------------------------------------------------------------ r759 | joe | 2005-11-28 08:36:20 +0000 (Mon, 28 Nov 2005) | 3 lines * src/ne_openssl.c (ne_ssl_clicert_decrypt): Check that private key/cert match. ------------------------------------------------------------------------ r755 | joe | 2005-11-24 22:37:49 +0000 (Thu, 24 Nov 2005) | 10 lines * src/ne_request.c (open_connection, do_connect): Take session pointer as argument not request. * src/ne_openssl.c (ne__negotiate_ssl): Take session pointer as argument not request. * src/ne_gnutls.c (ne__negotiate_ssl): Likewise. * src/ne_private.h (ne__negotiate_ssl): Update prototype. ------------------------------------------------------------------------ r754 | joe | 2005-11-23 15:20:37 +0000 (Wed, 23 Nov 2005) | 2 lines * test/makekeys.sh: Fix new domain extraction for multi-part domains. ------------------------------------------------------------------------ r750 | joe | 2005-10-29 14:41:18 +0100 (Sat, 29 Oct 2005) | 2 lines * src/ne_alloc.h: Remove NE_FREE macro. ------------------------------------------------------------------------ r749 | joe | 2005-10-29 14:40:09 +0100 (Sat, 29 Oct 2005) | 4 lines * src/ne_props.c (free_propset): Eliminate use of NE_FREE macro. * src/ne_redirect.c (create): Likewise. ------------------------------------------------------------------------ r748 | joe | 2005-10-29 14:34:59 +0100 (Sat, 29 Oct 2005) | 2 lines * src/ne_auth.c (clean_session): Eliminate use of NE_FREE macro. ------------------------------------------------------------------------ r747 | joe | 2005-10-29 14:31:22 +0100 (Sat, 29 Oct 2005) | 3 lines * src/ne_207.c (end_element, start_response, ne_simple_request): Eliminate use of NE_FREE macro. ------------------------------------------------------------------------ r746 | joe | 2005-10-29 00:32:50 +0100 (Sat, 29 Oct 2005) | 6 lines Fix type mismatch with OpenSSL >= 0.9.8. * src/ne_openssl.c (ne_d2i_uchar): Add typedef. (ne_ssl_cert_import): Use ne_d2i_uchar as type of second argument to d2i_x509. ------------------------------------------------------------------------ r736 | joe | 2005-10-13 20:01:35 +0100 (Thu, 13 Oct 2005) | 3 lines * test/makekeys.sh: Begin octal escapes with \0; use sed to munge hostname. (based on patch by Mikhail Teterin) ------------------------------------------------------------------------ r735 | joe | 2005-10-13 08:18:17 +0100 (Thu, 13 Oct 2005) | 9 lines GSSAPI fixes for non-MIT Kerberos implementations, from Mikhail Teterin: * src/ne_auth.c (clean_session): Pass pointer to gssctx to gss_delete_sec_context. Don't release stored gssmech. (continue_negotiate): Pass sess->gssmech directly to gss_init_sec_context. (free_auth): Pass pointer to stored name to gss_release_name. ------------------------------------------------------------------------ r733 | joe | 2005-10-09 14:31:00 +0100 (Sun, 09 Oct 2005) | 3 lines * src/: In all files, s/BEGIN_NEON_DECLS/NE_BEGIN_DECLS/g and s/END_NEON_DECLS/NE_END_DECLS/g. ------------------------------------------------------------------------ r732 | joe | 2005-10-09 14:28:03 +0100 (Sun, 09 Oct 2005) | 2 lines * src/ne_i18n.h: Use {BEGIN,END}_NEON_DECLS. ------------------------------------------------------------------------ r730 | joe | 2005-10-09 09:16:39 +0100 (Sun, 09 Oct 2005) | 3 lines * src/ne_private.h (struct ne_session_s): Use 512-byte buffer for error string. ------------------------------------------------------------------------ r729 | joe | 2005-10-09 09:15:49 +0100 (Sun, 09 Oct 2005) | 3 lines * src/ne_request.c [!NE_LFS]: Define NE_OFFT_MAX correctly for platforms with sizeof(off_t) == sizeof(long long). ------------------------------------------------------------------------ r726 | joe | 2005-10-06 09:08:36 +0100 (Thu, 06 Oct 2005) | 10 lines * src/ne_defs.h (NE_BUFSIZ): Define. * src/ne_request.c (struct ne_request_s): Use NE_BUFSIZ for respbuf size. (send_request_body): Use NE_BUFSIZ for buffer. (ne_print_request_header): Use NE_BUFSIZ for stack buffer. * src/ne_compress.c (struct ne_decompress_s): Use NE_BUFSIZ for outbuf size. ------------------------------------------------------------------------ r722 | joe | 2005-09-22 02:02:12 +0100 (Thu, 22 Sep 2005) | 3 lines * src/ne_xml.c [HAVE_EXPAT]: Fix NEED_BOM_HANDLING for the !defined(XML_MAJOR_VERSION) case; patch by D.J. Heap. ------------------------------------------------------------------------ r721 | joe | 2005-09-22 01:59:37 +0100 (Thu, 22 Sep 2005) | 2 lines * config.hw.in (in_addr_t) [!USE_GETADDRINFO]: Define to unsigned int. ------------------------------------------------------------------------ r719 | joe | 2005-09-19 20:36:57 +0100 (Mon, 19 Sep 2005) | 2 lines * doc/ref/reqopts.xml: Fix parameter type. ------------------------------------------------------------------------ r718 | joe | 2005-09-19 10:17:43 +0100 (Mon, 19 Sep 2005) | 2 lines * doc/ref/iaddr.xml: Fix function name. ------------------------------------------------------------------------ r716 | joe | 2005-09-19 10:14:53 +0100 (Mon, 19 Sep 2005) | 2 lines * src/ne_request.h (ne_get_response_header): Fix docco. ------------------------------------------------------------------------ r715 | joe | 2005-09-19 10:14:23 +0100 (Mon, 19 Sep 2005) | 2 lines * doc/ref/resphdr.xml: Fix typo in element name. ------------------------------------------------------------------------ r713 | joe | 2005-09-17 18:07:53 +0100 (Sat, 17 Sep 2005) | 3 lines * src/ne_gnutls.c (provide_client_cert): Remove unused variable. (ne_ssl_cert_write, ne_ssl_cert_read): Fix type of length variables. ------------------------------------------------------------------------ r712 | joe | 2005-09-17 14:55:17 +0100 (Sat, 17 Sep 2005) | 4 lines * src/ne_gnutls.c (ne_ssl_context_create): Zero-initialize allocated structure. (provide_client_cert): Fail if no ne_session * pointer is registered with the socket. ------------------------------------------------------------------------ r711 | joe | 2005-09-17 14:44:38 +0100 (Sat, 17 Sep 2005) | 2 lines * src/ne_gnutls.c (check_identity): Handle iPAddress subjectAltName. ------------------------------------------------------------------------ r710 | joe | 2005-09-17 13:35:43 +0100 (Sat, 17 Sep 2005) | 6 lines Hook up basic client cert provision; based on patch by Aleix Conchillo Flaque: * src/ne_gnutls.c (provide_client_cert): New function. (ne_ssl_context_create): Install client cert provider callback. ------------------------------------------------------------------------ r709 | joe | 2005-09-17 13:26:41 +0100 (Sat, 17 Sep 2005) | 9 lines * src/ne_privssl.h (struct ne_ssl_context_s) [HAVE_GNUTLS]: Add verify field. * src/ne_socket.c (ne_sock_accept_ssl): If ctx->verify is set, verify peer certificate. * src/ne_gnutls.c (ne_ssl_context_set_verify): Set ctx->verify. Comment on lack of handling of ca_names argument. ------------------------------------------------------------------------ r708 | joe | 2005-09-17 12:38:32 +0100 (Sat, 17 Sep 2005) | 3 lines * src/ne_gnutls.c (x509_crt_copy): Fix check for gnutls_x509_crt_init return value. ------------------------------------------------------------------------ r707 | joe | 2005-09-17 12:37:26 +0100 (Sat, 17 Sep 2005) | 4 lines * src/ne_gnutls.c (ne_ssl_readable_dname): Switch to new implementation since fixed GNUTLS is required. (ne_ssl_dname_cmp): Implement. ------------------------------------------------------------------------ r706 | joe | 2005-09-17 12:05:51 +0100 (Sat, 17 Sep 2005) | 2 lines * po/: make update-po. ------------------------------------------------------------------------ r705 | joe | 2005-09-17 12:05:21 +0100 (Sat, 17 Sep 2005) | 3 lines * Makefile.in (XGETTEXT_OPTS): Explicitly mark functions taking format strings. (update-po): Pass --check-format to msgfmt. ------------------------------------------------------------------------ r704 | joe | 2005-09-17 12:02:37 +0100 (Sat, 17 Sep 2005) | 3 lines * src/ne_request.c (body_fd_send): Avoid using macro in string passed to gettext. ------------------------------------------------------------------------ r698 | joe | 2005-09-14 22:11:32 +0100 (Wed, 14 Sep 2005) | 4 lines * doc/ref/resphdr.xml: New file; document response header handling. * doc/manual.xml: Reference it. ------------------------------------------------------------------------ r697 | joe | 2005-09-14 21:53:41 +0100 (Wed, 14 Sep 2005) | 3 lines * Makefile.in (doc-status): Add hacky target to see what is undocumented... "for maintainer's use only". ------------------------------------------------------------------------ r696 | joe | 2005-09-14 21:47:45 +0100 (Wed, 14 Sep 2005) | 6 lines * doc/ref/reqopts.xml: Document ne_set_request_expect100. * doc/ref/opts.xml: Remove ne_set_expect100 documentation. * doc/manual.xml: Pull in reqopts.xml. ------------------------------------------------------------------------ r695 | joe | 2005-09-14 21:40:44 +0100 (Wed, 14 Sep 2005) | 2 lines * doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API.* doc/ref/opts.xml: Update for neon 0.25 API. ------------------------------------------------------------------------ r692 | joe | 2005-08-29 17:31:34 +0100 (Mon, 29 Aug 2005) | 3 lines * configure.in, po/it.po: Remove translation which looks too sitecopy-specific. ------------------------------------------------------------------------ r691 | joe | 2005-08-29 17:29:05 +0100 (Mon, 29 Aug 2005) | 10 lines * src/ne_i18n.h (ne_i18n_init): Take an encoding parameter. * src/ne_i18n.c (ne_i18n_init) [HAVE_BIND_TEXTDOMAIN_CODESET]: Call bind_textdomain_codeset if encoding is specified. * macros/neon.m4 (NEON_I18N): Fix to enable NLS by default. Check for bind_textdomain_codeset. * test/common/tests.c (main): Pass NULL to ne_i18n_init. ------------------------------------------------------------------------ r680 | joe | 2005-08-19 10:24:20 +0100 (Fri, 19 Aug 2005) | 32 lines Implement support for internationalization of error message: * src/Makefile.in (NEON_BASEOBJS): Build ne_i18n.o. * src/ne_i18n.c: Include config.h, ne_i18n.h. (ne_i18n_init): Renamed from neon_i18n_init. * src/ne_i18n.h: Remove library-private definition of '_' and 'N_' macros. * src/ne_internal.h: New header; add definitions of _ and N_. * src/*.c: Update all sources to include ne_internal.h instead of ne_i18n.h. * po/: New directory. Add message catalog template and translated message catalogs extracted from sitecopy. * macros/neon-test.m4: Check for setlocale and locale.h. * test/common/tests.c: Include locale.h, ne_i18n.h. (main): Call setlocale and ne_i18n_init. * test/run.sh: By default disable i18n to allow checks for English error messages to succeed. * .release.sh: Compile the gmo files here. * macros/neon.m4 (NEON_I18N): Add macro. * configure.in: Use NEON_I18N. Define ALL_LINGUAS. ------------------------------------------------------------------------ r679 | joe | 2005-08-19 08:24:32 +0100 (Fri, 19 Aug 2005) | 3 lines * src/ne_socket.c (INADDR_NONE): Define using in_addr_t if system is missing the definition. ------------------------------------------------------------------------ r678 | joe | 2005-08-19 08:19:45 +0100 (Fri, 19 Aug 2005) | 7 lines * src/ne_socket.c (ne_addr_resolve) [!USE_GETADDRINFO]: Use in_addr_t not unsigned long for address; fix for LP64 platforms - patch by Matthew Sanderson. * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Add check for in_addr_t. Fix check for h_errno declaration. ------------------------------------------------------------------------ r671 | joe | 2005-08-14 18:20:23 +0100 (Sun, 14 Aug 2005) | 5 lines * src/ne_locks.c (ne_lock, ne_unlock): Don't lose the NE_AUTH etc return code for non-2xx responses. * test/lock.c (fail_lockauth, no_creds): Add test case. ------------------------------------------------------------------------ r657 | joe | 2005-07-06 12:08:21 +0100 (Wed, 06 Jul 2005) | 2 lines * src/ne_redirect.c (post_send): Code cleanup. ------------------------------------------------------------------------ r656 | joe | 2005-07-02 12:20:11 +0100 (Sat, 02 Jul 2005) | 2 lines Add Jiang. ------------------------------------------------------------------------ r655 | joe | 2005-07-02 12:19:44 +0100 (Sat, 02 Jul 2005) | 2 lines * macros/neon.m4 (NE_MACOSX): Disable poll on Darwin. ------------------------------------------------------------------------ r654 | joe | 2005-07-02 12:18:37 +0100 (Sat, 02 Jul 2005) | 2 lines * test/Makefile.in (VALGRIND): Update to work with modern valgrind. ------------------------------------------------------------------------ r651 | joe | 2005-06-30 13:17:33 +0100 (Thu, 30 Jun 2005) | 2 lines * configure.in: Disable tests-install mode by default. ------------------------------------------------------------------------ r650 | joe | 2005-06-30 13:02:29 +0100 (Thu, 30 Jun 2005) | 2 lines * src/ne_xml.c: Omit BOM handling for recent releases of libxml2. ------------------------------------------------------------------------ r648 | joe | 2005-06-29 09:54:11 +0100 (Wed, 29 Jun 2005) | 12 lines * Makefile.in (install-tests): New target. * configure.in: Add --enable-install-tests to support test suite installation; only add -no-install to TEST_LDFLAGS if not given. * test/Makefile.in (install, random.txt): New targets. (LINK): Use TEST_LDFLAGS. (ZLIB_HELPERS): Add random.txt. * test/compress.c (init): Use random.txt in pwd rather than trying to find NEWS from the srcdir. ------------------------------------------------------------------------ r636 | joe | 2005-06-22 09:21:48 +0100 (Wed, 22 Jun 2005) | 17 lines Merge r627, r629, r631 from 0.25.x branch: * src/ne_auth.c (ah_post_send): Print auth_hdr safely. Remove unused SAFELY macro. * src/ne_compress.c (process_footer): Don't invoke reader callback with len=0 here as well when end-of-response is really reached. (do_inflate): Do pass on the reader callback return value. * test/compress.c (reader): Catch multiple invocations with len=0. (retry_accept): Reset the reader state. (reader_abort, compress_abort): New functions. * src/ne_xml.c (end_element): Use NE_DBG_XML debug channel for consistency. ------------------------------------------------------------------------ r635 | joe | 2005-06-22 09:14:15 +0100 (Wed, 22 Jun 2005) | 2 lines * config.hw.in: Really fix the Win32 build. ------------------------------------------------------------------------ r624 | joe | 2005-06-01 10:13:16 +0100 (Wed, 01 Jun 2005) | 3 lines * src/ne_openssl.c (ne__negotiate_ssl): Replace the cached session with the new one if they differ; based on patch by Robert Eiglmaier. ------------------------------------------------------------------------ r623 | joe | 2005-06-01 10:10:12 +0100 (Wed, 01 Jun 2005) | 5 lines * src/ne_basic.c (ne_get_content_type): Ensure that ->charset is NULL on exit (Johannes Schneider). * test/basic.c (content_type): Test that all fields are set. ------------------------------------------------------------------------ r622 | joe | 2005-05-20 01:56:31 +0100 (Fri, 20 May 2005) | 3 lines * src/ne_xml.c (start_element): Use NE_DBG_XML debug constant. (ne_xml_parse): Use NE_DBG_XMLPARSE debug constant. ------------------------------------------------------------------------ r621 | joe | 2005-05-20 01:44:36 +0100 (Fri, 20 May 2005) | 2 lines * src/ne_xml.c (char_data): Tidy up debug message. ------------------------------------------------------------------------ r619 | joe | 2005-05-19 22:06:55 +0100 (Thu, 19 May 2005) | 2 lines Updates. ------------------------------------------------------------------------ r618 | joe | 2005-05-19 22:04:27 +0100 (Thu, 19 May 2005) | 3 lines * src/ne_request.h (ne_hook_post_send): Clarify when the post_send hook runs. ------------------------------------------------------------------------ r616 | joe | 2005-05-14 12:35:50 +0100 (Sat, 14 May 2005) | 2 lines Credit Vladimir. ------------------------------------------------------------------------ r615 | joe | 2005-05-14 12:35:22 +0100 (Sat, 14 May 2005) | 2 lines * src/ne_auth.c: Fix Windows SSPI build. ------------------------------------------------------------------------ r614 | joe | 2005-05-12 15:24:53 +0100 (Thu, 12 May 2005) | 3 lines * INSTALL.win32: Update to reference 0.9.7g from confirmation from David Reid. ------------------------------------------------------------------------ r613 | joe | 2005-05-11 16:07:05 +0100 (Wed, 11 May 2005) | 3 lines * src/ne_string.c (b64_alphabet): Use constant array; eliminate last sizeof(pointer)'s worth of data section in libneon. ------------------------------------------------------------------------ r612 | joe | 2005-05-11 16:01:03 +0100 (Wed, 11 May 2005) | 3 lines * src/ne_dates.c (rfc1123_weekdays, short_months): Mark pointers as const. ------------------------------------------------------------------------ r611 | joe | 2005-05-09 15:28:47 +0100 (Mon, 09 May 2005) | 2 lines * src/ne_request.h: Fix nonsensical API requirement. ------------------------------------------------------------------------ r608 | joe | 2005-05-06 15:25:41 +0100 (Fri, 06 May 2005) | 3 lines Fix the feature name, thanks to the report on the evening news from a Mr Fogel. ------------------------------------------------------------------------ r599 | joe | 2005-04-24 19:34:46 +0100 (Sun, 24 Apr 2005) | 4 lines * macros/neon.m4 (NE_REQUIRE_VERSIONS): New macro, replacing NEON_REQUIRE. (NEON_CHECK_VERSION): Just check version against that reported by 'neon-config --version'; support multiple minor versions. ------------------------------------------------------------------------ r593 | joe | 2005-04-24 11:54:55 +0100 (Sun, 24 Apr 2005) | 2 lines * neon-config.in: Remove idna support flag. ------------------------------------------------------------------------ r592 | joe | 2005-04-24 11:51:15 +0100 (Sun, 24 Apr 2005) | 2 lines Synch with 0.25.x branch. ------------------------------------------------------------------------ r588 | joe | 2005-04-24 11:06:37 +0100 (Sun, 24 Apr 2005) | 2 lines * test/stubs.c [!NE_HAVE_ZLIB] (sd_reader): Fix to match prototype. ------------------------------------------------------------------------ r586 | joe | 2005-04-24 09:00:59 +0100 (Sun, 24 Apr 2005) | 3 lines * test/request.c (send_bad_offset): Use an empty file and a negative offset rather than /dev/null. ------------------------------------------------------------------------ r585 | joe | 2005-04-24 08:56:46 +0100 (Sun, 24 Apr 2005) | 2 lines * macros/neon.m4 (NEON_WARNINGS): Tweak gcc warnings. ------------------------------------------------------------------------ r584 | joe | 2005-04-24 08:55:34 +0100 (Sun, 24 Apr 2005) | 2 lines * src/Makefile.in (c++.c): Fix to exclude ne_privssl.h too. ------------------------------------------------------------------------ r582 | joe | 2005-04-17 22:29:56 +0100 (Sun, 17 Apr 2005) | 2 lines * Makefile.in (DIST_HEADERS): Do install ne_xmlreq.h. ------------------------------------------------------------------------ r579 | joe | 2005-04-17 21:54:37 +0100 (Sun, 17 Apr 2005) | 2 lines * src/ne_stubssl.c (ne_ssl_clicert_name): Match new prototype. ------------------------------------------------------------------------ r577 | joe | 2005-04-17 17:05:27 +0100 (Sun, 17 Apr 2005) | 6 lines Merge r576 from 0.25.x branch: * config.hw.in: Define the correct version macros. * .release.sh: Substitute release correctly. ------------------------------------------------------------------------ r574 | joe | 2005-04-17 16:43:25 +0100 (Sun, 17 Apr 2005) | 2 lines * src/ne_openssl.c (check_identity): Fix typo. ------------------------------------------------------------------------ r571 | joe | 2005-04-16 17:24:56 +0100 (Sat, 16 Apr 2005) | 2 lines * src/ne_alloc.c (ne_realloc_ml): Fix realloc tracking. ------------------------------------------------------------------------ r570 | joe | 2005-04-15 15:33:04 +0100 (Fri, 15 Apr 2005) | 4 lines Fix further memory leak found by --enable-memleak: * src/ne_openssl.c (check_identity): Destroy buffer on error path. ------------------------------------------------------------------------ r569 | joe | 2005-04-15 14:45:32 +0100 (Fri, 15 Apr 2005) | 6 lines Fix memory leaks found by --enable-memleak: * src/ne_openssl.c (check_identity): Destroy buffer on error path. * test/request.c (iterate_many): Destroy temp buffer. ------------------------------------------------------------------------ r568 | joe | 2005-04-15 02:23:13 +0100 (Fri, 15 Apr 2005) | 5 lines * src/ne_request.c (body_fd_send): Set session error string if seek fails, per new interface requirement. * test/request.c (send_bad_offset): New test. ------------------------------------------------------------------------ r567 | joe | 2005-04-15 02:19:34 +0100 (Fri, 15 Apr 2005) | 4 lines * src/ne_request.h: Improve general comments. (ne_request_dispatch, ne_set_request_expect100): Clarify. (ne_get_session): Mark as const. ------------------------------------------------------------------------ r563 | joe | 2005-04-14 20:05:53 +0100 (Thu, 14 Apr 2005) | 2 lines * neon-config.in: Fix syntax error. ------------------------------------------------------------------------ r562 | joe | 2005-04-14 20:04:50 +0100 (Thu, 14 Apr 2005) | 3 lines * Makefile.in (DIST_HEADERS): Don't try to install non-existant ne_cookies.h. ------------------------------------------------------------------------ r560 | joe | 2005-04-14 19:44:56 +0100 (Thu, 14 Apr 2005) | 3 lines * test/util-tests.c (versioning): Update for new macros, correct interface. ------------------------------------------------------------------------ r559 | joe | 2005-04-11 14:55:45 +0100 (Mon, 11 Apr 2005) | 4 lines * src/ne_ssl.h (ne_ssl_clicert_name): Take const clicert argument. * src/ne_openssl.c, src/ne_gnutls.c: Adapt likewise. ------------------------------------------------------------------------ r558 | joe | 2005-04-06 09:07:18 +0100 (Wed, 06 Apr 2005) | 5 lines * configure.in: Use NE_VERSIONS_BUNDLED. * src/ne_utils.c (ne_version_match): Update for new version macros; make behaviour and docs match reference documentation. ------------------------------------------------------------------------ r554 | joe | 2005-04-05 20:22:40 +0100 (Tue, 05 Apr 2005) | 5 lines * macros/neon.m4 (NE_DEFINE_VERSIONS): New macro. (NE_VERSIONS_BUNDLED): Renamed from NEON_VERSIONS; use NE_DEFINE_VERSIONS. (NEON_USE_EXTERNAL): Use NE_DEFINE_VERSIONS. ------------------------------------------------------------------------ r553 | joe | 2005-04-05 16:02:49 +0100 (Tue, 05 Apr 2005) | 2 lines * src/Makefile.in: Add deps for ne_xmlreq.c. ------------------------------------------------------------------------ r551 | joe | 2005-04-05 11:19:42 +0100 (Tue, 05 Apr 2005) | 2 lines Update. ------------------------------------------------------------------------ r550 | joe | 2005-04-05 11:19:16 +0100 (Tue, 05 Apr 2005) | 2 lines * src/ne_request.h: Improve comment wording. ------------------------------------------------------------------------ r549 | joe | 2005-04-05 00:50:26 +0100 (Tue, 05 Apr 2005) | 2 lines Fix typo. ------------------------------------------------------------------------ r548 | joe | 2005-04-04 21:01:56 +0100 (Mon, 04 Apr 2005) | 2 lines Updates. ------------------------------------------------------------------------ r547 | joe | 2005-04-04 20:51:33 +0100 (Mon, 04 Apr 2005) | 3 lines * test/uri-tests.c (leak_authinfo): Remove test; API now clarified such that current implementation is valid. ------------------------------------------------------------------------ r546 | joe | 2005-04-04 20:50:36 +0100 (Mon, 04 Apr 2005) | 2 lines * src/ne_uri.h (ne_uri_free, ne_uri_parse): Clarify API. ------------------------------------------------------------------------ r545 | joe | 2005-04-04 20:40:08 +0100 (Mon, 04 Apr 2005) | 4 lines * src/ne_alloc.c, src/ne_alloc.h (ne_oom_callback): Use a typedef for the callback argument, to fix warnings with OpenWatcom; patch by Vitali E. Pelenyov. ------------------------------------------------------------------------ r544 | joe | 2005-04-04 20:34:26 +0100 (Mon, 04 Apr 2005) | 4 lines * src/ne_request.c (add_fixed_headers): Send "close" token in Connection header if persistent connections are disabled; patch by Tom Hoefakker. Use ne_buffer_czappend throughout. ------------------------------------------------------------------------ r542 | joe | 2005-04-04 18:32:15 +0100 (Mon, 04 Apr 2005) | 6 lines * test/xmlreq.c: New file. * test/Makefile.in: Build it. * test/utils.h: Include child.h. ------------------------------------------------------------------------ r541 | joe | 2005-04-04 18:30:50 +0100 (Mon, 04 Apr 2005) | 8 lines * src/ne_xmlreq.h (ne_xml_parse_response, ne_xml_dispatch_request): Specify that session error string is set for XML parse errors. * src/ne_xmlreq.c (parse_error): New function. (ne_xml_parse_response): On successful end-of-response, tell the the XML parser the end of the document is reached. Use parse_error() for error handling. ------------------------------------------------------------------------ r540 | joe | 2005-04-04 14:49:25 +0100 (Mon, 04 Apr 2005) | 2 lines * src/ne_socket.c (ne_service_lookup): Remove function. ------------------------------------------------------------------------ r531 | joe | 2005-03-19 22:30:43 +0000 (Sat, 19 Mar 2005) | 2 lines * test/request.c: Remove idna_hostname; missed in previous commit. ------------------------------------------------------------------------ r530 | joe | 2005-03-19 22:19:37 +0000 (Sat, 19 Mar 2005) | 7 lines Avoid use of "read" and "write" since POSIX owns these names and allows them to be macros. * src/ne_socket.c (struct iofns): Rename read and write functions to sread and swrite. (ne_sock_read, ne_sock_peek, ne_sock_fullwrite, ne_sock_readline): Synch. ------------------------------------------------------------------------ r529 | joe | 2005-03-19 21:24:27 +0000 (Sat, 19 Mar 2005) | 2 lines * src/ne_uri.c (uri_paths): Fix URI encoding default. ------------------------------------------------------------------------ r518 | joe | 2005-03-05 09:14:59 +0000 (Sat, 05 Mar 2005) | 11 lines Remove support for IDNA: IDNA really needs to be done at application level. * macros/neon.m4 (NEON_LIBIDN): Remove. * src/ne_session.c (set_hostinfo): Remove IDNA support. * src/ne_utils.c, src/ne_utils.h: Don't advertise IDNA feature. * test/util-tests.c, test/request.c: Remove IDNA tests. ------------------------------------------------------------------------ r517 | joe | 2005-03-03 19:25:11 +0000 (Thu, 03 Mar 2005) | 3 lines * src/ne_socket.c (NE_ISRESET): Also treat ENOTCONN as a "connection reset" error. ------------------------------------------------------------------------ r516 | joe | 2005-03-03 19:20:03 +0000 (Thu, 03 Mar 2005) | 3 lines * macros/neon-xml-parser.m4 (NEON_XML_PARSER): Default to detect expat; fall back on libxml2. ------------------------------------------------------------------------ r515 | joe | 2005-03-03 19:11:45 +0000 (Thu, 03 Mar 2005) | 3 lines * macros/neon.m4 (NEON_SSL): Disable GNU TLS support for the 0.25.0 release, since it's not complete yet. ------------------------------------------------------------------------ r512 | joe | 2005-02-28 14:17:09 +0000 (Mon, 28 Feb 2005) | 2 lines Note string type changes. ------------------------------------------------------------------------ r511 | joe | 2005-02-28 14:16:24 +0000 (Mon, 28 Feb 2005) | 5 lines Missed in previous commit: * src/ne_ssl.h (ne_ssl_cert_identity, ne_ssl_cert_name): Define to return UTF-8 only. ------------------------------------------------------------------------ r510 | joe | 2005-02-28 14:15:59 +0000 (Mon, 28 Feb 2005) | 9 lines * src/ne_ssl.h (ne_ssl_cert_identity, ne_ssl_cert_name): Define to return UTF-8 only. * src/ne_openssl.c (append_dirstring): Factor out from ne_ssl_readable_dname. (ne_ssl_readable_dname): Use factored-out version. (dup_ia5string): New function. (check_identity): Use append_dirstring to convert commonName to UTF-8 if necessary; use dup_ia5string. ------------------------------------------------------------------------ r509 | joe | 2005-02-28 14:09:02 +0000 (Mon, 28 Feb 2005) | 9 lines * src/ne_ssl.h (ne_ssl_cert_identity, ne_ssl_cert_name): Define to return UTF-8 only. * src/ne_openssl.c (append_dirstring): Factor out from ne_ssl_readable_dname. (ne_ssl_readable_dname): Use factored-out version. (dup_ia5string): New function. (check_identity): Use append_dirstring to convert commonName to UTF-8 if necessary; use dup_ia5string. ------------------------------------------------------------------------ r508 | joe | 2005-02-28 11:54:17 +0000 (Mon, 28 Feb 2005) | 2 lines * test/xml.c (matches): Test that with-BOM without-prolog also parses. ------------------------------------------------------------------------ r507 | joe | 2005-02-28 11:53:39 +0000 (Mon, 28 Feb 2005) | 3 lines * src/ne_xml.c (ne_xml_parser_s, ne_xml_parse): Conditionalize BOM handling to expat <= 1.95.2 and all current versions of libxml2. ------------------------------------------------------------------------ r506 | joe | 2005-02-28 11:07:11 +0000 (Mon, 28 Feb 2005) | 2 lines * test/compress.c: Fix signedness warning. ------------------------------------------------------------------------ r505 | joe | 2005-02-28 11:03:42 +0000 (Mon, 28 Feb 2005) | 3 lines * test/socket.c (addr_compare): Fix to pass real raw addresses and fixed signedness warnings. ------------------------------------------------------------------------ r504 | joe | 2005-02-28 10:54:28 +0000 (Mon, 28 Feb 2005) | 2 lines Add ne_get_content_type change and reshuffle. ------------------------------------------------------------------------ r503 | joe | 2005-02-28 10:52:09 +0000 (Mon, 28 Feb 2005) | 3 lines * src/ne_basic.h (ne_get_content_type): Clarify that all fields will be non-NULL on success. ------------------------------------------------------------------------ r502 | joe | 2005-02-26 19:57:19 +0000 (Sat, 26 Feb 2005) | 2 lines Note provider-callback error handling API change; fixed bug. ------------------------------------------------------------------------ r501 | joe | 2005-02-26 19:56:24 +0000 (Sat, 26 Feb 2005) | 14 lines * src/ne_private.h (ne__pull_request_body): Remove prototype. * src/ne_request.h: Require that request-body-provider callback sets the session error string if returning errors. * src/ne_request.c (struct ne_request_s): Remove body_progress field. (send_request_body): Combine old ne__pull_request_body, send_request_body and send_with_progress functions into one. Fix error handling confusion between provider errors and socket errors; move NE_RETRY handling here and take a retry flag. (send_request): Update to pass retry flag to send_request_body and remove NE_RETRY handling on errors from same. ------------------------------------------------------------------------ r500 | joe | 2005-02-26 19:24:49 +0000 (Sat, 26 Feb 2005) | 1 line Ignore ChangeLog ------------------------------------------------------------------------ r499 | joe | 2005-02-26 19:23:52 +0000 (Sat, 26 Feb 2005) | 3 lines ne_lock_refresh does now DTRT, and D.J.'s cunningly borked proxy should now be handled. ------------------------------------------------------------------------ r498 | joe | 2005-02-26 19:22:31 +0000 (Sat, 26 Feb 2005) | 6 lines * src/ne_request.h: Remove EOL definition, namespace violation. * test/stubs.c, test/lock.c, test/auth.c, src/ne_request.c, src/ne_request.h, src/ne_props.c, src/ne_acl.c, src/ne_locks.c: Define EOL. ------------------------------------------------------------------------ r497 | joe | 2005-02-26 19:16:14 +0000 (Sat, 26 Feb 2005) | 3 lines * src/ne_locks.c (ne_lock_refresh): Always update timeout of passed-in lock structure, even if new timeout is unknown. ------------------------------------------------------------------------ r496 | joe | 2005-02-26 19:10:19 +0000 (Sat, 26 Feb 2005) | 2 lines ne_uri_escape escaping rules updated. ------------------------------------------------------------------------ r495 | joe | 2005-02-26 19:09:52 +0000 (Sat, 26 Feb 2005) | 2 lines * src/ne_uri.h (ne_path_escape): Fix grammar. ------------------------------------------------------------------------ r494 | joe | 2005-02-26 19:02:53 +0000 (Sat, 26 Feb 2005) | 4 lines * ChangeLog.CVS: Renamed from ChangeLog. * Makefile.in (ChangeLog): New target. ------------------------------------------------------------------------ r493 | joe | 2005-02-26 18:58:46 +0000 (Sat, 26 Feb 2005) | 2 lines * macros/neon.m4 (NE_SNPRINTF): Use new trio URL. ------------------------------------------------------------------------ r492 | joe | 2005-02-26 18:57:32 +0000 (Sat, 26 Feb 2005) | 3 lines * src/ne_socket.c (init_ssl): Call OpenSSL_add_all_algorithms instead of the specific PKCS12_PBE_add. ------------------------------------------------------------------------ r488 | joe | 2005-02-24 14:42:09 +0000 (Thu, 24 Feb 2005) | 4 lines * src/ne_auth.c (clean_session, make_gss_error, free_auth): Fixed signdness mismatch warnings from GSSAPI code; always use unsigned integers for error codes. ------------------------------------------------------------------------ r483 | joe | 2005-02-24 14:05:44 +0000 (Thu, 24 Feb 2005) | 2 lines * macros/neon.m4 (NEON_FORMAT): Support type arguments with spaces. ------------------------------------------------------------------------ r481 | joe | 2005-02-14 16:07:35 +0000 (Mon, 14 Feb 2005) | 3 lines * configure.in: Just AC_DEFINE NEON_IS_LIBRARY; update copyright notice; be less noisy. ------------------------------------------------------------------------ r480 | joe | 2005-02-14 16:02:58 +0000 (Mon, 14 Feb 2005) | 2 lines * Makefile.in (clean, subdirs, check): Be less noisy. ------------------------------------------------------------------------ r479 | joe | 2005-02-14 15:43:27 +0000 (Mon, 14 Feb 2005) | 10 lines * common/tests.c (W): Suppress glibc warn_unused_result annoyance. (W_RED): New macro. (child_segv): Use W_RED; do dump core. (parent_segv): Rename from segv; don't call async-signal-unsafe fflush(); use W_RED; sleep after kill(); (in_child, main): Install signal handlers for SIGABRT as well as SIGSEGV. * common/child.c (server_child, spawn_server_repeat): Suppress glibc warn_unused_result annoyance; abort if write() fails. ------------------------------------------------------------------------ r477 | joe | 2005-02-11 13:15:22 +0000 (Fri, 11 Feb 2005) | 2 lines * neon-config.in (--libs): Don't print -L$libdir if $prefix==/usr. ------------------------------------------------------------------------ r464 | joe | 2005-01-27 22:27:26 +0000 (Thu, 27 Jan 2005) | 3 lines * test/uri-tests.c (leak_authinfo): Add expected-leaky test for ne_uri_parse leak. ------------------------------------------------------------------------ r463 | joe | 2005-01-27 22:13:10 +0000 (Thu, 27 Jan 2005) | 3 lines * src/ne_auth.c: Only include ne_private.h for GSSAPI code. (digest_body): Remove function. ------------------------------------------------------------------------ r462 | joe | 2005-01-27 22:04:44 +0000 (Thu, 27 Jan 2005) | 7 lines * src/ne_auth.c: Drop qop=auth-int support, sice it is universally unimplemented by servers and comes with too much baggage. (struct auth_challenge): Drop qop_auth_int field. (digest_challenge, request_digest, verify_digest_response, auth_challenge, ah_pre_send): Drop qop=auth-int support. (auth_body_reader): Remove function. ------------------------------------------------------------------------ r461 | joe | 2005-01-27 21:56:19 +0000 (Thu, 27 Jan 2005) | 2 lines * src/ne_locks.c (ne_lock): Use ne_xml_dispatch_request. ------------------------------------------------------------------------ r460 | joe | 2005-01-27 21:50:32 +0000 (Thu, 27 Jan 2005) | 1 line News updates. ------------------------------------------------------------------------ r459 | joe | 2005-01-27 20:05:25 +0000 (Thu, 27 Jan 2005) | 2 lines * neon.mak: Conditionally enable SSPI support (Vladimir). ------------------------------------------------------------------------ r458 | joe | 2005-01-27 20:04:39 +0000 (Thu, 27 Jan 2005) | 2 lines * test/cookies.c: Remove file. ------------------------------------------------------------------------ r457 | joe | 2005-01-27 20:03:53 +0000 (Thu, 27 Jan 2005) | 11 lines Fix SSPI code so that it compiles for Win32 (Vladimir): * src/ne_sspi.h (ne_sspi_deinit): fixed return type. * src/ne_sspi.c: Added preprocessor check HAVE_SSPI to allow compilation without SSPI. (getMaxTokenSize): removed const qualifier for package parameter because it has to be passed to a function that takes a not const reference. (ne_sspi_init, ne_sspi_deinit): Match the function names to the correct functions. ------------------------------------------------------------------------ r456 | joe | 2005-01-27 20:01:48 +0000 (Thu, 27 Jan 2005) | 2 lines * neon.mak: Don't build ne_cookies.c (Vladimir). ------------------------------------------------------------------------ r450 | joe | 2005-01-26 16:22:26 +0000 (Wed, 26 Jan 2005) | 2 lines * src/ne_session.h (ne_set_persist): Clarify lifetime of addrs array. ------------------------------------------------------------------------ r449 | joe | 2005-01-26 14:36:02 +0000 (Wed, 26 Jan 2005) | 7 lines * src/ne_uri.h (ne_path_escape): Define to percent-encode any characters barring unreserved and forward-slash. * src/ne_uri.c (uri_chars): Update to use RF3986 grammar productions. (path_escape_ch): Replaces ESCAPE. (ne_path_escape): Clean up, use new path_escape_ch. ------------------------------------------------------------------------ r448 | joe | 2005-01-26 09:23:36 +0000 (Wed, 26 Jan 2005) | 2 lines * src/ne_auth.c (get_gss_name): Remove redundant buffer initilization. ------------------------------------------------------------------------ r446 | joe | 2005-01-22 00:00:54 +0000 (Sat, 22 Jan 2005) | 4 lines * src/ne_request.c (read_message_header, read_response_headers): Clarify that both functions guarantee to close the connection on error. ------------------------------------------------------------------------ r445 | joe | 2005-01-21 23:54:36 +0000 (Fri, 21 Jan 2005) | 3 lines * test/request.c (fail_on_invalid): Test for chunk size overflow and EOF-at-chunk-size cases. ------------------------------------------------------------------------ r444 | joe | 2005-01-21 23:47:55 +0000 (Fri, 21 Jan 2005) | 3 lines * test/request.c (fail_on_invalid): Rename from fail_corrupt_chunks; test for invalid C-L in response. ------------------------------------------------------------------------ r443 | joe | 2005-01-21 23:41:42 +0000 (Fri, 21 Jan 2005) | 4 lines * src/ne_request.c (ne_begin_request): Reorder message-length logic to avoid doing unnecessary work. Fail rather than ignore an invalid Content-Length response header. ------------------------------------------------------------------------ r442 | joe | 2005-01-21 23:38:57 +0000 (Fri, 21 Jan 2005) | 3 lines * Makefile.in (cover): Remove all .*da files before running coverage testing to avoid gcda merge errors. ------------------------------------------------------------------------ r441 | joe | 2005-01-21 17:41:00 +0000 (Fri, 21 Jan 2005) | 1 line Tweak comment. ------------------------------------------------------------------------ r440 | joe | 2005-01-21 17:28:19 +0000 (Fri, 21 Jan 2005) | 3 lines * src/ne_request.h (ne_get_response_header, ne_response_header_iterate): Clarify API guarantees. ------------------------------------------------------------------------ r439 | joe | 2005-01-21 17:23:06 +0000 (Fri, 21 Jan 2005) | 7 lines Add a response-header iterator interface, needed by OpenOffice: * src/ne_request.c (struct ne_request_s): Add current_index field. (ne_response_header_iterate): New function. * test/request.c (iterate_many, iterate_none): New tests. ------------------------------------------------------------------------ r438 | joe | 2005-01-21 16:28:52 +0000 (Fri, 21 Jan 2005) | 2 lines * src/ne_request.c (struct field): Remove unused valloc field. ------------------------------------------------------------------------ r437 | joe | 2005-01-21 16:25:12 +0000 (Fri, 21 Jan 2005) | 5 lines * src/ne_request.c (ne_begin_request): Fix a case where NE_RETRY could be leaked to the caller if a connection was left open then ne_set_persist(sess, 0) was called immediately before a request was sent but suffered a persistent connection timeout. ------------------------------------------------------------------------ r436 | joe | 2005-01-21 16:19:05 +0000 (Fri, 21 Jan 2005) | 5 lines * src/ne_request.c (HTTP_ERR, HTTP_EXPECT_*): Remove now-unused macros. (ne_begin_request, ne_end_request, ne_request_dispatch): Expand HTTP_ERR usage. ------------------------------------------------------------------------ r435 | joe | 2005-01-21 16:08:53 +0000 (Fri, 21 Jan 2005) | 3 lines * test/compress.c (tests): retry_notcompress passes since response-header-handling fixes. ------------------------------------------------------------------------ r434 | joe | 2005-01-21 16:07:05 +0000 (Fri, 21 Jan 2005) | 3 lines * src/ne_request.c (send_request): Code cleanups, no functional change. ------------------------------------------------------------------------ r433 | joe | 2005-01-21 16:03:28 +0000 (Fri, 21 Jan 2005) | 2 lines * src/ne_request.c (ne_request_create): Remove some debugging noise. ------------------------------------------------------------------------ r432 | joe | 2005-01-21 15:59:37 +0000 (Fri, 21 Jan 2005) | 3 lines * src/ne_request.c (open_connection): Only call ne_close_connection in ne__negotiate_ssl failure case. ------------------------------------------------------------------------ r431 | joe | 2005-01-21 15:54:26 +0000 (Fri, 21 Jan 2005) | 2 lines * neon.mak: Build ne_xmlreq.c. ------------------------------------------------------------------------ r430 | joe | 2005-01-20 22:04:23 +0000 (Thu, 20 Jan 2005) | 15 lines Windows SSPI NTLM/Negotiate implementation from Vladimir Berezniker: * config.hw.in: Define HAVE_SSPI. * src/ne_sspi.c, src/ne_sspi.h: New files. * src/ne_auth.c (auth_scheme): Add new schemes to enum. [HAVE_SSPI] (auth_session): Add sspi_token, sspi_context fields. (clean_session): Clean up sspi fields. (request_sspi, sspi_challenge): New functions. (auth_challenge, ah_pre_send): Handle Negotiate/NTLM-using-SSPI schemes. * src/ne_socket.c [HAVE_SSPI] (ne_sock_init, ne_sock_exit): Initialize/de-initialize SSPI global state. ------------------------------------------------------------------------ r429 | joe | 2005-01-13 19:00:13 +0000 (Thu, 13 Jan 2005) | 2 lines Reorganise. ------------------------------------------------------------------------ r428 | joe | 2005-01-13 18:53:33 +0000 (Thu, 13 Jan 2005) | 6 lines Re-drop ne_cookies.[ch], change lost in CVS conversion somehow: * ne_cookies.c, ne_cookies.h: Drop cookies support: used old spec revision and wasn't very complete anyway. ------------------------------------------------------------------------ r427 | joe | 2005-01-13 18:51:53 +0000 (Thu, 13 Jan 2005) | 2 lines * test/string-tests.c (append): Test ne_buffer_czappend. ------------------------------------------------------------------------ r426 | joe | 2005-01-13 18:44:00 +0000 (Thu, 13 Jan 2005) | 7 lines Fixes for some warnings from Solaris cc: * src/ne_openssl.c (ne_ssl_clicert_read): Pass an int not an unsigned int to X509_alias_get0. (ne_ssl_cert_export): Use a char * for the ne_base64 return value to fix signed-vs-unsigned mismatch. ------------------------------------------------------------------------ r425 | joe | 2005-01-09 13:45:09 +0000 (Sun, 09 Jan 2005) | 2 lines * src/ne_string.h (ne_buffer_czappend): New macro. ------------------------------------------------------------------------ r424 | joe | 2005-01-09 13:06:22 +0000 (Sun, 09 Jan 2005) | 3 lines * src/ne_request.c (free_response_headers): Adjust code style, no functional change. ------------------------------------------------------------------------ r414 | joe | 2005-01-07 15:12:17 +0000 (Fri, 07 Jan 2005) | 6 lines * src/ne_locks.c (lk_startelm): Set timeout of active lock to NE_TIMEOUT_INVALID. (ne_lock_free, ne_lock): Out-of-line NE_FREE. (ne_lock_refresh): Use ne_xml_dispatch_request; rejig error handling; really update timeout field of passed-in lock structure if returned by server. ------------------------------------------------------------------------ r413 | joe | 2005-01-07 00:55:42 +0000 (Fri, 07 Jan 2005) | 4 lines * src/ne_locks.c (lk_startelm): Only retrive lock-token if not already known; set session error on abort. (ne_lock_refresh): Store lock-token in context, simplify error handling. ------------------------------------------------------------------------ r389 | joe | 2005-01-03 10:01:20 +0000 (Mon, 03 Jan 2005) | 3 lines * macros/neon.m4 (LIBNEON_SOURCE_CHECKS): Only look for gethostbyname if getaddrinfo is not available. ------------------------------------------------------------------------ r382 | joe | 2005-01-02 13:18:23 +0000 (Sun, 02 Jan 2005) | 4 lines * macros/neon-xml-parser.m4 (NEON_XML_PARSER, NE_XML_BUNDLED_EXPAT): Take srcdir, builddir arguments to support VPATH builds correctly. ------------------------------------------------------------------------ r373 | joe | 2004-12-31 17:55:39 +0000 (Fri, 31 Dec 2004) | 4 lines * src/ne_request.c (read_response_block): Read chunk size lines into req->respbuf to eliminate the "minimum buffer size" requirement of ne_read_response_block. ------------------------------------------------------------------------ r372 | joe | 2004-12-31 12:13:22 +0000 (Fri, 31 Dec 2004) | 3 lines * test/common/tests.h (ONCMP): Fix inverted expected/actual in failure case. ------------------------------------------------------------------------ r371 | joe | 2004-12-31 12:12:29 +0000 (Fri, 31 Dec 2004) | 7 lines * src/ne_request.c (free_response_headers): Factor out from ne_request_destroy. (ne_request_destroy): Use it. (ne_begin_request): Free response headers each time the response is read. * test/request.c (retry_post_send, reset_headers): New functions. ------------------------------------------------------------------------ r370 | joe | 2004-12-31 11:19:57 +0000 (Fri, 31 Dec 2004) | 3 lines * src/ne_redirect.c (post_send): C89 compile fix from Vladimir Berezniker. ------------------------------------------------------------------------ r369 | joe | 2004-12-31 01:36:29 +0000 (Fri, 31 Dec 2004) | 1 line Docco fix. ------------------------------------------------------------------------ r368 | joe | 2004-12-31 01:11:23 +0000 (Fri, 31 Dec 2004) | 8 lines * src/ne_auth.c (tokenize): Optionally pass back the separator character to fix the Negotiate parameter handling. (auth_challenge): Only grab a Negotiate parameter if the separator was a space. * test/auth.c (basic): Test for a Negotiate challenge *without* a parameter. ------------------------------------------------------------------------ r367 | joe | 2004-12-30 11:55:13 +0000 (Thu, 30 Dec 2004) | 63 lines Remove callback-based response header handling in favour of ne_get_response_header interface: * src/ne_request.h (ne_get_response_header): New function, replacing ne_add_response_header_handler and ne_add_response_header_catcher. * src/ne_request.c (struct header_handler): Remove. (struct field): Add. (struct ne_request_s): Store a hash of header fields rather than a hash of callbacks. (te_hdr_handler, connection_hdr_handler, clength_hdr_handler, ne_add_response_header_catcher, ne_add_response_header_handler, ne_duplicate_header, ne_handle_numeric_header): Remove functions. (get_response_header_hv, ne_get_response_header, add_response_header, remove_response_header): New functions. (ne_request_create): Don't register the callbacks. (read_response_headers): Call add_response_header for each field. (ne_begin_request): Move handling of Connection, T-E and C-L headers here. Comply with 2616/14.10 w.r.t. Connection header handling in HTTP/1.0 responses. (ne_request_dispatch): Use ne_discard_response (unrelated). * src/ne_redirect.c (struct redirect): Remove location field. (post_send): Adjust to retrieve location header here. * src/ne_basic.h (ne_get_content_type): Replaces ne_content_type_handler. * src/ne_basic.c (dispatch_to_fd): New function. (get_to_fd, get_lastmodified, clength_hdr_handler, accept_206, content_range_hdr_handler): Remove functions. (ne_getmodtime): Adjust to use ne_get_response_header. (ne_get_range, ne_get, ne_post): Adjust to use dispatch_to_fd. (ne_get_content_type): Adjust for new API, use ne_get_response_header. (parse_dav_header, ne_options): Adjust to use ne_get_response_header. * src/ne_compress.c (struct ne_decompress_s): Add ne_request * field, remove enchdr field. (gz_reader): Retrieve C-E header on demand, here. (ne_decompress_reader, ne_decompress_destroy): Remove C-E response header duplication. * src/ne_auth.c (auth_request): Remove auth_hdr, auth_info_hdr fields. (ah_collect_header): Remove function. (ah_create, ah_destroy): Remove response-header callback handling. (ah_post_send): Retrieve -Authenticate header here; correctly handle the broken proxy which sends a 401 in response to CONNECT. * src/ne_locks.c (lk_startelm): Retrieve Lock-Token header here. (get_ltoken_hdr): Remove function. (ne_lock, ne_lock_refresh): Remove response-header handling. * test/basic.c (content_type): Test new interface. * test/request.c (expect_header_value): Adjust to accept NULL value, use ne_get_response_header interface. (multi_header): Test new ne_get_response_header multi-header handling. (multi_header2, strip_http10_connhdr, strip_http10_connhdr2): New tests. ------------------------------------------------------------------------ r366 | joe | 2004-12-30 11:38:37 +0000 (Thu, 30 Dec 2004) | 2 lines * src/ne_compress.c: Debugging message tweaks. ------------------------------------------------------------------------ r365 | joe | 2004-12-30 10:58:08 +0000 (Thu, 30 Dec 2004) | 2 lines * test/socket.c (peek_expect): Add buffer overflow detection. ------------------------------------------------------------------------ r364 | joe | 2004-12-30 10:51:17 +0000 (Thu, 30 Dec 2004) | 2 lines * test/common/tests.c (main): Fix build for non-NEON_MEMLEAK. ------------------------------------------------------------------------ r363 | joe | 2004-12-30 10:50:20 +0000 (Thu, 30 Dec 2004) | 3 lines * test/common/tests.c (main): Print a message for tests which are marked as T_XLEAKY. ------------------------------------------------------------------------ r362 | joe | 2004-12-30 10:23:00 +0000 (Thu, 30 Dec 2004) | 3 lines * test/utils.c (any_2xx_request): Destroy the request object even if failing. ------------------------------------------------------------------------ r361 | joe | 2004-12-30 00:11:53 +0000 (Thu, 30 Dec 2004) | 5 lines * src/ne_xmlreq.c (ne_xml_parse_response, ne_xml_dispatch_request): New file, new functions. * src/Makefile.in (NEON_DAVOBJS): Add ne_xmlreq.*o. ------------------------------------------------------------------------ r360 | joe | 2004-12-24 14:49:02 +0000 (Fri, 24 Dec 2004) | 3 lines * src/ne_request.c (ne_read_response_to_fd, ne_discard_response): New functions. ------------------------------------------------------------------------ r359 | joe | 2004-12-13 14:13:27 +0000 (Mon, 13 Dec 2004) | 6 lines * src/ne_auth.c (auth_challenge): Fix previous commit; stop parsing if ne_token() reaches end-of-string. * test/auth.c (negotiate_regress): Add test. ------------------------------------------------------------------------ r358 | joe | 2004-12-09 22:22:26 +0000 (Thu, 09 Dec 2004) | 3 lines * src/ne_auth.c (auth_challenge): Grab the Negotiate parameter properly. ------------------------------------------------------------------------ r357 | joe | 2004-12-01 08:42:49 +0000 (Wed, 01 Dec 2004) | 11 lines From Vladimir Berezniker: update Win32 make file to match the preprocessor definition changes applied to source code in r256: * neon.mak: OpenSSL: Change NEON_SSL to NE_HAVE_SSL and add a missing HAVE_OPENSSL. ZLib: Change NEON_ZLIB to NE_HAVE_ZLIB. Expat: Replace NEON_NODAV with NE_HAVE_DAV * config.hw.in: Discard no longer used USE_DAV_LOCKS. ------------------------------------------------------------------------ r356 | joe | 2004-11-18 10:09:07 +0000 (Thu, 18 Nov 2004) | 11 lines Win32 build update from Branko Čibej: Change the Win32 build to compile ZLib from sources, and change the ZLib versin requirement. This doesn't change neon.mak's external interface. * neon.mak: Add parameters and targets for building ZLib from source. * INSTALL.win32: Update the documentation, and note that the ZLib version must be at least 1.2.1. ------------------------------------------------------------------------ r355 | joe | 2004-11-18 09:50:27 +0000 (Thu, 18 Nov 2004) | 5 lines Win32 build fix from Vladimir Berezniker: * src/ne_dates.c: Add windows.h to the list of include files to provide definition of TIME_ZONE_INFORMATION on WIN32 platforms. ------------------------------------------------------------------------ r354 | joe | 2004-11-15 14:47:52 +0000 (Mon, 15 Nov 2004) | 7 lines Improve OpenSSL error handling, fixing "SSL error: (null)" errors from interrupted Subversion checkouts over SSL; now reported as "Interrupted system call" as expected: * src/ne_socket.c (error_ossl): Always check the OpenSSL error stack for SSL errors other than SSL_ERROR_ZERO_RETURN. ------------------------------------------------------------------------ r353 | joe | 2004-11-11 14:38:49 +0000 (Thu, 11 Nov 2004) | 3 lines * test/socket.c (begin) [SOCKET_SSL]: Update to pass third argument to ne_sock_connect_ssl. ------------------------------------------------------------------------ r352 | joe | 2004-10-31 22:33:28 +0000 (Sun, 31 Oct 2004) | 2 lines * macros/neon.m4 (NEON_SSL): Require GNU TLS 1.0.22 or later. ------------------------------------------------------------------------ r351 | joe | 2004-10-31 19:17:00 +0000 (Sun, 31 Oct 2004) | 3 lines * src/ne_openssl.c (ne__negotiate_ssl): Set freechain to fix certificate chain leak for an SSLv2 connection. ------------------------------------------------------------------------ r350 | joe | 2004-10-31 19:14:47 +0000 (Sun, 31 Oct 2004) | 1 line Doc fix. ------------------------------------------------------------------------ r349 | joe | 2004-10-31 19:13:43 +0000 (Sun, 31 Oct 2004) | 11 lines * src/ne_socket.c (ne_sock_connect_ssl): Take a userdata parameter; attach this as OpenSSL "app data" pointer and GNU TLS "session pointer". * src/ne_openssl.c (provide_client_cert): Adapt to use right app data pointer. (ne__negotiate_ssl): Pass session pointer to ne_sock_connect_ssl. * src/ne_gnutls.c (ne__negotiate_ssl): Pass session pointer to ne_sock_connect_ssl. ------------------------------------------------------------------------ r348 | joe | 2004-10-31 18:44:31 +0000 (Sun, 31 Oct 2004) | 3 lines * Makefile.in (uncover, cover): Remove all .*da files before re-running coverage testing. ------------------------------------------------------------------------ r347 | joe | 2004-10-31 18:43:41 +0000 (Sun, 31 Oct 2004) | 8 lines Improve ne_socket.c coverage: * test/socket.c (addr_make_v4, addr_make_v6): Test ne_iaddr_typeof. (addr_compare): Fix ne_iaddr_cmp tests with v6 addresses. (expect_close, expect_read): Fix error messages. (fullread_expect, line_overflow, line_long_chunked, expect_block_timeout, blocking, block_timeout): New functions. ------------------------------------------------------------------------ r346 | joe | 2004-10-31 15:03:54 +0000 (Sun, 31 Oct 2004) | 1 line Doc fix. ------------------------------------------------------------------------ r345 | joe | 2004-10-31 12:15:55 +0000 (Sun, 31 Oct 2004) | 7 lines * src/ne_compress.c (struct ne_decompress_s): Stop using a union to decode the gzip header; rename in.buf to header, incount to hdrcount. (HDR_ID1, HDR_ID2, HDR_CMETH, HDR_FLAGS, HDR_MTIME, HDR_XFLAGS, HDR_OS): New macros. (parse_header): Decode the header in-place using new macros. (gz_reader): Adjust for new field names. ------------------------------------------------------------------------ r344 | joe | 2004-10-31 12:01:06 +0000 (Sun, 31 Oct 2004) | 2 lines * test/compress.c (do_fetch): Do call ne_decompress_destroy still. ------------------------------------------------------------------------ r343 | joe | 2004-10-31 11:53:35 +0000 (Sun, 31 Oct 2004) | 7 lines * Makefile.in (uncover): New target. (cover): Adapt for modern gcc. * src/Makefile.in (clean): Clean more. * test/Makefile.in (clean): Clean more. ------------------------------------------------------------------------ r342 | joe | 2004-10-30 12:54:26 +0100 (Sat, 30 Oct 2004) | 3 lines * src/ne_utils.c (ne_has_support): Avoid a leading 'return 1' without a case statement when *no* features are supported. ------------------------------------------------------------------------ r339 | joe | 2004-10-30 12:41:53 +0100 (Sat, 30 Oct 2004) | 5 lines * src/ne_compress.c (ne_decompress_reader) [!HAVE_ZLIB]: Update for new interface. * test/stubs.c (stub_decompress): Update for new interface. ------------------------------------------------------------------------ r337 | joe | 2004-10-25 21:17:32 +0100 (Mon, 25 Oct 2004) | 4 lines Missed in previous commit: * test/Makefile.in (ZLIB_HELPERS, empty.gz): New helper targets. ------------------------------------------------------------------------ r336 | joe | 2004-10-25 21:12:16 +0100 (Mon, 25 Oct 2004) | 15 lines Update ne_decompress interface to handle errors by aborting the response rather than returning errors via ne_decompress_destroy. * src/ne_compress.c (struct ne_decompress_s): Remove NE_Z_ERROR state. (parse_header, do_inflate): Don't set error state. (gz_reader): Do truncated response handling properly at end-of-response. Don't set state to NE_Z_ERROR on error cases, just return failure and abort the response. (ne_decompress_destroy): Return void, do no error handling here. * test/compress.c (reader): Abort on failure. (do_fetch): Handle errors returned via ne_request_dispatch rather than ne_decompress_destroy. (fail_trailing_1b, fail_empty, notcomp_empty): New tests. ------------------------------------------------------------------------ r335 | joe | 2004-10-25 20:34:34 +0100 (Mon, 25 Oct 2004) | 2 lines * test/ssl.c (cert_identities): Check the simplest case first. ------------------------------------------------------------------------ r334 | joe | 2004-10-25 20:11:55 +0100 (Mon, 25 Oct 2004) | 5 lines * src/ne_gnutls.c (ne_ssl_context_trustcert): Fix for GNU TLS 1.0 (Aleix). (check_certificate): Less debugging noise (ne__negotiate_ssl): Remove unused variable, tweak debug message. ------------------------------------------------------------------------ r333 | joe | 2004-10-25 10:44:33 +0100 (Mon, 25 Oct 2004) | 3 lines * src/ne_gnutls.c (check_identity): Fix handling of multiple names in the subjectAltName extension (per the two_subject_altname2 test). ------------------------------------------------------------------------ r332 | joe | 2004-10-24 21:10:29 +0100 (Sun, 24 Oct 2004) | 1 line Note that expect100 is now sensible, and that ne_lock_refresh is not. ------------------------------------------------------------------------ r331 | joe | 2004-10-24 18:44:49 +0100 (Sun, 24 Oct 2004) | 4 lines * src/ne_gnutls.c (check_identity): Return -1 if no CN field found. (make_peers_chain, check_certificates): New function. (ne__negotiate_ssl): Retrieve and verify the peer certificate chain. ------------------------------------------------------------------------ r330 | joe | 2004-10-24 16:50:33 +0100 (Sun, 24 Oct 2004) | 7 lines * src/ne_gnutls.c (ne__negotiate_ssl): Mark pointers as const, prepare for doing cert verification. (ne_ssl_context_trustcert): Implement. (pkcs12_parse): Don't try and determine encryptedness here. (ne_ssl_clicert_read): Verify the MAC using an empty password. (ne_ssl_clicert_decrypt): Verify the MAC using the given password. ------------------------------------------------------------------------ r329 | joe | 2004-10-24 15:46:32 +0100 (Sun, 24 Oct 2004) | 2 lines * src/ne_gnutls.c (pkcs12_parse): Fix GCC warnings from unhandled enum fields. ------------------------------------------------------------------------ r328 | joe | 2004-10-24 13:55:14 +0100 (Sun, 24 Oct 2004) | 9 lines Based on patch from Aleix Conchillo Flaque: * src/ne_gnutls.c (ne_ssl_clicert_free): Conditionally free the pkey, subject fields. (x509_crt_copy): New function. (dup_client_cert): Fix memory handling. (pkcs12_parse): Take pointers to pkey, crt, name. (ne_ssl_clicert_read, ne_ssl_clicert_decrypt): Adjust accordingly. ------------------------------------------------------------------------ r327 | joe | 2004-10-22 09:41:46 +0100 (Fri, 22 Oct 2004) | 6 lines From Aleix Conchillo Flaque: * src/ne_gnutls.c (ne_ssl_context_trustcert): Implement pending GnuTLS fix. (pkcs12_parse): Fix certificate handling. ------------------------------------------------------------------------ r326 | joe | 2004-10-20 07:17:34 +0100 (Wed, 20 Oct 2004) | 6 lines PKCS#12 support for GnuTLS interface from Aleix Conchillo Flaque: * src/ne_gnutls.c (ne_ssl_clicert_free, dup_client_cert, ne_ssl_clicert_read, ne_ssl_clicert_encrypted, ne_ssl_clicert_decrypt, ne_ssl_clicert_owner, ne_ssl_clicert_owner, pkcs12_parse): New functions. ------------------------------------------------------------------------ r325 | joe | 2004-10-19 13:39:34 +0100 (Tue, 19 Oct 2004) | 8 lines * src/ne_xml.c (invalid_ncname): Factor out macro for NCName checking. (declare_nspaces): Use invalid_ncname macro. Don't compare 'xmlns' case-insensitively. (expand_qname): Use invalid_ncname macro. * test/xml.c (fail_match): Skip correct checks for the time being. ------------------------------------------------------------------------ r324 | joe | 2004-10-17 21:32:44 +0100 (Sun, 17 Oct 2004) | 7 lines * src/ne_gnutls.c (oid_find_highest_index): New function. (append_rdn): Use oid_find_highest_index to find all RDNs using given OID. (ne_ssl_readable_dname): Add #if'd out better code which can be used once GnuTLS bugs are fixed. (check_identity): Use oid_find_highest_index. ------------------------------------------------------------------------ r323 | joe | 2004-10-17 21:07:29 +0100 (Sun, 17 Oct 2004) | 7 lines * test/openssl.conf [reqDN.twoOU]: New section. * test/makekeys.sh: Produce a twoou.cert certificate with two OU fields. * test/ssl.c (dname_readable): Test for printing of certificate with two OU fields. ------------------------------------------------------------------------ r322 | joe | 2004-10-17 19:18:20 +0100 (Sun, 17 Oct 2004) | 8 lines * test/utils.c (serve_infinite): Move from props.c * test/props.c (serve_infinite): Remove function. * test/request.c (serve_infinite_folds, serve_infinite_headers): Remove functions. (unbounded_headers, unbounded_folding): Adjust to use serve_infinite. ------------------------------------------------------------------------ r321 | joe | 2004-10-17 19:08:55 +0100 (Sun, 17 Oct 2004) | 3 lines * src/ne_request.c (debug_dump_request): Revert part of previous change: only print unsanitized request to debug channel by default. ------------------------------------------------------------------------ r320 | joe | 2004-10-17 19:07:06 +0100 (Sun, 17 Oct 2004) | 3 lines * src/ne_request.c (debug_dump_request): Only jump through request-sanitization debug hoops if really necessary. ------------------------------------------------------------------------ r319 | joe | 2004-10-17 18:58:31 +0100 (Sun, 17 Oct 2004) | 4 lines * src/ne_request.c (read_response_block): Update comments, style. Remove unnecessary early return for zero-length chunk. No functional changes. ------------------------------------------------------------------------ r318 | joe | 2004-10-17 18:22:22 +0100 (Sun, 17 Oct 2004) | 1 line Fix typo. ------------------------------------------------------------------------ r317 | joe | 2004-10-17 18:19:37 +0100 (Sun, 17 Oct 2004) | 10 lines Prevent memory exhaustion in PROPFIND response parsing by a hostile server: * src/ne_props.c (struct ne_prop_result_set): Add counter field. (start_propstat, start_prop): Enforce a limit of 1024 properties per resource. * test/props.c (serve_infinite, unbounded_response, unbounded_propstats, unbounded_props): New functions. ------------------------------------------------------------------------ r316 | joe | 2004-10-17 18:06:22 +0100 (Sun, 17 Oct 2004) | 5 lines * src/ne_207.h (ne_207_start_propstat): Specify that a NULL return value means that the parse is aborted. * src/ne_207.c (start_element): Abort parsing as above. ------------------------------------------------------------------------ r315 | joe | 2004-10-17 14:06:00 +0100 (Sun, 17 Oct 2004) | 10 lines * src/ne_xml.h (ne_xml_parse): Returns an error if parsing fails. (ne_xml_failed): Redefine in terms of ne_xml_parse return value. * src/ne_xml.c (ne_xml_parse): Return p->failure. (ne_xml_parse_v): Pass through return value from ne_xml_parse. * test/xml.c (parse_match): Check ne_xml_parse() return value; handle match_chunked test mode. (matches): Test for UTF-8 BOM handling in chunked mode. ------------------------------------------------------------------------ r314 | joe | 2004-10-17 13:59:26 +0100 (Sun, 17 Oct 2004) | 2 lines * doc/ref/iaddr.xml: Document ne_iaddr_typeof. ------------------------------------------------------------------------ r313 | joe | 2004-10-17 13:53:52 +0100 (Sun, 17 Oct 2004) | 2 lines * src/ne_socket.h: Docs tweaks. ------------------------------------------------------------------------ r312 | joe | 2004-10-17 13:22:07 +0100 (Sun, 17 Oct 2004) | 7 lines * src/ne_request.c (read_response_block): Document to always close the connection on error. (ne_read_response_block): Close the connection if the reader callback fails. * test/request.c (abort_reader): Check that the connection is closed if after the abort. ------------------------------------------------------------------------ r311 | joe | 2004-10-14 21:26:59 +0100 (Thu, 14 Oct 2004) | 3 lines * INSTALL.win32, neon.mak: Update to support ENABLE_IPV6 flag. (Kai Sommerfeld). ------------------------------------------------------------------------ r310 | joe | 2004-10-14 13:11:30 +0100 (Thu, 14 Oct 2004) | 4 lines * src/ne_socket.c: Include ws2tcpip.h if USE_GETADDRINFO is defined (Kai Sommerfeld). (ne_iaddr_print): Use getnameinfo/NI_NUMERICHOST if inet_ntop is not available. ------------------------------------------------------------------------ r308 | joe | 2004-10-11 20:59:58 +0100 (Mon, 11 Oct 2004) | 21 lines Allow response body callbacks to return an error: * src/ne_request.h (ne_block_reader): Return error code. * src/ne_request.c (ne_read_response_block): Fail with -1 if a reader callback returns an error. * src/ne_xml.c (ne_xml_parse_v): Return 0 (for the moment). * src/ne_basic.c (get_to_fd): Return error. * src/ne_compress.c (gz_reader): Return 0 (mostly), or pass through. * src/ne_auth.c (auth_body_reader): Return 0. * test/compress.c (reader): Return error. * test/request.c (collector): Return 0. (abortive_reader, abort_reader): New functions. ------------------------------------------------------------------------ r307 | joe | 2004-10-10 22:11:54 +0100 (Sun, 10 Oct 2004) | 4 lines * src/Makefile.in: Pick up top_builddir from autoconf. * configure.in: Let autoconf define top_builddir. ------------------------------------------------------------------------ r303 | joe | 2004-10-10 21:47:06 +0100 (Sun, 10 Oct 2004) | 9 lines * src/ne_openssl.c (check_identity): Only match iPAddress names against the hostname used for the session rather than the server IP address. (check_certificate, populate_cert): Update callers. * test/ssl.c (fail_ssl_request): Take hostname argument, update callers. (fail_host_ipaltname): New test. ------------------------------------------------------------------------ r302 | joe | 2004-10-10 18:44:56 +0100 (Sun, 10 Oct 2004) | 2 lines * Makefile.in (distclean): Remove neon.pc. ------------------------------------------------------------------------ r301 | joe | 2004-10-09 11:38:46 +0100 (Sat, 09 Oct 2004) | 3 lines * src/ne_stubssl.c (ne_ssl_context_create): Take mode argument. (ne_ssl_context_set_verify): New function. ------------------------------------------------------------------------ r300 | joe | 2004-10-08 15:07:26 +0100 (Fri, 08 Oct 2004) | 4 lines * tests/common/tests.c (main): Print XFAIL in reverse video so it stands out better, and use a white foreground for SKIPPED so it's readable. ------------------------------------------------------------------------ r299 | joe | 2004-10-08 08:14:45 +0100 (Fri, 08 Oct 2004) | 2 lines Compress THANKS, update copyright in README and AUTHORS. ------------------------------------------------------------------------ r298 | joe | 2004-10-07 21:25:00 +0100 (Thu, 07 Oct 2004) | 6 lines * test/ssl.c (fail_bad_ipaltname): New function. * test/openssl.conf, test/makekeys.sh: Create altname6.cert. Correct altname5.cert to have a bad CN field to prevent false positives if ipAddress altnames are not handled. ------------------------------------------------------------------------ r297 | joe | 2004-10-07 20:22:56 +0100 (Thu, 07 Oct 2004) | 4 lines * src/ne_gnutls.c (read_to_datum): New function. (mmap_file, munmap_file): Remove functions. (ne_ssl_cert_read): Use read_to_datum. ------------------------------------------------------------------------ r296 | joe | 2004-10-07 14:47:20 +0100 (Thu, 07 Oct 2004) | 3 lines * macros/neon.m4 (NEON_GSSAPI): Support --without-gssapi flag to disable Negotiate support. ------------------------------------------------------------------------ r295 | joe | 2004-10-07 13:57:44 +0100 (Thu, 07 Oct 2004) | 12 lines * src/ne_gnutls.c (struct ne_ssl_dname_s): Reference the cert and subject/issuer flag. (append_rdn): New function. (ne_ssl_readable_dname): Reimplement to generate dname on the fly, using append_rdn. (ne_ssl_dname_cmp): Break. (check_identity): Check against commonName correctly. (ne_ssl_cert_write, ne_ssl_cert_export, ne_ssl_cert_digest): Remove unused variables. (populate_cert): Populate new dn structures correctly. (ne_ssl_cert_free): Don't free dnames. (ne_ssl_cert_import): Fix memory leak. ------------------------------------------------------------------------ r294 | joe | 2004-10-07 11:47:28 +0100 (Thu, 07 Oct 2004) | 2 lines * test/ssl.c (ccert_unencrypted): Fail if ne_ssl_clicert_read returns NULL. ------------------------------------------------------------------------ r293 | joe | 2004-10-07 08:13:54 +0100 (Thu, 07 Oct 2004) | 3 lines * src/ne_gnutls.c (ne_ssl_cert_import): Fix to import as DER not PEM. (ne_ssl_cert_export): Handle arbitrary length certificates. ------------------------------------------------------------------------ r292 | joe | 2004-10-07 08:06:20 +0100 (Thu, 07 Oct 2004) | 6 lines GNU TLS updates from Aleix: * src/ne_gnutls.c (match_hostname, check_identity): New functions. (ne_ssl_cert_cmp, ne_ssl_cert_digest): Simplify. (x509_get_dn): Fix buffer length handling. ------------------------------------------------------------------------ r291 | joe | 2004-10-07 08:00:15 +0100 (Thu, 07 Oct 2004) | 10 lines * src/ne_ssl.h (ne_ssl_context_set_verify): New function. (ne_ssl_context_create): Change flags argument to 'mode'. * src/ne_openssl.c (ne_ssl_context_create): Update to handle modes. (ne_ssl_context_set_verify): Implement. * src/ne_gnutls.c (ne_ssl_cert_validity): Fix date format and use correct buffers. (ne_ssl_context_set_verify): Implement. ------------------------------------------------------------------------ r290 | joe | 2004-10-06 22:46:01 +0100 (Wed, 06 Oct 2004) | 2 lines * test/socket.c: Remove OpenSSL includes (Aleix). ------------------------------------------------------------------------ r289 | joe | 2004-10-06 12:16:58 +0100 (Wed, 06 Oct 2004) | 8 lines Fix slow startup problems with GNU TLS: * src/ne_privssl.h (struct ne_ssl_context_s) [HAVE_GNUTLS]: Remove _params fields. * src/ne_gnutls.c (ne_ssl_context_create, ne_ssl_context_destroy): Don't generate temporary RSA keys or DH paramaters. ------------------------------------------------------------------------ r288 | joe | 2004-10-06 11:58:53 +0100 (Wed, 06 Oct 2004) | 3 lines * src/ne_socket.c (ne_sock_accept_ssl) [HAVE_OPENSSL]: Fix to return 0 for SSL_accept() success. ------------------------------------------------------------------------ r287 | joe | 2004-10-06 11:22:57 +0100 (Wed, 06 Oct 2004) | 3 lines * test/socket.c (read_reset, write_reset, line_closure, ssl_closure): Print socket error string for failure cases. ------------------------------------------------------------------------ r286 | joe | 2004-10-06 11:16:58 +0100 (Wed, 06 Oct 2004) | 2 lines * src/ne_socket.c (read_gnutls): Return NE_SOCK_CLOSED on EOF. ------------------------------------------------------------------------ r285 | joe | 2004-10-06 09:43:05 +0100 (Wed, 06 Oct 2004) | 8 lines Fix write handling with GNU TLS: * src/ne_socket.c (struct iofns): Redefine write semantics to allow short writes. (write_raw): Drop short write handling, return bytes written. (write_ossl, write_gnutls): Return bytes written. (ne_sock_fullwrite): Handle short writes here. ------------------------------------------------------------------------ r284 | joe | 2004-10-06 09:30:48 +0100 (Wed, 06 Oct 2004) | 31 lines Simplify and extend abstraction of SSL layer: * src/ne_privssl.h: Make ne_ssl_socket a typedef. [HAVE_GNUTLS]: Remove union cred, gnutls_session pointer. (ne__sock_sslsock): Add prototype. * src/ne_socket.h (ne_sock_accept_ssl): Replaces ne_sock_switch_ssl. Remove ne_sock_sslsock prototype. * src/ne_socket.c: Include ne_privssl.h later. (readable_ossl, error_ossl, write_ossl, readable_gnutls, error_gnutls, read_gnutls, write_gnutls, ne_sock_connect_ssl): Adjust for ne_ssl_socket change. (ne__sock_sslsock): Rename from ne_sock_sslsock. (ne_sock_accept_ssl): New function. (ne_sock_switch_ssl): Remove function. * src/ne_ssl.h (ne_ssl_context_create): Take flags argument. (ne_ssl_context_keypair): New prototype. (ne_ssl_context_trustcert): Renamed from ne_ssl_ctx_trustcert. * src/ne_openssl.c (ne_ssl_context_create): Take flags. (ne_ssl_context_keypair): Implement. (ne__negotiate_ssl): Adjust to use ne__sock_sslsock. * src/ne_gnutls.c (ne_ssl_context_create): Take flags, adjust for ctx->cred change. (ne_ssl_context_keypair): Implement. * test/socket.c (init_ssl): Switch to use ne_ssl_context for the server context rather than OpenSSL directly. ------------------------------------------------------------------------ r283 | joe | 2004-10-06 09:15:30 +0100 (Wed, 06 Oct 2004) | 2 lines * src/Makefile.in: Add deps for ne_gnutls.lo. ------------------------------------------------------------------------ r282 | joe | 2004-10-05 21:50:01 +0100 (Tue, 05 Oct 2004) | 3 lines * test/socket.c (serve_reset): New function. (write_reset, read_reset): Use it. ------------------------------------------------------------------------ r281 | joe | 2004-10-05 21:22:35 +0100 (Tue, 05 Oct 2004) | 1 line Suffer the aclocal noise for the time being. ------------------------------------------------------------------------ r280 | joe | 2004-10-05 21:21:40 +0100 (Tue, 05 Oct 2004) | 11 lines Continued work on GNU TLS support, from Aleix Conchillo Flaque: * src/ne_gnutls.c (ne__negotiate_ssl): Rename from ne_negotiate_ssl. * src/ne_socket.c [HAVE_GNUTLS] (init_ssl): Call gnutls_global_init. (ne_sock_exit): Call gnutls_global_deinit. (check_alert, readable_gnutls, error_gnutls, read_gnutls, write_gnutls): New functions. (ne_sock_switch_ssl, ne_sock_connect_ssl, ne_sock_close): Add GNU TLS specific implementations. ------------------------------------------------------------------------ r279 | joe | 2004-10-05 21:12:19 +0100 (Tue, 05 Oct 2004) | 6 lines CygWin fixes: * src/ne_socket.c (NE_ISRESET): Treat ECONNABORTED like ECONNRESET. (ne_sock_connect): Don't compare fd numbers to FD_SETSIZE on Win32, do use ne_close(). ------------------------------------------------------------------------ r275 | joe | 2004-10-04 22:46:13 +0100 (Mon, 04 Oct 2004) | 6 lines * src/ne_request.c (ne_begin_request): Don't treat 205 like 204, per http-wg clarification: http://lists.w3.org/Archives/Public/ietf-http-wg/2004JulSep/0081.html * test/request.c (no_body_205): Remove test. ------------------------------------------------------------------------ r274 | joe | 2004-10-04 22:20:31 +0100 (Mon, 04 Oct 2004) | 17 lines Begin integration of GNU TLS support from Aleix Conchillo Flaque: * macros/neon.m4 (NE_CHECK_OPENSSLVER): Renamed from NE_CHECK_SSLVER. (NEON_SSL): Add detection support for GNU TLS. Define HAVE_GNUTLS or HAVE_OPENSSL as appropriate. * src/ne_utils.c (version_string): Update to include GNU TLS version string. * src/ne_privssl.h (HAVE_GNUTLS): Add alternative private structure definitions. * src/ne_auth.c (get_cnonce): Adjust to use HAVE_OPENSSL rather than NE_HAVE_SSL. * src/ne_gnutls.c: New file. ------------------------------------------------------------------------ r273 | joe | 2004-10-04 21:56:57 +0100 (Mon, 04 Oct 2004) | 3 lines * src/ne_socket.c (ne_sock_connect): Use htons not ntohs (Aleix Conchillo Flaque). ------------------------------------------------------------------------ r270 | joe | 2004-10-02 23:26:42 +0100 (Sat, 02 Oct 2004) | 1 line Add clog to svn:ignore. ------------------------------------------------------------------------ r269 | joe | 2004-10-02 23:25:13 +0100 (Sat, 02 Oct 2004) | 7 lines Merge r266, r267 from 0.24.x branch: * config.hw.in: Define HAVE_SETSOCKOPT to enable Nagle on Windows. * macros/neon.m4: Check for socket() in ws2_32 for CygWin. ------------------------------------------------------------------------ r268 | joe | 2004-10-02 23:19:52 +0100 (Sat, 02 Oct 2004) | 1 line Convert .cvsignore to svn:ignore. ------------------------------------------------------------------------ r256 | joe | 2004-10-02 20:38:59 +0100 (Sat, 02 Oct 2004) | 1 line Merge trunk up to current neon CVS HEAD. ------------------------------------------------------------------------ r255 | joe | 2004-10-02 20:34:48 +0100 (Sat, 02 Oct 2004) | 1 line Branch trunk from 0.24.4 on 0.24.x branch. ------------------------------------------------------------------------ r251 | joe | 2004-10-02 20:31:06 +0100 (Sat, 02 Oct 2004) | 1 line Import neon-0.24.4. ------------------------------------------------------------------------ r249 | joe | 2004-10-02 20:29:59 +0100 (Sat, 02 Oct 2004) | 1 line Import neon-0.24.3. ------------------------------------------------------------------------ r247 | joe | 2004-10-02 20:25:57 +0100 (Sat, 02 Oct 2004) | 1 line Import neon-0.24.2. ------------------------------------------------------------------------ r244 | joe | 2004-10-02 20:15:53 +0100 (Sat, 02 Oct 2004) | 1 line Import neon-0.24.1. ------------------------------------------------------------------------ r243 | joe | 2004-10-02 19:47:02 +0100 (Sat, 02 Oct 2004) | 2 lines Import neon 0.24.0 to begin 0.24.x branch. ------------------------------------------------------------------------ davix-R_0_5_0/deps/libneon/ChangeLog.CVS000066400000000000000000000531771257152637300200670ustar00rootroot00000000000000Mon May 17 21:25:44 2004 Joe Orton * neon.mak: Fix for handling of paths with spaces, and simplify (Jon Foster ). Thu May 13 11:42:07 2004 Joe Orton * configure.in: Don't rely on echo -n in ne_version. Sun Feb 22 20:29:04 2004 Joe Orton * configure.in: Move memleak.h include to end of config.h. Sun Feb 22 18:44:55 2004 Joe Orton * configure.in: Fix to run DAV tests when an XML parser is configured. Sat Jan 24 17:50:52 2004 Joe Orton * configure.in: AC_DEFINE _GNU_SOURCE again so that it's used during compiler checks. Sat Jan 24 17:33:54 2004 Joe Orton * configure.in: Cleanup; move all AC_SUBSTs together; use a single AH_TOP for config.h.in header; require autoconf 2.58. Thu Jan 1 17:40:34 2004 Joe Orton * neon-config.in: Handle 'lfs' feature. Sat Nov 15 09:42:40 2003 Joe Orton * neon-config.in: Print help output on stderr for unknown arguments. (usage): Update help output for new NE_FLAG_ substitutions. Sat Nov 15 09:24:49 2003 Joe Orton * configure.in: Update for use latest autoconf best-practice: s/AC_HELP_STRING/AS_HELP_STRING. Fri Nov 14 11:28:24 2003 Joe Orton * configure.in, neon-config.in: Use new NE_FLAG substitutions for feature detection. Fri Nov 14 09:08:10 2003 Joe Orton * configure.in: Add -export-symbols-regex to NEON_LINK_FLAGS to prevent export of ne__ symbols where possible. Sun Oct 26 12:42:15 2003 Joe Orton * neon-config.in: Fix to exit with failure for an unrecognized option. Sat Oct 25 10:37:59 2003 Joe Orton * configure.in: Use AC_LIBTOOL_TAGS if available. Mon Sep 22 20:56:21 2003 Joe Orton * Makefile.in: Respect @datadir@ from configure (Max Bowsher). Sun Sep 14 11:13:36 2003 Joe Orton * configure.in: Run NEON_TEST before LIBNEON_SOURCE_CHECKS, to help prevent time_t format string detection failing due to changed CFLAGS. Fri Jun 20 17:51:05 2003 Joe Orton * configure.in, neon-config.in: Don't pass user-supplied CPPFLAGS through to neon-config, it is no longer necessary. Sun Apr 6 19:51:31 2003 Joe Orton * doc/manual.xml: Include clicert reference docs. * doc/ref/clicert.xml: New file. Sun Apr 6 19:24:47 2003 Joe Orton * Makefile.in (XMLTO): New variable. (docs-man, docs-pdf, docs-ps, docs-html): Use $(XMLTO) variable. Wed Mar 26 20:09:12 2003 Joe Orton * Makefile.in (DIST_HEADERS): Add ne_tls.h * neon.mak: Build ne_openssl.obj for SSL build, ne_stubssl.obj for non-SSL build. Sun Mar 9 10:38:36 2003 Joe Orton * configure.in: Set ALLOW_INSTALL=yes early to allow later overrides. * Makefile.in (install-yes): Remove dependence on subdirs. (install-lib): Depend on subdirs; don't install neon.pc. (install-config): Install neon.pc here. Sat Mar 1 21:50:17 2003 Joe Orton * Makefile.in (cover): New target. Sat Mar 1 20:39:32 2003 Joe Orton * configure.in: Add --enable-memleak argument; if enabled, have config.h include memleak.h, add top_srcdir/src to include path, and substitute ALLOW_INSTALL as 'memleak'. Otherwise, substitute ALLOW_INSTALL as 'yes'. * Makefile.in (install): Use install-@ALLOW_INSTALL@. (install-yes): Renamed from install. (install-memleak): Prevent installation with non-standard ABI. Fri Dec 27 15:15:54 2002 Joe Orton * neon.pc.in: New file. * configure.in: Generate neon.pc. * Makefile.in (install-lib): Install neon.pc Tue Nov 19 11:24:40 2002 Joe Orton * configure.in: Use NEON_TEST before NEON_XML_PARSER to prevent problems if NEON_XML_PARSER adds anything to CPPFLAGS which breaks gcc -Werror (e.g. -I/usr/local/include). Sat Sep 21 12:29:56 2002 Joe Orton * neon-config.in: Add support for `--la-file' argument, to print location of libtool .la file. Sat Sep 14 12:46:21 2002 Joe Orton * configure.in: Add AC_COPYRIGHT, use AC_MSG_NOTICE for post-configure message, update for modern use of AC_CONFIG_FILES and AC_OUTPUT. Thu Aug 29 23:49:40 2002 Joe Orton Further Win32 updates from Blair Zajac: * config.hw.in: Define HAVE_ERRNO_H; fix non-SSL build. * neon.mak: Fix to build DAV sources if EXPAT_FLAGS is set but not EXPAT_SRC. Sun Aug 25 23:37:59 2002 Joe Orton Win32 updates from Blair Zajac : * neon.mak: Fix expansion of $(LIB32_OBJS) variable that was causing nmake failures. Allow non-DAV build if EXPAT_SRC is not specified. * config.hw.in: Remove hard-coded defines. * INSTALL.win32: Overhaul. Sat Aug 10 10:42:09 2002 Joe Orton * configure.in: Substitue OPENSSL into Makefiles as an absolute path. Fri Aug 9 20:45:01 2002 Joe Orton * configure.in: Update to use modern three-argument AC_INIT and AC_CONFIG_SRCDIR. Pick up version string from .version; thanks to Greg Stein for they `esyscmd' trick. Move NEON_WITH_LIBS earlier. Use AC_HELP_STRING for --disable-webdav. Fri Aug 9 20:41:24 2002 Joe Orton * config.hw.in, neon.mak, INSTALL.win32: Win32 build update from Gerald Richter: add optional NEON_NODAV and OPENSSL_STATIC flags, update locations of includes and libraries. Sun Jun 30 11:08:56 2002 Joe Orton * neon.mak: Enable WIN32_LEAN_AND_MEAN etc, to prevent X509_NAME definition conflicting with OpenSSL headers in recent versions of Platform SDK (Branko ibej). Thu Jun 13 20:35:43 2002 Joe Orton * configure.in: Call NEON_WITH_LIBS for --with-libs option. Tue Jun 4 13:27:48 2002 Joe Orton * neon.mak: Always build ne_compress.obj; patch from Branko ibej. Tue Jun 4 09:38:24 2002 Joe Orton * Makefile.in (man1dir, man3dir): Use $(mandir). (Rodney Dawes) Mon Jun 3 20:47:14 2002 Joe Orton * Makefile.in (install-html, install-man): Fix for VPATH builds. Sat May 25 15:01:18 2002 Joe Orton * configure.in: Only enable SSL tests if an `openssl' binary is found in $PATH. Thu May 23 20:31:01 2002 Joe Orton * configure.in: Require a release version of autoconf. Sat May 18 14:43:15 2002 Joe Orton * Makefile.in (docs-man): Use customisation layer. Sat Apr 13 22:34:00 2002 Joe Orton * configure.in, neon-config.in: Pass LDFLAGS and CPPFLAGS setting given to configure through to neon-config --libs/--cflags output. Mon Feb 25 20:53:28 2002 Joe Orton * neon.mak (OPENSSL_FLAGS): Define NEON_SSL not ENABLE_SSL (Branko). Mon Feb 25 20:46:04 2002 Joe Orton * config.hw.in: Add NE_FMT_OFF_T (Dan Berlin, Branko ibej). Sun Feb 10 20:35:55 2002 Joe Orton * Makefile.in (docs-html): Use XSL customisation layer for the HTML output. Wed Feb 6 00:42:32 2002 Joe Orton * configure.in: Require autoconf 2.52d for AC_C_BIGENDIAN which supports cross-compiling. Sat Jan 26 11:19:39 2002 Joe Orton * configure.in: Define TESTS and HELPERS appropriately for whether DAV, SSL, zlib are supported. Sat Jan 26 11:03:38 2002 Joe Orton * neon.mak: Add OpenSSL, zlib support (Branko ibej). Sat Jan 26 00:15:29 2002 Joe Orton * neon.dsp, neon.dsw: Removed per advice from Branko. Thu Jan 24 21:02:02 2002 Joe Orton * Makefile.in (check): Run check target in test subdir. (subdirs): Remove redundant subshell. (distclean): Clean harder. Thu Jan 24 20:46:28 2002 Joe Orton * neon.mak: Remove sslcerts.c from build. Sun Jan 20 12:51:27 2002 Joe Orton * configure.in: Create test/common for vpath build. Tue Jan 8 21:35:12 2002 Joe Orton * neon.mak: Rewritten by Branko ibej . * config.hw.in: Update from Branko ibej. Thu Jan 3 08:48:00 2002 Joe Orton * Makefile.in (neon-config): Add target. Thu Jan 3 08:47:06 2002 Joe Orton * neon-config.in (libs): Don't print -L/usr/lib or -L/lib. Thu Jan 3 08:43:08 2002 Joe Orton * configure.in: Make neon-config executable in the build tree. Mon Dec 17 22:54:00 2001 Joe Orton * Makefile.in (install-lib, install-headers, install-config): Support DESTDIR; patch from Pawel Golaszewski . Sat Oct 27 12:23:57 2001 Joe Orton * neon-config.in: Add "--support FEATURE" option; the script exits with success if given FEATURE is supported. Sat Oct 6 13:11:57 2001 Joe Orton * configure.in: Require autoconf 2.50. Use AC_HELP_STRING. Sun Sep 30 23:44:56 2001 Joe Orton * configure.in, neon-config.in: Clean up handling of cflags/libs exporting. Sat Sep 29 12:45:25 2001 Joe Orton * Makefile.in: Add Makefile re-generation target, have clean recurse into test too, have check depend on subdirs, distribute ne_compress.h. Tue Sep 25 07:34:32 2001 Mo DeJong * configure.in: Move check for signal.h into LIBNEON_SOURCE_CHECKS. Mon Sep 24 20:28:26 2001 Joe Orton * autogen.sh: Bomb out on errors (set -e). Mon Sep 24 20:20:08 2001 Joe Orton * autogen.sh: Clean up, use libtoolize. * ltmain.sh: Removed from CVS. Mon Sep 24 20:17:18 2001 Joe Orton * configure.in: Use three-argument AC_DEFINE for _GNU_SOURCE (Mo DeJong). Tue Sep 11 23:20:23 2001 Joe Orton * config.hw.in: Define USE_DAV_LOCKS. Mon Aug 13 21:07:28 2001 Joe Orton * neon.mak: Add support for SSL (Peter Boos). Sat Jun 30 12:22:17 2001 Joe Orton * configure.in: Add NEONLIBS to LIBS, so that the depedencies are added to the link line. This means they are picked up as references in the .so, and also listed in the libtool .la file. Tue Jun 12 13:02:58 2001 Joe Orton * config.hw.in: Renamed from config.hw, and have version substituted in when tarball is rolled. Adjust for XML parser changes. (Gerald Richter) Sun Jun 10 16:41:46 2001 Joe Orton * configure.in: Check for pipe() for tests, use NEON_DEBUG. Fri Jun 8 22:57:24 2001 Joe Orton * config.hw: Fixes from Gerald Richter . * neon.mak, INSTALL.win32: New files from Gerald Richter. Thu May 31 00:00:32 2001 Joe Orton * configure.in: Disable shared library build by default. Use NE_DEBUGGING rather than DEBUGGING. Check for 'usleep' for tests. Sun Apr 29 16:41:17 2001 Joe Orton * configure.in: Produce test/Makefile. Wed Mar 14 22:51:28 2001 Joe Orton * Makefile.in (DIST_HEADERS): Add http_auth.h Wed Mar 14 22:45:51 2001 Joe Orton * configure.in: Build bundled directory regardless of --disable-webdav. Sun Feb 25 17:00:40 2001 Joe Orton * configure.in: Rename NEON_IS_BUNDLED to NEON_BUILD_BUNDLED. Sun Feb 25 16:53:28 2001 Joe Orton * configure.in: Set NEON_IS_BUNDLED to "yes". Sat Feb 24 00:09:57 2001 Joe Orton * configure.in: Add --disable-webdav flag to disable WebDAV support. Set NEON_NEED_XML_PARSER=yes if DAV is not disabled. Sun Jan 28 23:10:39 2001 Joe Orton * Makefile.in: Remove neon_config.h from DIST_HEADERS. Sun Jan 28 10:41:40 2001 Joe Orton * configure.in: Don't produce neon_config.h. Tue Jan 23 23:16:25 2001 Joe Orton * configure.in: Moved version defns into NEON_VERSIONS macros. Produce src/neon_config.h. Tue Jan 16 20:16:47 2001 Joe Orton * configure.in: Bumped version to 0.10.1. Mon Jan 15 22:59:47 2001 Joe Orton * configure.in: Bumped version to 0.10.0. Sun Jan 14 23:55:47 2001 Joe Orton * Makefile.in (distclean): Don't remove neon_config.h. (install): Depend on subdirs. Wed Jan 10 22:46:53 2001 Joe Orton * configure.in: Use NEON_LINK_FLAGS to pass through -version-info and interface version flags. Add -I${top_builddir} to CFLAGS. Remove NEONOBJS declaration, let NEON_LIBTOOL_BUILD do it. Wed Dec 20 00:11:56 2000 Joe Orton * configure.in: Bumped version to 0.9.1, interface version to 9:1:0. Tue Dec 19 22:15:45 2000 Joe Orton * Makefile.in: Build using recursive make into src directory. Add VPATH support. (Mo DeJong ) Tue Dec 19 22:13:40 2000 Joe Orton * configure.in: Build using new src/Makefile.in. Sun Dec 17 19:53:36 2000 Joe Orton * config.sub, config.guess, ltconfig, ltmain.sh: Update to libtool 1.3.5 versions. Sun Dec 17 18:43:00 2000 Joe Orton * Makefile.in: Remove all traces of example programs. Fix uritest. Thu Dec 14 21:47:48 2000 Joe Orton * configure.in: Bumped version to 0.8.0, interface version to 8:0:0. Thu Dec 14 20:57:49 2000 Joe Orton * configure.in: Removed configuration of examples. Wed Dec 13 20:14:53 2000 Joe Orton * config.hw: Added for Windows. Sun Nov 26 09:52:29 2000 Joe Orton * example/: Removed directory (now in separate neon-examples package). Tue Sep 12 10:33:50 2000 Joe Orton * Makefile.in: Remove sitecopy bits which somehow got left in there. Tue Sep 12 00:41:49 2000 Joe Orton * configure.in: Bumped version to 0.7.3, interface version to 7:1:1. Tue Sep 12 00:39:49 2000 Joe Orton * Makefile.in (distclean): New target. Thu Sep 7 00:14:15 2000 Joe Orton * configure.in: Bumped version to 0.7.2, interface version to 7:0:1. Thu Sep 7 00:10:54 2000 Joe Orton * Makefile.in: Added 'all' target (patch by Greg Stein ). Sun Sep 3 10:32:09 2000 Joe Orton * Makefile.in (SHELL): Added definition. Changed xalloc.h to ne_alloc.h in DIST_HEADERS. Thanks to Eric Mumpower . Tue Aug 15 21:53:37 2000 Joe Orton * configure.in: Bumped version to 0.7.1, interface version to 6:1:1. Mon Aug 14 09:28:47 2000 Joe Orton * configure.in: Bumped version to 0.7.0, interface version to 6:0:0. Sun Aug 13 15:59:58 2000 Joe Orton * configure.in: Bumped version to 0.6.1, interface version to 5:1:1. Sat Aug 12 17:10:09 2000 Joe Orton * configure.in: Bumped version to 0.6.0, interface version to 5:0:1. Sat Aug 12 17:08:54 2000 Joe Orton * configure.in: Add --with-extra-includes and --with-extra-libs configure parameters Sat Aug 12 17:07:22 2000 Joe Orton * example/nget.c (redirect_notify): New function. (main): Support automatic redirects. Sat Aug 12 16:53:50 2000 Joe Orton * Makefile.in: Build http_redirect.lo. Sat Aug 12 14:43:28 2000 Joe Orton * example/nget.c (pretty_progress_bar): Use 'off_t' not size_t arguments. Sat Aug 12 02:11:05 2000 Joe Orton * configure.in: Bumped interface version to 4:1:0, version to 0.5.1. Fri Aug 11 17:18:19 2000 Joe Orton * configure.in: Bumped interface version to 4:0:0, version to 0.5.0. Fri Jul 28 13:35:06 2000 Joe Orton * configure.in: Bumped interface version to 3:2:1, version to 0.4.2. Fri Jul 28 11:26:18 2000 Joe Orton * configure.in: Bumped interface version to 3:1:1, version to 0.4.1. Fri Jul 28 11:25:05 2000 Joe Orton * example/nget.c: Include nsocket.h not socket.h. Fri Jul 28 10:31:50 2000 Joe Orton * configure.in: Bumped interface version to 3:0:1. Bumped version to 0.4.0. Thu Jul 27 22:01:11 2000 Joe Orton * Makefile.in: Install nsocket.h not socket.h. Thu Jul 27 21:59:45 2000 Joe Orton * configure.in: Tell neon-config that header files are in $(includedir)/neon. Use NEON_WARNINGS macro for compiler warnings. Thu Jul 20 19:20:23 2000 Joe Orton * Makefile.in: Install headers into $(includedir)/neon rather libneon. Add dav_locks.h, xalloc.h, neon_md5.h, neon_i18n.h to list of headers installed. Mon Jul 17 09:11:46 2000 Joe Orton * configure.in: Bumped version to 0.3.1, interface version to 2:0:1. Sun Jul 16 18:47:47 2000 Joe Orton * configure.in: Bumped version to 0.3.0. Sun Jul 16 17:17:51 2000 Joe Orton * Makefile.in (nbrowse, nserver, debug-nserver, debug-nbrowse): Added targets. Sun Jul 16 17:15:08 2000 Joe Orton * example/nget.c (main): Updated for new SSL interface. Sun Jul 16 16:51:16 2000 Joe Orton * configure.in: Added --enable-gnome-examples switch. Sun Jun 18 12:56:00 2000 Joe Orton * example/nserver.c: New file. Sun Jun 18 12:54:43 2000 Joe Orton * example/nbrowse.glade: Added Glade project file. Sun Jun 18 12:51:56 2000 Joe Orton * example/nbrowse/main.c, example/nbrowse/interface.c, example/nbrowse/callbacks.c, example/nbrowse/support.c: Added files from Glade. Thu May 25 01:04:11 2000 Joe Orton * configure.in: Bumped NEON_INTERFACE_VERSION to 1:0:0. With --enable-warnings, only include -Wstrict-prototypes if we're not building with SSL support. Thu May 25 01:01:01 2000 Joe Orton * Makefile.in: Pass --quiet to libtool to make it a bit less chatty. (again, debug-nget): New target. Tue May 23 17:14:43 2000 Joe Orton * example/nget.c (main): Use http_session_create/destroy. Quit if http_set_secure fails. Tue May 23 15:35:16 2000 Joe Orton * example/nget.c (parse_args, conn_notify): New functions. (main): Call neon_debug_init, call sock_init. Register conn_notify. If scheme is "https", use a secure connection. Tue May 23 14:14:05 2000 Joe Orton * example/nget.c (parse_args): New function. (main): Sun May 21 23:54:48 2000 Joe Orton * neon-config.in: Use @NEON_LIBDIR@ not -L@libdir@ in --libs output. Sun May 21 23:53:41 2000 Joe Orton * configure.in: Call NEON_SSL macro, add LDFLAGS to NEON_LIBDIR to pick up OpenSSL library location. Sat May 20 21:47:54 2000 Joe Orton * example/nget.c: Include neon_config.h for NEON_VERSION declaration. Sat May 20 21:47:29 2000 Joe Orton * configure.in: Added --enable-warnings parameter. Sat May 20 21:46:54 2000 Joe Orton * Makefile.in (libneon.la): Fixed passing interface version. Sun May 14 00:40:38 2000 Joe Orton * configure.in (NEON_VERSION): Bumped to 0.2.0. Sun May 14 00:28:33 2000 Joe Orton * Makefile.in (install-config): New goal. Sun May 14 00:26:00 2000 Joe Orton * configure.in: Added --enable-debugging argument. Added NEON_LIBDIR, NEON_INCLUDEDIR, NEON_LIBS, NEON_CFLAGS for neon-config. Produce neon-config from neon-config.in. * neon-config.in: New file, modified from libxml. Sat May 13 23:16:46 2000 Joe Orton * configure.in: Builed static and shared libraries by default. Sat May 13 16:32:15 2000 Joe Orton * config.sub, config.guess, ltmain.sh, ltconfig: Updated from libtool-1.3.4. Sat May 13 13:45:56 2000 Joe Orton * example/nget.c: Don't include neon.h. Sat May 13 13:44:22 2000 Joe Orton * Makefile.in: Use libtool. (install-examples): New goal. * configure.in: Define NEON_VERSION. Thu May 11 14:14:00 2000 Joe Orton * example/nget.c (main): Set user-agent. Thu May 11 14:10:24 2000 Joe Orton * ltconfig, ltmain.sh, config.sub, config.guess: Added libtool support files. * configure.in: Call AC_PROG_LIBTOOL and AC_DISABLE_STATIC. * .cvsignore: Added libtool. Wed May 10 19:17:24 2000 Joe Orton * configure.in: Print configuration message, check for ranlib. Wed May 10 19:16:43 2000 Joe Orton * example/nget.c (main): Allow output to stdout. Wed May 10 19:15:56 2000 Joe Orton * Makefile.in: Added shared, install* targets Wed May 10 17:47:30 2000 Joe Orton * example/nget.c (pretty_progress_bar): New function, from cadaver. Wed May 10 14:42:45 2000 Joe Orton * example/nget.c: New file. Wed May 10 14:41:39 2000 Joe Orton * configure.in, Makefile.in, .cvsignore, install-sh: New files. davix-R_0_5_0/deps/libneon/INSTALL.win32000066400000000000000000000101421257152637300176360ustar00rootroot00000000000000Building neon on Windows uses a single Nmake neon.mak file. By placing various parameters on nmake's command line, you can specify exactly the features and behavior of the Neon libraries. The parameters are additive, so to add more features, add the command line options specified in the particular section below. All the builds described below should work with Microsoft VC++ 5 and 6. Build neon __________ This is the most basic version of the Neon library you can build. It does not require any third party libraries, but you do not get the full capabilities of Neon. Compile Neon with no parameters nmake /f neon.mak After compiling the library, the directory contains libneon.lib, against which you can link your program. Build neon with WebDAV support ______________________________ To compile Neon with WebDAV support, Neon must compile and link against a third-party XML parser, either expat, expat-lite, libxml or libxml2. This Windows neon.mak file is designed to compile and link against the pre-built Expat Windows libraries version 1.95.X or newer. This library is available for download from http://sourceforge.net/projects/expat/ Download the latest expat_win32bin package named expat_win32bin_X_YY_Z.exe and install it on your system. It wants to install itself into Q:\some\dir\Expat-X.Y.ZZ. Choose your installation location for expat and then compile Neon with nmake /f neon.mak EXPAT_SRC=\path\to\Expat-X.YY.Z NOTE: When you run your program make sure the LIBEXPAT.DLL from expat is accessible, i.e. is in your PATH. This should work with Microsoft VC++ 5 and 6. Build neon with dynamically linked SSL support ______________________________________________ To build neon on Windows with SSL support you need OpenSSL already installed on your system (I used OpenSSL 0.9.7g). It can be downloaded from http://www.openssl.org/source/openssl-0.9.7g.tar.gz After compiling OpenSSL, now simply point make to the OpenSSL sources: nmake /f neon.mak OPENSSL_SRC=\path\to\openssl NOTE: The include files for OpenSSL reside in inc32/ directory ("../openssl-0.9.7g/inc32"). NOTE: Make sure that your program is linked against libeay32.lib and ssleay32.lib (normally in "../openssl-0.9.7g/out32dll") and that libeay32.dll and ssleay32.dll is accessible, i.e. is in your PATH. Build neon with statically linked OpenSSL support _________________________________________________ If you want to statically link against OpenSSL, then add the OPENSSL_STATIC parameter. nmake /f neon.mak OPENSSL_SRC=\path\to\openssl OPENSSL_STATIC=yes Build neon with statically linked Zlib support ______________________________________________ If you want to build Neon with the capability to decompress compressed content, then you need to compile against the Zlib library. Neon's neon.mak file will compile and link the Zlib sources. You need Zlib 1.2.1 or later, as previous versions do not include build scripts for Win32. Here's how to compile in Zlib support. 1) Get one of the Zlib source file packages in Zip format from http://www.gzip.org/zlib/; for example, http://www.gzip.org/zlib/zlib121.zip 2) Unzip it. Now add the ZLIB_SRC parameter to Neon's neon.mak pointing to your newly compiled zlib. nmake /f neon.mak ZLIB_SRC=\path\to\zlib Build neon with dynamically linked Zlib support _______________________________________________ To build Neon with dynamically linked Zlib support, use the instructions for the statically linked Zlib support above and add the ZLIB_DLL parameter nmake /f neon.mak ZLIB_SRC=\path\to\zlib ZLIB_DLL=yes Build neon with IPv6 support ____________________________ To build neon with support for IPv6, use parameter ENABLE_IPV6. nmake /f neon.mak ENABLE_IPV6=yes This requires a copy of the Platform SDK which contains the IPv6 headers and libraries. Build neon with debugging support _________________________________ Set the DEBUG_BUILD parameter nmake /f neon.mak DEBUG_BUILD=yes It does not matter what value DEBUG_BUILD is set to, as long as it is not set to "". After compiling the library, the directory contains libneonD.lib, against which you can link your program. davix-R_0_5_0/deps/libneon/Makefile.in000066400000000000000000000143321257152637300177160ustar00rootroot00000000000000# Copyright (C) 2001-2009 Joe Orton # Copyright (C) 1994, 1995-8, 1999, 2000 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # libtool bits mostly stolen from libxml and libtool/demo SHELL = @SHELL@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ mandir = @mandir@ man1dir = $(mandir)/man1 man3dir = $(mandir)/man3 datarootdir = @datarootdir@ datadir = @datadir@ docdir = $(datadir)/doc/neon-@NEON_VERSION@ includedir = @includedir@ neonincludes = $(includedir)/neon pkgconfigdir = $(libdir)/pkgconfig localedir = $(datadir)/locale top_srcdir = @top_srcdir@ top_builddir = . srcdir = @srcdir@ VPATH = @srcdir@ @SET_MAKE@ LDFLAGS = -L. @LDFLAGS@ LIBS = @LIBS@ CC = @CC@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL = @INSTALL@ transform = @program_transform_name@ LIBTOOL = @LIBTOOL@ XMLTO = xmlto GCOV = gcov XGETTEXT_OPTS = --keyword=_ --keyword=N_ --msgid-bugs-address=neon@lists.manyfish.co.uk \ --default-domain=neon --flag ne_print_request_header:3:c-format \ --flag ne_snprintf:3:c-format --flag ne_vsnprintf:3:c-format \ --flag ne_set_error:2:c-format POTFILE = $(top_srcdir)/po/neon.pot XGETTEXT = xgettext MSGFMT = msgfmt MSGMERGE = msgmerge LINGUAS = @ALL_LINGUAS@ # The headers to distribute - making up the public interface of neon DIST_HEADERS = ne_request.h ne_session.h ne_utils.h ne_uri.h ne_socket.h \ ne_basic.h ne_207.h ne_props.h ne_xml.h ne_dates.h ne_string.h \ ne_defs.h ne_locks.h ne_alloc.h ne_md5.h ne_i18n.h ne_redirect.h \ ne_auth.h ne_compress.h ne_acl.h ne_ssl.h ne_xmlreq.h ne_pkcs11.h \ ne_acl3744.h all: subdirs check: subdirs @cd test && $(MAKE) check # Useful for doing coverage analysis; use e.g.: # make TESTS=string-tests MODULE=ne_string.c cover cover: subdirs @rm -f src/*.*da test/common/*.*da test/*.*da @cd test && $(MAKE) check @cd src && $(GCOV) -cb $(MODULE) # as per 'cover' target; prints list of functions without 100% coverage uncover: subdirs @rm -f src/*.*da test/common/*.*da test/*.*da @cd test && $(MAKE) check @cd src && $(GCOV) -cb $(MODULE) @grep ^function src/$(MODULE).gcov | grep -v 'executed 100' | sort -nr -k 9,9 subdirs: @cd src && $(MAKE) # Uses Tim Waugh's excellent "xmlto" utility, see # http://cyberelk.net/tim/xmlto/. (The docs target is executed at release # time before generating a .tar.gz) docs: docs-man docs-html docs-man: rm -rf doc/man; mkdir doc/man $(XMLTO) -o `pwd`/doc/man -x doc/man.xsl man doc/manual.xml docs-pdf: $(XMLTO) -o `pwd`/doc pdf doc/manual.xml docs-ps: $(XMLTO) -o `pwd`/doc ps doc/manual.xml docs-html: test -d doc/html && rm -rf doc/html || true mkdir doc/html $(XMLTO) -o `pwd`/doc/html -x doc/html.xsl html doc/manual.xml # Validate the manual source docs-valid: xmllint --noout --valid doc/manual.xml clean: @cd src && $(MAKE) clean @cd test && $(MAKE) clean distclean: clean rm -rf Makefile config.h neon.pc config.status src/Makefile libtool config.log config.cache neon-config autom4te*.cache test/Makefile again: clean Makefile: $(srcdir)/Makefile.in @./config.status Makefile neon-config: $(srcdir)/neon-config.in @./config.status neon-config install-docs: install-man install-html install-html: $(INSTALL) -d $(DESTDIR)$(docdir)/html for d in $(srcdir)/doc/html/*.html; do \ $(INSTALL_DATA) $$d $(DESTDIR)$(docdir)/html; \ done install-man: $(INSTALL) -d $(DESTDIR)$(man3dir) $(INSTALL) -d $(DESTDIR)$(man1dir) for m in $(srcdir)/doc/man/*.3; do \ $(INSTALL_DATA) $$m $(DESTDIR)$(man3dir); done for m in $(srcdir)/doc/man/*.1; do \ $(INSTALL_DATA) $$m $(DESTDIR)$(man1dir); done install: install-@ALLOW_INSTALL@ install-memleak: @echo "ERROR: The neon internal memory leak checking code is for testing" @echo "ERROR: purposes only; this copy of neon must not be installed." @false install-yes: install-lib install-headers install-config install-docs install-nls # libtool does all the necessary magic here install-lib: subdirs $(INSTALL) -d $(DESTDIR)$(libdir) $(LIBTOOL) --mode=install $(INSTALL) src/libneon.la \ $(DESTDIR)$(libdir)/libneon.la install-headers: $(INSTALL) -d $(DESTDIR)$(neonincludes) @for h in $(DIST_HEADERS); do \ echo Installing $$h into $(DESTDIR)$(neonincludes); \ $(INSTALL_DATA) $(srcdir)/src/$$h $(DESTDIR)$(neonincludes)/$$h \ || exit 1; \ done install-config: neon-config neon.pc $(INSTALL) -d $(DESTDIR)$(bindir) @echo Installing neon-config into $(DESTDIR)$(bindir) @$(INSTALL_SCRIPT) neon-config \ $(DESTDIR)$(bindir)/`echo neon-config|sed '$(transform)'` $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) $(INSTALL_DATA) neon.pc $(DESTDIR)$(pkgconfigdir)/neon.pc install-tests: install-lib @cd test && make install install-nls: install-nls-@NE_FLAG_I18N@ install-nls-no: @echo NLS not enabled. install-nls-yes: @for f in $(LINGUAS); do \ $(INSTALL) -d $(DESTDIR)$(localedir)/$$f/LC_MESSAGES; \ $(INSTALL_DATA) $(srcdir)/po/$$f.gmo $(DESTDIR)$(localedir)/$$f/LC_MESSAGES/neon.mo; \ done ChangeLog: svn log > $@ update-po: @xgettext $(XGETTEXT_OPTS) $(top_srcdir)/src/ne*.c -o $(POTFILE) @for f in $(LINGUAS); do \ echo "> Updating \"$$f\" catalog:"; \ $(MSGMERGE) --update $(top_srcdir)/po/$$f.po $(POTFILE); \ $(MSGFMT) --output /dev/null --check-format $(top_srcdir)/po/$$f.po || exit 1; \ done compile-gmo: @for f in $(LINGUAS); do \ echo "> Compiling \"$$f\" catalog:"; \ $(MSGFMT) --statistics -c -o po/$$f.gmo $(top_srcdir)/po/$$f.po; \ done update-copyright: Makefile sed -n '/^Copyright/q;p' < README > README.orig (cat README.orig; grep -h Copyright src/*.[ch] po/*.po macros/*.m4 \ | sed -r 's/\(C\) [12].+[0-9],? /(C) /;s/^\#//;s/^dnl//;s/[ ]*//;s/ *$$//;/Orton/d' | sort -u) > README doc-status: @echo -n "Missing docs for:" @for f in `nm src/.libs/libneon.so | grep ' T ' | colrm 1 11`; do \ test -f doc/man/$$f.3 || echo -n " $$f"; \ done; echo davix-R_0_5_0/deps/libneon/NEWS000066400000000000000000001734631257152637300163630ustar00rootroot00000000000000Changes in release 0.29.6: * Don't abort SSL handshake with GnuTLS if a client cert is requested but none is configured/available (thanks to Patrick Ohly) * Fix GnuTLS build with Nettle (Arfrever Frehtes Taifersar Arahesis) * Win32: Fix handling of SSPI challenges (Ivan Zhakov) * Fix the method string passed to create_request hooks to have the same lifetime as the request object (Patrick Ohly) * Docs updates. Changes in release 0.29.5: * Fix GnuTLS handshakes failures with 'TLS warning alert' (Bryan Cain) * Further fix for SSPI support on Win32 (Danil Shopyrin) Changes in release 0.29.4: * Fix SNI support (Tobias Gruetzmacher) * Fix possible Solaris linker errors if building static library * Win32: Fix Kerberos authentication support with SSPI (Danil Shopyrin) * Fix error handling when pulling a request body from an file (thanks to Lou Montulli) * Fix ne_request_dispatch() return value for SOCKS proxy failure cases * Tighten SSL cert ID checks to deny a wildcard match against an IP address Changes in release 0.29.3: * Change ne_sock_close() to no longer wait for SSL closure alert: - fixes possible hang with IIS servers when closing SSL connection - this reverts the behaviour with OpenSSL to match 0.28.x, and changes the behaviour with GnuTLS to match that with OpenSSL * Fix memory leak with GnuTLS * API clarification in ne_sock_close(): - SSL closure handling now documented - return value semantics fixed to describe the implementation Changes in release 0.29.2: * Fix spurious 'certificate verify failed' errors with OpenSSL (Tom C) * Fix unnecessary re-authentication with SSPI (Danil Shopyrin) Changes in release 0.29.1: * Fixes for (Unix) NTLM implementation: - fix handling of session timeout (Kai Sommerfeld) - fix possible crash (basic@mozdev.org) * Build fixes for Win32: - fix use of socklen_t with recent SDKs (Stefan Kung) - fix USE_GETADDRINFO on Win2K (Kai Sommerfeld) * Fix build with versions of GnuTLS older than 2.8.0. Changes in release 0.29.0: * Interface changes: - none, API and ABI backwards-compatible with 0.28.x and 0.27.x * New interfaces and features: - added NTLM auth support for Unix builds (Kai Sommerfeld, Daniel Stenberg) - ne_auth.h: added NE_AUTH_GSSAPI and NE_AUTH_NTLM auth protocol codes - added ne_acl3744.h, updated WebDAV ACL support (Henrik Holst) - added built-in SOCKS v4/v4a/v5 support: ne_socket.h:ne_sock_proxy(), and ne_session.h:ne_session_socks_proxy() - added support for system-default proxies: ne_session_system_proxy(), implemented using libproxy where available - ne_session.h: added NE_SESSFLAG_EXPECT100 session flag, SSL verification failure bits extended by NE_SSL_BADCHAIN and NE_SSL_REVOKED, better handling of failures within the cert chain (thanks to Ludwig Nussel) - ne_utils.h: added feature code NE_FEATURE_SYSPROXY - ne_socket.h: ne_sock_writev() (Julien Reichel), ne_sock_set_error(), ne_iaddr_raw(), ne_iaddr_parse() - ne_string.h: ne_buffer_qappend(), ne_strnqdup() * Deprecated interfaces: - ne_acl.h is obsoleted by ne_acl3744.h (but is still present) - obsolete feature "NE_FEATURE_SOCKS" now never marked present * Other changes: - fix handling of "stale" flag in RFC2069-style Digest auth challenge - ne_free() implemented as a function on Win32 (thanks to Helge Hess) - symbol versioning used for new symbols, where supported - ensure SSL connections are closed cleanly with OpenSSL - fix build with OpenSSL 1.0 beta - updated Polish (pl) translation (Arfrever Frehtes Taifersar Arahesis) Changes in release 0.28.6: * SECURITY (CVE-2009-2473): Fix "billion laughs" attack against expat; could allow a Denial of Service attack by a malicious server. * SECURITY (CVE-2009-2474): Fix handling of an embedded NUL byte in a certificate subject name with OpenSSL; could allow an undetected MITM attack against an SSL server if a trusted CA issues such a cert. Changes in release 0.28.5: * Enable support for X.509v1 CA certificates in GnuTLS. * Fix handling of EINTR in connect() calls. * Fix use of builds with SOCK_CLOEXEC support on older Linux kernels. Changes in release 0.28.4: * Fix ne_forget_auth (Kai Sommerfeld) * GnuTLS support fixes: - fix handling of PKCS#12 client certs with multiple certs or keys - fix crash with OpenPGP certificate - use pkg-config data in configure, in preference to libgnutls-config * Add PKCS#11 support for OpenSSL builds (where pakchois is available) * Fix small memory leak in PKCS#11 code. * Fix build on Haiku (scott mc) Changes in release 0.28.3: * SECURITY (CVE-2008-3746): Fix potential NULL pointer dereference in Digest domain parameter support; could allow a DoS by a malicious server * Fix parsing of *-Authenticate response header with LWS after quoted value * Fix ne_set_progress(, NULL, ) to match pre-0.27 behaviour (and not crash) * Fix to disable Nagle on Win32 with newer toolchain (thanks to Stefan Kng) * Fix build on Netware (Guenter Knauf) * Document existing ne_uri_parse() API postcondition and ne_uri_resolve() pre/postconditions regarding the ->path field in ne_uri structures * Mark ne_{,buffer_}concat with sentinel attribute for GCC >= 4. * Distinguish the error message for an SSL handshake which fails after a client cert was requested. * Compile with PIC flags by default even for static library builds Changes in release 0.28.2: * Support "Proxy-Connection: Keep-Alive" for compatibility with HTTP/1.0 proxies which require persistent connections for NTLM authentication * Fix an fd leak in ne_ssl_{,cli}cert_read (GnuTLS only) * Enable fast initialization in GnuTLS. Changes in release 0.28.1: * Fix Win32 build * Fix build on SCO OpenServer 5.0.x (thanks to Nico Kadel-Garcia) * Fix handling of Digest domain parameter values without a trailing slash * Fix build against apr-util's bundled libexpat.la in Subversion * Add --without-pakchois to configure (Arfrever Frehtes Taifersar Arahesis) * zh message catalog renamed to zh_CN, translation updated (Dongsheng Song) Changes in release 0.28.0: * Interface changes: - none, API and ABI backwards-compatible with 0.27.x * New interfaces: - ne_pkcs11.h: added basic PKCS#11 support (requires GnuTLS and pakchois) - ne_auth.h: added NE_AUTH_ALL and NE_AUTH_DEFAULT constants - ne_socket.h: added ne_sock_peer(), ne_sock_prebind(), ne_sock_cipher() - ne_session.h: NE_SESSFLAG_TLSSNI flag added; TLS SNI support is enabled by default, where supported; ne_set_localaddr() added - ne_request.h: added close_conn hooks (Robert J. van der Boon) - ne_basic.h: added ne_options2() * Other changes: - add Polish (pl) translation (Arfrever Frehtes Taifersar Arahesis) - add support for the 'domain' parameter in Digest authentication - fix fd leak in ne_sock_connect() error path (Andrew Teirney) - the FD_CLOEXEC flag is set on socket fds - fix timezone handling in ne_dates for more platforms (Alessandro Vesely) - fix ne_simple_propfind() to print XML namespaces in flat property values - fix ne_get_range() for unspecified end-range case (Henrik Holst) - fix ne_strclean() to be locale-independent and avoid possible Win32 crash - fix ne_get_error() to not "clean" localized error strings - fix ne_ssl_clicert_read() to fail for client certs missing cert or key - Win32: fix build with VS 2008 (Stefan Kueng) - Win32: fix neon.mak to not double-quote $(MAKE) (Henrik Holst) - improve strength of Digest cnonces in GnuTLS builds Changes in release 0.27.2: * Fix crash in GSSAPI Negotiate response header verification (regression since 0.26.x) Changes in release 0.27.1: * Fix regression in response progress counter for notifier/progress callbacks * Fix interface description for ne_set_notifier() callback; sr.total is set to -1 not 0 for an indeterminate response length Changes in release 0.27.0: * New interfaces: - ne_session.h: ne_fill_proxy_uri() retrieves configured proxy, ne_hook_post_headers() adds a hook after response headers are read, ne_set_connect_timeout() sets session connection timeout, NE_SESSFLAG_RFC4918, NE_SESSFLAG_CONNAUTH flags added - ne_socket.h: ne_sock_connect_timeout() sets connection timeout, ne_iaddr_reverse() performs reverse DNS lookup - ne_string.h: ne_buffer_snprintf() prints to a buffer object - ne_xml.h: ne_xml_resolve_nspace() resolves namespace prefixes * Interface changes: - ne_set_notifier() replaces ne_set_status(); finer-grained and type-safe connection status information now provided; obsoletes ne_set_progress() - ne_xml_dispatch_request() now only invokes the XML parser for response entities with an XML content-type, following RFC 3023 rules - ne_acl_set() now takes a "const" entries array - LFS compatibility functions *64 removed: all functions taking an off_t now take an ne_off_t which is off64_t for LFS builds * GnuTLS support now mostly feature-complete with OpenSSL support: - greatly improved SSL distinguished name handling with GnuTLS >= 1.7.8 * Other changes: - descriptive error messages for authentication failures - SSPI support uses canonical DNS server name (Yves Martin) - fixes for handling of "stale" parameter in Digest authentication - added support for URIs in SSL server certificate subjectAltName field - fix compiler warnings with expat 2.x - fix handling of "Transfer-Encoding: identity" responses from privoxy Changes in release 0.26.4: * Fix Negotiate Authentication-Info response header verification with GSSAPI * Fix multiple handlers with ne_add_{server,proxy}_auth (Werner Baumann) * Fix SSPI build with some versions of MinGW (Gisle Vanem) * Fix for SSPI segfault in response header verification (Mike DiCuccio) * Fix error strings for CONNECT SSL proxy tunnel request failure * Fix install-nls for VPATH builds (Hans Meine) * Fix use of unencrypted client certs with GnuTLS * Fix ne_lock* If: header insertion to use CRLF-terminated headers * Fix test suite failures on QNX by working around send() length limit * Fix handling of POSIX strerror_r failure case in ne_strerror * Fix alignment issues in test suite MD5 code Changes in release 0.26.3: * Fix buffer under-read in URI parser (Laszlo Boszormenyi, CVE-2007-0157) * Fix regression in handling of "attempt" argument passed to auth callbacks; ensure the value only increments for each invocation of the callback * Fix handling of "nextnonce" parameter in Digest authentication Changes in release 0.26.2: * Fix error reported for LOCK responses lacking a Lock-Token header. * Use Libs.private in neon.pc for newer versions of pkg-config. * Build fix for platforms without libintl.h. * Build fixes for MinGW. (Matthias Miller) * Build fix for h_errno detection on HP-UX 10. (Albert Chin) * Win32: enable debugging; build fixes with some SDKs. (Kiyo Kelvin Lee) Changes in release 0.26.1: * Build fixes for Win32 (D.J. Heap) and OS X. * Add Simplified Chinese translation (Dongsheng Song). Changes in release 0.26.0: * Added internationalization support: - ne_i18n.h exposes ne_i18n_init(), a process-global initializer which may be required for some applications - (partial) message catalogs for cs, de, fr, ja, nn, ru and tr - NE_FEATURE_I18N feature code added to indicate support * Added support for GnuTLS (thanks to Aleix Conchillo Flaque): - pass --with-ssl=gnutls to configure; GnuTLS >= 1.0.22 required - use --with-ca-bundle to specify a default SSL CA root bundle - some remaining issues with PKCS#12 certs in current GnuTLS releases, distinguished name handling is sub-standard relative to OpenSSL * Changes and additions to URI support: - ne_uri structure: add query, fragment fields; authinfo renamed to userinfo - ne_uri_parse() now takes a URI-reference as input rather than the previous pseudo-URI syntax; the query and fragment components are now parsed out. Many malformed URIs are now rejected - ne_uri_unparse() changed to respect the new fields - ne_uri_resolve(): new function; resolves relative URI references - ne_uri_copy(): new function, copies a URI structure * Changed results callbacks for ne_lock_discover, PROPFIND interfaces: - take URI as parsed ne_uri * structure rather than char * * Added functions which give control over authentication protocol use: - ne_add_server_auth(), ne_add_proxy_auth() * Added ne_unhook_* functions to remove hooks * Added ne_set_session_flags()/ne_get_session_flags() functions: - flags to disable persistent connection support, enable "ICY" protocol support, and to disable SSLv2 protocol support. - replaces ne_set_persist() * Added ne_set_request_flags()/ne_get_request_flags() functions: - flags to enable 100-continue support, mark requests as non-idempotent - replaces ne_set_request_expect100() * Change ne_md5.h interface to make struct ne_md5_ctx opaque: - added ne_md5_create_ctx(), ne_md5_destroy_ctx(), ne_md5_reset_ctx(), ne_md5_finish_ascii(); removed ne_md5_init_ctx() - fix alignment issues which could cause crashes in Digest code * Fixed ne_get_range(), added ne_get_range64() (thanks to Lennart Poettering) * Removed NE_FREE() macro from ne_alloc.h * Added ne_strcasecmp(), ne_strncasecmp(), ne_tolower() functions to ne_string.h - locale-independent string comparison * Changed ne_sock_init()/ne_sock_exit() such that ne_sock_exit() only has effect once called an equal number of times to _init(). * Added "--enable-threadsafe-ssl=posix" configure flag, to enable thread-safe SSL support using POSIX threads in OpenSSL/GnuTLS - NE_FEATURE_TS_SSL feature code added to indicate support * The manual is now licensed under the GPL rather than the GFDL Changes in release 0.25.5: * ne_ssl_clicert_decrypt(): catch and fail to load a client cert with mismatched key/cert pair. * Fix build issue on AIX 5.1. * Fix warnings if built against OpenSSL >= 0.9.8. * Win32: fix issues in SSPI implementation (Stefan Kng). Changes in release 0.25.4: * GSSAPI fixes for non-MIT implementations (Mikhail Teterin). * Fix ne_print_request_header() et al to use 8K buffer size on all platforms (fixes issue with long Destination: URLs on Win32). * Win32 build fix for !USE_GETADDRINFO configuration. * Documentation updates. Changes in release 0.25.3: * ne_lock() and ne_unlock(): fix cases where NE_ERROR would be returned instead of e.g. NE_AUTH on auth failure. * Prevent use of poll() on Darwin. * Fix gethostbyname-based resolver on LP64 platforms (Matthew Sanderson). Changes in release 0.25.2: * Really fix the Win32 build. Changes in release 0.25.1: * ne_get_content_type(): fix cases where the charset field was not set to NULL after successful return (Johannes Schneider) * Compressed response handling fixes: - fix double invocation of reader callback with len=0 - fix cases where the reader callback return value was ignored * Cache the new SSL session if the old one was expired (Robert Eiglmaier) * Win32: fix build issues. Changes in release 0.25.0: * New interfaces: - ne_get_response_header() replaces ne_add_response_header_handler - ne_read_response_to_fd() and ne_discard_response() for use with ne_begin_request/ne_end_request style response handling - ne_xmlreq.h: ne_xml_parse_response() and ne_xml_dispatch_request() - ne_has_support() for feature detection, replaces ne_support_ssl() - ne_set_addrlist() can be used to bypass normal DNS hostname resolver - ne_buffer_czappend(), convenience wrapper for ne_buffer_append. - ne_iaddr_typeof() returns type of a socket object - ne_get_content_type() replaces ne_content_type_handler() - ne_set_request_expect100() replaces ne_set_expect100() * New interfaces on LFS systems for large file support: - ne_set_request_body_fd64() call for using an fd opened using O_LARGEFILE - ne_set_request_body_provider64(), takes an off64_t length argument * Interface changes: - ne_set_request_body_fd takes offset and length arguments and returns void - ne_set_request_body_provider takes length as off_t rather than size_t; provider callbacks now MUST set session error string if returning an error - response body reader callback returns an integer and can abort the response - ne_decompress_destroy() returns void; errors are caught earlier - ne_xml_failed() replaces ne_xml_valid(), with different return value logic - ne_xml_parse() can return an error; ne_xml_parse_v() aborts the response if the parse either fails or is aborted by a handler returning NE_XML_ABORT - ne_path_escape() now escapes all but unreserved characters - ne_ssl_clicert_name() and ne_ssl_cert_identity() clarified to return UTF-8 - ne_ssl_clicert_name() clicert object argument is now const - ne_uri_parse()/ne_uri_free() memory handling clarified - removed the buffer length requirement for ne_read_response_block() * Bug fixes: - properly handle multiple Authentication challenges per request - fixes and improvements to the Negotiate auth implementation - handle proxies which send a 401 auth challenge to a CONNECT request - XML: handle the UTF-8 BOM even if the underlying parser does not - Win32: Fix timezone handling (Jiang Lei) - ne_lock_refresh() works and will update timeout of passed-in lock - persistent connection timeout handling fixes for CygWin et al - impose hard limit of 1024 props per resource in ne_props.h response parsing * New platform-specific features: - Win32: Negotiate/NTLM support using SSPI (Vladimir Berezniker) - Win32: Add IPv6 support using ENABLE_IPV6 neon.mak flag (Kai Sommerfeld) * Removed features: - the cookies interface has been removed - removed functions: ne_service_lookup(), ne_put_if_unmodified() - "qop=auth-int" support removed from Digest auth implementation * Default XML parser search changed to check for expat before libxml2. Changes in release 0.24.7: * Compression interface fixes: - fix issues handling content decoding and request retries from authentication challenges (Justin Erenkrantz) - fix places where reader callback would receive spurious size=0 calls - fix to pass user-supplied userdata to user-supplied acceptance callback * Fix for RFC2617-style digest authentication (Hideaki Takahashi). * Fix to pick up gethostbyname() on QNX 6.2. Changes in release 0.24.6: * SECURITY (CVE CAN-2004-0398): Fix sscanf overflow in ne_rfc1036_parse, thanks to Stefan Esser. * Link libneon against libexpat during Subversion build using bundled neon. * Win32 build script update (Jon Foster). Changes in release 0.24.5: * SECURITY (CVE CAN-2004-0179): Fix format string vulnerabilities in XML/207 response handling, reported by greuff@void.at. * Performance fix: avoid seeding the SSL PRNG if not creating an SSL socket. * ne_ssl_readable_dname() is now defined to return UTF-8 strings. * Fix case where gssapi/gssapi_generic.h was included but not present. * Fix ne_utils.c build on platforms where zlib does "#define const". * Fix use of ne_proppatch_operation with some C++ compilers. * Update libtool for fix to --enable-shared on Darwin. * BeOS: check for gethostbyname in -lbind (David Reid). Changes in release 0.24.4: * Ignore unclean SSL closure when response body is delimited by EOF ("Could not read response body: Secure connection truncated" errors with some buggy SSL servers). * Fix test/ssl.c syntax errors with C89 compilers (Radu Greab). Changes in release 0.24.3: * Respect configure's --datadir argument (Max Bowsher). * Fix build on Windows when OpenSSL is not used. * Fix use of SSLv2 (spurious "Server did not present certificate" error). * When using SSL via a proxy, prevent leaking server auth credentials to the proxy, or proxy auth credentials to the server. Changes in release 0.24.2: * Fix name resolver with some old versions of glibc. * Fix problems with configure's "time_t format string" detection. * Fix problems when a broken Kerberos installation is found. * When verifying SSL certificates, check iPaddress names in the subjectAltName extension. Changes in release 0.24.1: * Add support for "GSS-Negotiate" Kerberos authentication scheme (from Risko Gergely and Burjan Gabor). * Disable Nagle to improve performance of small requests (thanks to Jim Whitehead and Teng Xu). * Fix compatibility with OpenSSL 0.9.6 (broken in 0.24.0). * Fix prototype mismatch in ne_207.c. * Define ssize_t from ne_request.h for Win32. * Prevent segfault on zlib initialization failures. * ne_sock_init does not fail if PRNG could not be seeded. * Fix segfault in cookies code (Markus Mueller). * Documentation updates. Changes in release 0.24.0: * Major changes to XML interface: - have the start-element callback either accept, decline, abort, or return a state integer. - remove 'struct ne_xml_elm'; callbacks are passed {nspace, name} strings along with a state integer. - dropped "collect", "strip-leading-whitespace" modes - push responsibility for accumulating cdata onto caller; drop 'cdata' argument from end-element callback. - don't abort if no handler accepts a particular element, just ignore that branch of the tree. - dropped support for libxml 1.x and expat < 1.95.0. - guarantee that start_element callback is not passed attrs=NULL - add ne_xml_doc_encoding() to retrieve encoding of parsed XML document. * Major changes to SSL interface: - rewrite of interfaces for handling server and client certificates; ne_ssl.h: many new functions available. - only PKCS#12-encoded client certs are supported. - changes to most names of SSL-related functions operating on an ne_session, e.g. ne_ssl_load_cert->ne_ssl_trust_cert. - client cert provider callback is passed the set of acceptable CA names sent by the server - the entire chain of certs presented by server is now accessible * Remove unused ne_register_progress() from socket layer. * Changes to resolver interface: ne_addr_first and _next return const; ne_addr_print renamed to ne_iaddr_print; ne_iaddr_make and ne_iaddr_free have been added. * ne_request_create() now duplicates the method string passed in. * ne_redirect_location() will now return NULL in some cases. * Split socket creation to ne_sock_create() from ne_sock_connect: - should report connect() error messages properly on Win32. * Fix several memory leaks in error handling paths. * Add a pkg-config file, neon.pc.in. Changes in release 0.23.9: * Fix inability to connect on AIX 4.3. * neon-config exports includes needed for OpenSSL given by pkg-config. * ne_redirect_location will return NULL if redirect hooks have not been registered for the session (Ralf Mattes ). Changes in release 0.23.8: * SECURITY: Prevent control characters from being included in the reason_phrase field filled in by ne_parse_statusline(), and in the session error string. * Disable getaddrinfo() support on HP-UX; fix resolver for HP-UX 11.11. * Fix digest auth response verification for >9 responses in session (bug manifests as "Server was not authenticated correctly" error). * On Linux, skip slow lookup for IPv6 addresses when IPv6 support is not loaded in kernel (thanks to Daniel Stenberg for this technique). * Update to autoconf 2.57 and libtool 1.4.3. Changes in release 0.23.7: * Fix for handling EINTR during write() call (Sergey N Ushakov). * When available, use pkg-config to determine compiler flags needed to use OpenSSL headers and libraries. Changes in release 0.23.6: * Fixes for error handling in socket layer on Win32 from Johan Lindh and Sergey N Ushakov : - meaningful error messages rather than "No error" - handle persistent connection timeouts properly * Fix to use RFC2617-style digest auth when possible (had reverted to only using RFC2068-style in 0.16.1). * Fix NULL pointer dereference on certain ill-formed PROPFIND responses. * Allow ne_sock_init to re-initialize after ne_sock_finish has been called (Sergey N Ushakov). Changes in release 0.23.5: * Fix rejection of SSL server certificates which had commonName as the least specific attribute in the subject name. * Fix to dereference entities (e.g. "&") in attribute values with libxml. * Fix ne_socket.c build on HP-UX 10.20 (thanks to Branko ibej) * Remove misguided insistence on "secure" versions of zlib/OpenSSL; no checks for zlib version are now performed, only OpenSSL 0.9.6 is required. --with-force-ssl, --with-force-zlib option removed. * Add --with-egd[=PATH] option, conditionally enable EGD support; either using EGD socket at PATH, or fall back on system defaults. $EGDSOCKET and $HOME/.entropy are no longer used. * Add support for `--la-file' argument to neon-config, which prints the full path of the installed libneon.la file. Changes in release 0.23.4: * Ignore an unclean SSL shutdown on persistent connection timeout (fixing spurious "Secure connection truncated" errors). * Fix a segfault on second and subsequent requests using a given session, when the first fails with NE_LOOKUP. * Fix configure for gcc installations which produce warnings by default (such as gcc on hppa2.0n-hp-hpux11.00 using native as) Changes in release 0.23.3: * Further build fixes for Win32 (Blair Zajac). * Another fix for use of SSL against Tomcat 3.2. Changes in release 0.23.2: * Build fix for Win32 (Blair Zajac). Changes in release 0.23.1: * Identify as correct version, not 0.22. Changes in release 0.23.0: * Improved address resolver (ne_addr_*) replacing ne_name_lookup(): - use getaddrinfo() if found; include support for IPv6 (based on work by Noriaki Takamiya ) * For a hostname with multiple addresses, each address is tried in turn until a connection is made. * Support for seeding OpenSSL's PRNG via $EGDSOCKET or $HOME/.entropy, to enable SSL on platforms which lack a /dev/random device. * RFC2818 compliance for certificate identity checks in SSL: - use `dNSname' values in subjectAltName extension if present - hostname comparison fixed to not be case-sensitive * Fix interop with buggy SSL implementation in Tomcat 3.2. * Added NE_DBG_SSL debug channel. * ne_strerror changed to return the passed-in buffer. * Added ne_strnzcpy macro to ne_string.h. * Win32 build fixes, improvements, and documentation updates, from Blair Zajac . * Fix ne_sock_init so SIGPIPE signals are ignored even if SSL library initialization fails (e.g. platforms without /dev/random). * Added reference documentation: - ne_sock_init, ne_addr_*. Changes in release 0.22.0: * Remove the const qualifier from the reason_phrase field in ne_status. - ne_parse_statusline() now strdup's the reason_phrase * Remove the status_line argument from ne_207_end_propstat and _end_response * Change ne_session_create, ne_session_proxy, ne_sock_connect, and the 'port' field of the ne_uri structure to use an unsigned int for port numbers * ne_uri_defaultport returns unsigned and '0' on an unknown port (not -1). * Changes to hooks interface: - pass an ne_request pointer to per-request hooks - replace "accessor" hooks with ne_{get,set}_{request,session}_private * Authentication changes: - the hooks changes fix a segfault if auth is enabled for an SSL session through a proxy server - fix ne_forget_auth segfault if either proxy or server auth are not used * Improvements to persistent connection retry logic and error handling in request code; fixing some cases where some errors where incorrectly treated as a persistent connection timeout - a TCP RST at the appropriate time is now treated as a persistent connection timeout. - handle persistent connection timeouts on SSL connections * Changes to SSL support: - improved error handling - OpenSSL 0.9.6f or later is required for security fixes and functional correctness; 0.9.6 or later required for functional correctness - use --with-force-ssl to override OpenSSL version check - fix for proxy CONNECT tunnelling with some proxies (e.g. Traffic-Server) - fix potential segfault if client cert. provider callback is used - fix to use supplied password callback for PEM-encoded client certificates (Daniel Berlin ) * strerror_r is used if available for thread-safe error handling. * Remove ne_read_file(). * ne_version_match replaces ne_version_minimum (semantics changed slightly). * XML request bodies use a content-type of "application/xml" now; applications can use NE_XML_MEDIA_TYPE from ne_xml.h * Fix decompress code on big-endian or 64-bit platforms. * Fix to build on Darwin 6 (aka Mac OS X 10.2) (Wilfredo Snchez, ) * Win32 changes: - remove conflict between OpenSSL's X509_NAME and recent versions of the Platform SDK (Branko ibej) - fix inverted debug/non-debug build logic (Branko ibej) - add NODAV and OPENSSL_STATIC flags to neon.mak (Gerald Richter) Changes in release 0.21.3: * Fix segfault if using proxy server with SSL session and server certificate verification fails. * Fix leak of proxy hostname once per session (if a proxy is used). * Add --with-libs configure argument; e.g. --with-libs=/usr/local picks up any support libraries in /usr/local/{lib,include} Changes in release 0.21.2: * Fix 'make install' for VPATH builds. * Use $(mandir) for installing man pages (Rodney Dawes). * Follow some simple (yet illegal) relativeURI redirects. * Always build ne_compress.obj in Win32 build (Branko ibej). * Fix decompression logic bug (Justin Erenkrantz ) (could give a decompress failure for particular responses) * Fix ne_proppatch() to submit lock tokens for available locks. * More optimisation of ne_sock_readline. Changes in release 0.21.1: * Don't include default SSL port in Host request header, which can help interoperability with misbehaving servers (thanks to Rodney Dawes ). * Don't give a "truncated response" error from ne_decompress_destroy if the acceptance function returns non-zero. * Fix for Win32 build (Sander Striker ). * Fix for cookie name/value being free()d (thanks to Dan Mullen). * Optimisation of ne_sock_readline. Changes in release 0.21.0: * Socket layer implements read buffering; efficiency and performance improvement. Based on work by Jeff Johnson * Cleanup of socket interface: - renamed everything, s/sock_/ne_sock_/, s/SOCK_/NE_SOCK_/ - removed unused and inappropriate interfaces. - renaming done by Olof Oberg - see src/ChangeLog for the gory details. * Fix typoed 'ne_destroy_fn' typedef (Olof Oberg). * Support OpenSSL/ENGINE branch. * Bogus ne_utf8_encode/decode functions removed. * ne_base64() moved to ne_string.[ch]. * ne_token drops 'quotes' parameter; ne_qtoken added. * ne_buffer_create_sized renamed to ne_buffer_ncreate. * ne_xml_get_attr takes extra arguments and can resolve namespaces. * ne_accept_response function type takes const ne_status pointer. * Drop support for automatically following redirects: - ne_redirect_register just takes a session pointer - ne_redirect_location returns an ne_uri pointer * configure changes: --with-ssl and --with-socks no longer take a directory argument. To use SOCKS or SSL libraries/headers in non-system locations, use ./configure CPPFLAGS=-I/... LDFLAGS=-L/... * Reference documentation included for most of ne_alloc.h and ne_string.h, and parts of ne_session.h and ne_request.h. - see installed man pages, HTML documentation. Changes in release 0.20.0: * Major changes to DAV lock handling interface (ne_locks.h): - struct ne_lock uses a full URI structure to identify locked resource - ne_lock() requires that owner/token fields are malloc-allocated (or NULL) on entry - introduce a "lock store" type, ne_lock_store, to replace the lock session; accessor functions all renamed to ne_lockstore_*. - ne_lock_iterate replaced with a first/next "cursor"-style interface - If: headers use an absoluteURI (RFC2518 compliance fix). - fix for handling shared locks on DAV servers which return many active locks in the LOCK response (thanks to Keith Wannamaker) * Moved URI/path manipulation functions under ne_* namespace (ne_uri.h): - path handling functions renamed to ne_path_* - URI structure handling to ne_uri_*; struct uri becomes ne_uri. - ne_uri_parse doesn't take a 'defaults' parameter any more - if URI port is unspecified, ne_uri_parse sets port to 0 not -1. - added ne_uri_unparse and ne_uri_defaultport functions. * New 'ne_fill_server_uri' function to initialize a URI structure with the server details for a given session (useful with locks interface). * ne_decompress_{reader,destroy} are defined as passthrough-functions if zlib support is not enabled. * API change: ne_ssl_provide_fn returns void not int. * Added NE_SSL_FAILMASK for verify failure sanity check. * Removed return codes NE_SERVERAUTH and and NE_AUTHPROXY; correct documentation, NE_PROXYAUTH is given for proxy auth failure. * Require zlib >= 1.1.4 to avoid possible vulnerability in earlier versions. See http://www.gzip.org/zlib/advisory-2002-03-11.txt for more details. (version check can be skipped by passing --with-force-zlib to configure) * New 'ne_ssl_readable_dname' function to create a human-readable string from an X509 distinguished name. * Fix support for newer versions of libxml2 (thanks to Jon Trowbridge ). * Fix corruption of reason_phrase in status object returned by ne_propset_status. * More lenient handling of whitespace in response headers. * ne_content_type_handler will give a charset of "ISO-8859-1" if no charset parameter is specified for a text/* media type (as per RFC2616). * Miscellaneous cleanups and fixes (Jeff Johnson ). Changes in release 0.19.4: * Support bundled build of expat 1.95.x (Branko ibej). Changes in release 0.19.3: * For platforms lacking snprintf or vsnprintf in libc, require trio. * Add NE_FMT_OFF_T to fix Win32 build (Dan Berlin, Branko ibej). * Fix SSL support in Win32 build (Branko ibej). Changes in release 0.19.2: * Fix non-SSL build broken in 0.19.1. * Working SOCKSv5 support (thanks to Torsten Kalix ) Changes in release 0.19.1: * Add missing stubs for ne_ssl_* functions for non-SSL build. * Fix some error messages in new SSL code. Changes in release 0.19.0: * Major API change: ne_session_create now takes (scheme, hostname, port) arguments: a session is clarified to be "a group of requests to a certain server". - removal of ne_session_server, ne_set_secure, and ne_set_proxy_decider - ne_session_proxy returns void. - DNS lookups are delayed until request dispatch time. * Significant improvements to TLS/SSL support: - SSL is enabled if scheme passed to ne_session_create is "https" - new interfaces to load CA certs and to load SSL library's bundled CA certs - add server cert verification callback. An SSL connection to a server with an unknown CA will now fail unless a verification callback is used. - enable SSL session caching (performance improvement) - support for wildcard server certs where commonName is "*.example.com". - thanks to Tommi Komulainen for the contribution of code from mutt's IMAP/SSL implementation under the LGPL, from which bits of this were derived. * Improved SSL client certificate support: - far simpler interface, all done at ne_session.h level. - supports PKCS#12 and PEM-encoded certificates. - optional callback for only providing client when demanded by server. * Support for TLS upgrade is removed, since it isn't useful. * If NEON_SSL is defined, API extensions are available to: - allow access to the SSL_CTX * to adjust session SSL options - retrieve the server certificate (X509 *) * Decompress fixes: - fix potential segfault in ne_decompress_destroy - check the CRC of the deflated output (and fail if it doesn't match) - fail appropriately on truncated responses, and trailing bytes in response. * Added ne_set_read_timeout to use configurable timeout on socket reads. * Malformed response headers will be ignored rather than failing the request. * ne_set_error takes printf-style vararg. * Fixes for ne_get_range and improve error handling. * Functions which append to an ne_buffer do not return a success value, but they do use ne_realloc/ne_malloc under the hood now, so an OOM callback will be used (with the usual caveats). * XML interface does not strip leading whitespace from cdata by default, the NE_XML_STRIPWS flag is available to restore this feature if required. * Upgraded to libtool 1.4.2: - should fix --enable-shared on Mac OS X 10.1 * Test suite now contains over one hundred tests. Changes in release 0.18.5: * Removed old neon.dsp, neon.dsw. * Update Win32 build to add OpenSSL and zlib support (Branko ibej). * Fix ne_compress.c to compile on Win32 (Branko ibej). Changes in release 0.18.4: * Fixes for Content-Type parsing using ne_content_type_handler (Greg Stein) - also now parses the charset parameter from header value. * Removed ne_concat() function, which didn't work and wasn't used. Changes in release 0.18.3: * Fix parsing lock timeout from server (Arun Garg). * Send Timeout headers in LOCK and refresh LOCK requests (Arun Garg). * Updated neon.mak and config.hw.in for Win32 build (patch from Branko ibej ). * Define XML_BYTE_ORDER for bundled expat build in support macro NEON_XML_PARSER(). Changes in release 0.18.2: * Fix --with-neon=PATH in support macros. * Support DESTDIR in Makefile install targets (patch by Pawel Golaszewski ). * Portability fixes: - fix configure check for time_t on some platforms (e.g Solaris 2.6). - remove expect100_works bitfield in ne_session structure (thanks to Yan Periard ). Changes in release 0.18.1: * Minor fix for authentication: "attempt" counter was not reset correctly after authentication failed, so subsequent requests would not authenticate correctly either. * API change: ne_session_destroy returns void (there was no error case). * Portability fixes (non-GCC compilers, 64-bit platforms, UnixWare 7) * Optimisations in string manipulation routines. * config.hw is included in the release tarball again. * Improvements in the autoconf support macros: - check for neon-config in PATH if --with-neon is not given - stop if --with-neon is used, and the check for external neon fails - added NEON_WITHOUT_ACL to prevent build of ne_acl.o Changes in release 0.18.0: * API change: authentication callback is passed fixed-size username/password buffers, and an 'attempt' counter. Authentication is retried *forever* until either it succeeds, or the callback returns non-zero. * API clarifications: - ne_propname may have a NULL nspace field, indicating the property has no namespace. This holds for properties returned by the propfind interfaces. - added NE_ELM_PROPS_UNUSED as the lowest element number which should be used with handlers added to the XML parser returned by ne_propfind_get_parser. * Fixes and cleanups of lock discovery interface. * Fix for short write handling in ne_get() (thanks to rado ). * Fix for XML namespace prefix handling where a prefix could be mapped to an incorrect URI (e.g. in PROPFINDs against mod_dav with >10 namespaces used) * Add '--support ' option to neon-config; the script exits with success if given feature is supported. Known features are ssl, dav, zlib. * Support for SSL, DAV, zlib is exported by neon.m4 as shell variable NEON_SUPPORTS_{SSL,DAV,ZLIB}={yes,no} for bundled and external builds. * `neon-config --cflags` won't include -I/usr/include for SSL build. * Fix to call progress callbacks while sending request bodies again. * Test changes: - portability fixes, auth interface and progress tests. Changes in release 0.17.2: * Accept Status-Lines with no reason phrase (Jeremy Elson). * Fix handling of persistent connection timeout, and better error handling if sending a request fails. * Fix crashes in locking code. * Return parse error on XML namespace prefix declaration with an empty value. Thanks to Julian Reschke. * Allow passing property names with NULL namespace to ne_proppatch. * Fix for cross-compilation (Mo DeJong). * Moved ne_propname definition from ne_207.h to ne_props.h. * Test changes: - updated for Status-Line parsing changes (Jeremy Elson) - better persistent connection tests - fixed for --disable-webdav build Changes in release 0.17.1: * Add support for ACL method (Arun Garg ), see ne_acl.h. * Fixes and clean up of libraries exported via `neon-config --libs' * Fix timezone handling when parsing dates (on some platforms). * Upgrade to autoconf 2.52 and libtool 1.4 (thanks to Mo DeJong). * Cleanup/simplification of request dispatching: - better handling of error cases, including fix for a possible infinite loop when the server closes the connection prematurely. * Add '--without-zlib' configure option. * Test changes: - prettify output; imitate Perl test suite output. - add tests for interim 1xx responses, persistent connections, more unbounded operations. Changes in release 0.17.0: * Add support for decoding gzip Content-Encoding: see ne_compress.h. - built if zlib is found; `neon-config --cflags' will define NEON_ZLIB if so. * Rewrite hooks interface to register individual callbacks. - inspired by the Apache 2.0/APR hooks interface * Register cookies hooks using ne_cookie_register(). * Clean up configure scripts to enable use of autoconf 2.5x (Mo DeJong). * Use new endianess configure macro to allow cross-compiling (Mo DeJong). * Fix invalid C code in sock_init() in Win32 build (Mo DeJong). * Fix use of signal() on Win32 (Mo DeJong). * Workaround libxml 1.x string handling not being UTF-8. * Test changes: - add tests for decompression interface. Changes in release 0.16.1: * Also handle write errors in ne_get_range. * Dump request body blocks in debugging mode. * Fix ne_shave() causing memory corruption when the result should have been the empty string. * Refactor auth header parsing code; more efficient now. - fixes digest auth RFC2617-style broken in 0.16.0 Changes in release 0.16.0: * API change: ne_copy takes a depth parameter (thanks to Arun Garg, Medha Atre) * API change: validate callback to ne_xml also takes a userdata arg. * Added 'ne_lock_refresh' for performing lock refresh (Arun Garg). * Add SSL support to Win32 build (Peter Boos ) (see INSTALL.win32 for details). Compile with USE_DAV_LOCKS also. * Remove Server header parser for 100-continue support in ne_options. (and remove broken_expect100 from ne_server_capabilities). * Set SIGPIPE disposition to "ignored" in sock_init(). * On platforms with setvbuf(), turn off buffering for the debug log stream. * Ignore repeated calls to sock_init(). * Fixes to error handling in ne_get_range. * Minor improvements to memory handling in auth code. * Fix for start_propstat callback being called with NULL response argument when given invalid XML, causing a segfault in propfind code. * Test changes: - add regression test for the propfind segfault. - handle segfaults better (reap the child, flush the debug log). Changes in release 0.15.3: * Fix --with-expat=DIR build. Changes in release 0.15.2: * Fix Win32 for XML parser changes (Gerald Richter). * Substitute versions into config.hw at distribution time. * Add date parser for ISO8601-formatted dates as defined by RFC2518, e.g. the creationdate property (Taisuke Yamada ). * Fix Y2K bug in RFC1036 date parsing algorithm. * Test changes: - add tests for date parsing functions. Changes in release 0.15.1: * Win32 update from Gerald Richter - new files neon.mak, INSTALL.win32 * Fix for ne_socket.h includes (Mo DeJong). * More improvements for XML parser selection logic: - if parser is required, be sure to fail configure if none is found. - added --with-included-expat for bundled expat logic. * Rename --enable-debugging to --enable-debug (Mo DeJong). - added NEON_DEBUG macro to exported autoconf macros. * Call progress callbacks for request bodies. * Test changes: - check that reading response headers is a bounded operation. - use a pipe between child and parent to avoid race condition and tedious sleep(). Changes in release 0.15.0: * Major API renaming to use ne_/NE_ namespace: - http_ to ne_, HTTP_ to NE_, dav_ to ne_, DAV_ to NE_, neon_ to ne_ - hip_xml_ to ne_xml_, HIP_ELM_ to NE_ELM_, HIP_XML_ -> NE_XML_ - sbuffer_ to ne_buffer_ - DEBUG() to NE_DEBUG(), DEBUG_ to NE_DBG_ * Type renames: - http_req to ne_request - sbuffer to 'ne_buffer *' * Note, 'ne_buffer' is not an implicit pointer type, you must specify the '*' now, e.g. 'ne_buffer *buf = ne_buffer_create();'. * ne_buffer is no longer opaque. - ne_buffer_data() removed: use buf->data instead. - ne_buffer_size() is a macro. * Header renames and additions: - http_request.h -> ne_request.h - Session code split into ne_session.h - hip_xml.h -> ne_xml.h, nsocket.h -> ne_socket.h, http_utils.h -> ne_utils.h - neon_md5.h -> ne_md5.h, dav_207.h -> ne_207.h - http_basic.h and dav_basic.h merged into ne_basic.h * New functions: - ne_token and ne_shave, to obsolete split_string, shave_string. * Removed: ne_get_request_headers(). * autoconf changes: - disable building shared neon library by default. - option --enable-libxml is replaced by --with-libxml1 and --with-libxml2 to force use of a particular parser. * Fix auth code to only take MD5 digests of response body blocks when necessary (thanks to Kai Sommerfeld). * Fix alignment bug in MD5 code which could cause SIGBUS on Sparc architectures (Kai Sommerfeld). * Rewrite of request body handling: - ne_set_request_body_fd replaces _stream, using an int fd rather than a FILE *. - added ne_set_request_body_provider to give a callback which is called to provide request body blocks. - removal of 'use_body' hook in favour of 'ne_pull_request_body' function to allow hooks to manually read the request body. - ne_{put,get,post,put_if_unmodified} all take an integer fd rather than a FILE * stream. * Test changes: - added framework for testing "over the wire" (fork a server process) - added tests for response message length handling, chunked responses, header folding, sending request bodies. - start at listing RFC2616 requirements and whether they are met or not in test/STATUS. - test for MD5 alignment bug on Sparc (thanks to Kai Sommerfeld). Changes in release 0.14.0: * Add C++ inclusion safety to http_auth.h (Kai Sommerfeld). * Define ssize_t on Win32. (Kai Sommerfeld). * Add C++ inclusion safety to dav_locks.h and ne_alloc.h (thanks to Gregor Bornemann ). * Significant API change to properties code, to allow use of allprop and complex properties: - dav_propfind_set_complex and _set_flat are removed. - add parameter to dav_propfind_named to take the list of property names to be fetched. - new function dav_propfind_set_private to set private callback. - all properties not handled by caller are stored as flat properties. * Untested: add basic SOCKSv5 support: configure --with-socks. - please report success/failure to neon@webdav.org * Win32/MSVC build files from Magnus Sirwi . * Fix for expat detection from Shane Mayer . * Namespace-protect md5 code and more. - md5_* -> ne_md5_* - ascii_to_md5 -> ne_ascii_to_md5 (and moved to neon_md5.h) * Parse authinfo segment in URIs (Johan Lindh ). - added 'authinfo' field to struct uri. * New API: hip_xml_get_attr to retrieve attributes. * Store language for properties, access with dav_propset_lang. - only if property is defined on the property element itself. * Started a simple test suite (test/*). - includes some simple HTTP server tests. * Remove "Content-Length: 0" header for request with no body, fixing interop with Squid 2.3-STABLE1 (thanks to Kai Sommerfeld). * http_parse_statusline skips leading whitespace. (Johan Lindh). * Partial fix for timezone/date parsing problems. Changes in release 0.13.0: * Fix ne_strndup allocating one byte less than it should (Kai Sommerfeld) - if you use uri_parse, this bug may have caused subtle memory corruption in your application. * Revert API changes in 0.12: property values are not UTF-8 encoded/decoded internally. (thanks to Greg Stein) * Add another optional argument to NEON_BUNDLED macros, actions to be run if bundled build is *not* selected. * API change: added argument to http_add_hooks to register cleanup function for the cookie. * Removed dav_lock_unregister in favour of automatic cleanup when session is destroyed. * Fixed leaks in redirect code (Kai Sommerfeld). * Fixed crashes in hip_xml_destroy (Kai Sommerfeld). * Redirects to a different hostname/port/scheme are never followed: the request will fail with HTTP_REDIRECT instead. Redirect notification callback is only called for *followed* redirects. New API: http_redirect_location() for retrieving location of last redirect. * Authentication is now implemented as a hook, independently of http_request.c: - API change: removed 'hostname' argument from auth callbacks. - API change: you must now include http_auth.h from your application. - Also fixes case of using server and proxy authentication simultaneously * Added 'http_forget_auth' to clear authentication session. * New API: http_session_hook_private for retrieving private per-session cookie for hooks. * API change: http_set_request_body_stream has a return error value. * API change: http_set_request_body_buffer now takes the buffer length too. * New API: caller-pulls interface for reading response body: http_begin_request, http_end_request, http_read_response_block. An alternative to using the (much simpler) http_request_dispatch. * Make --disable-webdav build work. * New API: dav_propnames for retrieving property names. * New API: dav_propfind_get_request to access request object of handler. * API change: progress and connection status callbacks implemented at http_request.h level. Socket-level status callbacks removed, progress callbacks made per-socket. * Supports new expat (Sam TH ) * Supports libxml2 (in preference to libxml1). * API change: added namespace protection to base64 and dates functions: all have ne_ prefix now. * Fixed ranged GETs where a specific range is requested (Johan Lindh ). * Limit number of response header fields to 100. * Allow requests for the '*' URI even if a proxy server is in use. * libxml: Get useful error messages for parse errors. Changes in release 0.12.0: * Portability fixes to http_request.c and http_auth.c. - fixes digest auth on big-endian architectures. * Fix warnings from stray tokens after #endif's in uri.h and string_utils.h. * Add C++ inclusion safety to http_redirect.h (Kai Sommerfeld ). * Make redirects to a different host work (Kai Sommerfeld). * Fix reading response bodies when non-chunked and no Content-Length (Kai Sommerfeld). * API change: 'http_add_hooks takes a 'const' request object. * Fixed memory leaks in session hooks (thanks to Kai Sommerfeld). * Fix passing NULL props argument to dav_simple_propfind, to support allprop requests. **** MAJOR INTERFACE CHANGE **** - URIs passed to http_request_create() are NOT escaped by neon. You MUST do this yourself to remain HTTP compliant, using e.g. uri_abspath_escape. (Kai Sommerfeld) * Added --disable-webdav flag to configure, to disable DAV support in the library. This allows building neon without an XML parser. * Corresponding NEON_WITHOUT_WEBDAV macro for use in bundled builds. * Fix Makefile dependancies. * A bundled neon directory builds or doesn't build automatically (i.e. you recurse into it unconditionally). * API clarification: - dav_propset_status may return NULL if the server does not return a response for the given property (issue is open for debate). * API change up for debate: - Property values to dav_proppatch are UTF-8 encoded internally. - Property values in dav_propfind_* are UTF-8 decoded internally. * API additions: ne_realloc, ne_utf8_encode. Changes in release 0.11.0: * Added SSL client certificate support with 'sock_set_client_cert'. - Supports certs in PEM-encoded files. - Specify a callback for prompting the user for the password with sock_set_key_prompt. * Added 'ne_oom_callback', to register a callback which is used if malloc() returns NULL. (Mike Rosellini ) * Register appropriate callback with libxml to handle ). Changes in release 0.10.1: * Default expect-100 to OFF. Changes in release 0.10.0: * hip_xml API changes: - The search for a handler for a new child element begins at the handler of the parent element, and carries on up the stack. (previously, it always started from the base of the stack) - Documentation written: doc/parsing-xml.txt * Remove memory leaks and tidy debugging output in new properties code. * API changes to DAV locking interface: - New function: dav_lock_copy to copy a lock object. - Re-ordered arguments to callback of dav_lock_discover, and made the lock object passed back const. - Fix leaks and crashes due to vague interface definitions. * API change to dav_propfind_set_complex: use a callback to return the 'private' structure. * NEON_NORMAL_BUILD and NEON_LIBTOOL_BUILD macros defined for setting up neon's Makefile in a bundled build: see macros/neon.m4. * NEON_VPATH_BUNDLED macro added which takes separate srcdir and builddir arguments for supporting VPATH builds (thanks to Peter Moulder ). * Added optional final argument to NEON_(VPATH_)BUNDLED, which gives a set of actions to be run if the bundled build is chosen. * NEON_SSL checks for OpenSSL in /usr too. * API change: when using http_session_decide_proxy, it MUST be called before using http_session_server to prevent the DNS lookup on the origin server being optimised out. The real scheme in use is passed to the callback now. * New function, dav_207_ignore_unknown, to ignore any unknown XML fragments in the 207 response. Used by properties layer. Changes in release 0.9.2: * Fix using both dav_propfind_set_complex and dav_propfind_set_flat with the same propfind_handler. Changes in release 0.9.1: * dav_propfind interface - Guarantee that the 'private' structure will be initialized to zero on creation. - Make it the *callers* responsibility to free() the private structure. * Fix a few arguments/variables which mirrored globally declared symbols. Changes in release 0.9.0: * Removed old dav_propfind_* interface, replaced with a better, more powerful, and easier to use interface: - 'dav_simple_propfind' interface for just fetching "flat" (byte-string) properties. - 'dav_propfind_*' interface for fetching flat and/or "complex" (structured XML) properties. - Lets you retrieve the 'status' information, to see what happened if fetching the property failed (e.g 404 Not Found). * Fixes to doc/using-neon.txt (thanks to Greg Stein). * Allow building when srcdir != builddir (Mo DeJong ) Changes in release 0.8.1: * Fix segfault in PROPFIND code. Changes in release 0.8.0: * Fix for using COPY/MOVE over SSL (thanks to David Sloat). * Fix for using a proxy server and SSL. * Added 'http_get_scheme' API call. * Added 'http_redirect.h' to list of installed headers (thanks to everyone ;). * Changes for building on Windows (Peter Boos ) * Fixes for building on BeOS (Sam TH and David Reid ). * Add buffering to socket code for pre-BONE BeOS systems (David Reid). * Interface changes for hip_xml: - Renamed hip_xml_add_(mixed_)handler to hip_xml_push_(mixed_)handler - Documentation updates. - Added HIP_ELM_UNUSED for lowest element id which should be used. *** MAJOR INTERFACE CHANGE *** - Removed 'http_status *' pointer from http_request_dispatch. - Added http_get_status(req) to retrieve the response-status information instead. You don't have to declare an http_status object yourself now. * Similarly, added DAV_ELM_207_UNUSED for lowest element id which should be used by users of dav_207_* code (incl. use of dav_propfind_* code). * New NEON_* autoconf macro interface: - Use NEON_BUNDLED if sources are bundled, otherwise NEON_LIBRARY. - The NEON_XML_PARSER macro is NOT called automatically. You must call this yourself if using NEON_BUNDLED; see doc/using-neon.txt for details. * Fix use of 'socket' in nsocket.h function prototypes (Greg Stein). * Remove extra backslash at line 69 of src/Makefile.incl (Dirk Bergstrom). * Examples directory is now a separate package. Changes in release 0.7.7: * Another fix for linking against a libtool-built expat (Greg Stein). Changes in release 0.7.6: * Better check for closed SSL connection after doing SSL_peek. (thanks to Jeff Costlow ). * Attempt at correct sock_block() implementation for SSL. * sock_peek() will return SOCK_CLOSED correctly. Changes in release 0.7.5: * Fixed workaround for linking against a libtool-built expat (Greg Stein). Changes in release 0.7.4: * Fix for fd leak on connect failure (David Sloat ). * Fix for Digest auth against IIS5 (David Sloat). * Workaround for linking against a libtool-built libexpat.la (Greg Stein). Changes in release 0.7.3: * Check for -lsocket and -linet in configure. * Workaround for SSL problems. Changes in release 0.7.2: * Define SHELL in Makefile (thanks to Eric Mumpower ). * Added 'all' target to Makefile (Greg Stein ) * Added '--with-expat' argument to configure (Greg Stein) * Added 'dav_propfind_destroy' function. Changes in release 0.7.1: * Don't register response body/header authentication callbacks if no credentials-supplying callback has been registered (speed optimisation). Changes in release 0.7.0: * Deprecated use of 'NULL' to http_add_response_header_handler. New interface, http_add_response_header_catcher, to register a callback which is passed ALL response headers regardless of name. * Speed optimisation (~10%?): storing response-header handlers in a hash table for faster look. * New SBUFFER_CAST() macro for getting to the 'char *' of an sbuffer as fast as possible. Changes in release 0.6.1: * Fix for retrying request if connection is closed by server. * Make redirect hook work for >1 request per session. Changes in release 0.6.0: * New interface to allow following HTTP redirects (301/302 responses). A callback must be given to get user confirmation if the request method is not GET, HEAD, or PROPFIND. * New interface to determine whether the proxy server should be used for a given request: http_session_decide_proxy. * Fix nget build again. Support automatic redirects in 'nget'. * Add --with-extra-includes and --with-extra-libs configure parameters to point configure at Changes in release 0.5.1: * Prevent segfault if USE_DAV_LOCKS is defined, and a locking session is not registered (thanks to David Sloat). Changes in release 0.5.0: * Rename xmalloc, xstrdup etc to ne_malloc, ne_strdup etc. * Some speed optimisation in response-header reading. * Use 'off_t' rather than 'size_t' in sock_progress callback, sock_readfile_blocked, and sock_transfer. Changes in release 0.4.2: * Fix for sending request bodies after getting 100-continue response. Changes in release 0.4.1: * Fix nget build. Changes in release 0.4.0: * Install library headers into .../include/neon not .../include/libneon * Install all necessary library headers. * Compile support for WebDAV locking throughout the library * Rename md5.h to neon_md5.h (avoids conflict with md5.h in OpenSSL) * Rename socket.h to nsocket.h (avoids possible conflict with C library) * Update licensing notice on macros/neon*.m4: note that these files are NOT under the LGPL, and can be used in other packages regardless of the license the package uses. * Update NEON_LIBRARY m4 function to allow optional specification of names of bundled neon/expat source directories. * Increase socket read timeout to 60 seconds. * Added an POST method: from Sander Alberink . * Added 'http_get_request_headers' to return the sbuffer containing all request headers. * Allow passing NULL as name to http_add_response_header_handler: the handler callback is passed the entire header string, of ALL response headers. Changes in release 0.3.1: * Compile fix for dav_locks.c (thanks to Paul D'Anna) Changes in release 0.3.0: * Rewrite of socket handling layer. All sock_* functions changed. * Added basic SSL support: --with-ssl (requires OpenSSL). NOTE: Certificates are NOT presented for verification. * 'nget' accepts URL's using the 'https' scheme. * New example program, 'nserver', to display the Server: string, e.g. 'nserver https://www.eu.c2.net/' * Fixed request re-send when persistent connection times out. * "Hooks" support: allow external hooks into the HTTP request/ response dispatch loop. * New printf-style interface for adding request headers. * Make symbols used in header files C++-safe (Tom Bednarz). * WebDAV locking support: lock discovery, LOCK (exclusive/shared) UNLOCK. "If:" headers are sent as appropriate. Simple interface for implementors of new methods to indicate which locks are required for the method. * Primitive HTTP cookies support. * Primitive hack at a GNOME-based GUI example program "nbrowse". Enable build with --enable-gnome-examples. It crashes, and not much else. Requires GNOME and POSIX threads. Example usage: 'nbrowse dav.ics.uci.edu /msdav/' Many thanks to Lee Mallabone for Gtk help, and showing how to use Gtk and threads. Changes in release 0.2.0: * Use libtool: new configure options to select whether to build shared and/or static libraries. Should build shared libraries portably now. * Complete rewrite of the hip_xml interface to use opaque pointers. New functions: hip_xml_create, hip_xml_destroy: create parser. hip_xml_{set,get}_error: Access to error string. hip_xml_add_handler: Register callbacks for a set of elements. hip_xml_valid: Returns whether the parse was valid or not. Removed functions: hip_xml_init, hip_xml_finish. * Removed functions made reduntant by above changes in dav_207. * Don't include config.h in header files * Fix PROPFIND allprop request body (Michael Sobolev) * Added C++ safety macros around header files. * Added neon-config script for getting correct CFLAGS and LIBS values for using libneon in applications. Changes in release 0.1.1: * Fix for short writes in GET Changes in release 0.1.0: * Initial release. davix-R_0_5_0/deps/libneon/README000066400000000000000000000051241257152637300165300ustar00rootroot00000000000000 neon is an HTTP and WebDAV client library, with a C language API. Mailing list: neon@lists.manyfish.co.uk || Web site: http://www.webdav.org/neon/ PLEASE NOTE: The neon API is subject to backwards-incompatible change over minor releases (0.23.x -> 0.24.x) until the 1.0.0 release, but maintains source and binary backwards compatibility through patch releases (0.24.0 -> 0.24.7). Current features: - High-level interface to HTTP and WebDAV methods. - Low-level interface to HTTP request handling, to allow implementing new methods easily. - Persistent connection support (HTTP/1.1 and HTTP/1.0 aware) - Basic and digest authentication (RFC2617) (including auth-int, md5-sess) - Proxy support (including basic/digest authentication) - SSL/TLS support using OpenSSL (including client certificate support) - Generic WebDAV 207 XML response handling mechanism - XML parsing using expat or libxml (1.x or 2.x) parser - Easy generation of error messages from 207 error responses - Basic HTTP/1.1 methods: GET, PUT, HEAD, OPTIONS, conditional PUT - WebDAV resource manipulation: MOVE, COPY, DELETE, MKCOL. - WebDAV metadata support: set and remove properties (PROPPATCH), query any set of properties (PROPFIND). - WebDAV locking support - Autoconf macros supplied for easily embedding neon directly inside an application source tree. Provides lower-level interfaces to directly implement new HTTP methods, and higher-level interfaces so that you don't have to worry about the lower-level stuff. The neon library source code is licensed under the GNU Library GPL; see src/COPYING.LIB for full details. The manual and test suite are licensed under the terms of the GNU GPL; see test/COPYING for terms. The autoconf macros in the "macros" directory are under a less restrictive license, see each file for details. neon is Copyright (C) 1999-2008 Joe Orton Portions are: Copyright (C) Aleix Conchillo Flaque Copyright (C) Arfrever Frehtes Taifersar Arahesis Copyright (C) Arun Garg Copyright (C) Daniel Stenberg Copyright (C) Free Software Foundation, Inc. Copyright (C) Henrik Holst Copyright (C) Jiang Lei Copyright (C) Kai Sommerfeld Copyright (C) Karl Ove Hufthammer. Copyright (C) Michael Sobolev Copyright (C) Nobuyuki Tsuchimura Copyright (C) Sylvain Glaize Copyright (C) Thomas Schultz Copyright (C) Vladimir Berezniker @ http://public.xdi.org/=vmpn Copyright (C) Yves Martin davix-R_0_5_0/deps/libneon/THANKS000066400000000000000000000017501257152637300165640ustar00rootroot00000000000000Thanks go to the following people for contributing to neon development with code, patches, or good bug reports or suggestions. Arun Garg, Blair Zajac, Branko Èibej, Daniel Berlin, David Sloat, David Reid, Dirk Bergstrom, Ulrich Drepper, Gerald Richter, Greg Stein, Gregor Bornemann, Jeff Johnson, Jeremy Elson, Jim Whitehead, Johan Lindh, Justin Erenkrantz, Kai Sommerfeld, Keith Wannamaker, Lee Mallabone, Magnus Sirwiö, Markus Mueller, Max Bowsher, Michael Sobolev, Mike Rosellini, Mo DeJong, Noriaki Takamiya, Olof Oberg, Pawel Golaszewski, Peter Boos, Peter Moulder, rado, Risko Gergely, Rodney Dawes, Sam TH, Sander Alberink, Sander Striker, Stefan Esser, Shane Mayer, Taisuke Yamada, Teng Xu, Tom Bednarz, Tom Lee, Tommi Komulainen, Torsten Kalix, Wilfredo Sánchez, Daniel Veillard, Vladimir Berezniker, Jiang Lei, Werner Baumann, Mike DiCuccio, Gisle Vanem, Hans Meine, Laszlo Boszormenyi, Matthias Miller, Albert Chin, Kiyo Kelvin Lee, D.J. Heap, Dongsheng Song, Aleix Conchillo Flaque. davix-R_0_5_0/deps/libneon/TODO000066400000000000000000000022441257152637300163400ustar00rootroot00000000000000 To Do List for neon -*- text -*- =================== Please submit feature requests to For one-point-oh ---------------- Longer term ----------- 6. PUT with ranges... ne_put_range 9. DeltaV support (http://www.webdav.org/deltav/). See also the subversion project (http://subversion.tigris.org/) who might build a versioning system over DAV. 14. Improved request-header manipulation... some kind of indexed table (a la Apache, libghttp, so we're sure we don't add the same header to the request twice. Better control over adding Cache-Control headers would be good too. 21. Storing multiple authentication "sessions" within an actual auth_session, so I can log into e.g. /foo/ and /bar/ (which are not in the same authentication domain) and switch between them without having to re-enter passwords all the time. 46. Asynchronous request-dispatching? Makes integration into GUI loop easy... any other reasons? Must leave existing request_dispatch interface intact. 50. opendir/readdir/closedir-esque interface for PROPFIND depth 1, a la EZDAV. (cadaver has it already) davix-R_0_5_0/deps/libneon/aclocal.m4000066400000000000000000011354741257152637300175250ustar00rootroot00000000000000# generated automatically by aclocal 1.11.3 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_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 "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl 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 # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. 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 delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # 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 sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_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 _LT_EOF ;; esac _LT_PROG_LTMAIN # 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) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])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_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$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. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$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 -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_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${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed '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${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # 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. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_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 '$LINENO' "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-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|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-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; 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-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) 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_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[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 ;; *-*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*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' 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 \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$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:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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 m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$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 "$_lt_linker_boilerplate" | $SED '/^$/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 -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # 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* | cegcc*) # 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; ;; mint*) # On MiNT this can take a long time and run out of memory. 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 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; 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 ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then 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` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # 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. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` 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` fi ;; 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 max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_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 <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #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 /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 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; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_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_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_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* | cegcc*) 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="-ldld"], [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="-ldld"]) ]) ]) ]) ]) ]) ;; 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_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_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 _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$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:$LINENO: $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:$LINENO: \$? = $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 "$_lt_compiler_boilerplate" | $SED '/^$/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_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 .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_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 _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_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 _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_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_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; 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 _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) 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" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # 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. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) 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" 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 # correct to gnu/linux during the next big refactor 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' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor 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*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) 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=`func_echo_all "$lib" | $SED '\''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' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor 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* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc 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~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' 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}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; 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 dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. 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 # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # 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' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # 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}${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`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor 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 ;; 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[[23]].*) 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 ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor 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 ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" 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=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' 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' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor 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 # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # 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 # 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/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $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' ;; netbsdelf*-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='NetBSD ld.elf_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 # correct to gnu/linux during the next big refactor 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=qnx 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='ldqnx.so' ;; 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" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 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 # correct to gnu/linux during the next big refactor 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 shlibpath_overrides_runpath=yes 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' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' 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' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor 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 if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[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]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_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="m4_if([$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 <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_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 _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_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 _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_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])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 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|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 ;; haiku*) 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])(-bit)?( [LM]SB)? 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 ;; interix[[3-9]]*) # 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 glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) 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=pass_all ;; 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 ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) 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 ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi 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 _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (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 : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-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_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # 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]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' 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 # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \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\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # 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 # Try without a prefix underscore, 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. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_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_globsym_save_LIBS CFLAGS=$lt_globsym_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 -rf 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 # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_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_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # 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_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # 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). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_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_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # 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_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_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 ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # 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). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_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_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_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_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_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_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_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_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # 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_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # 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). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_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_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # 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_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # 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). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_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_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # 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 # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_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_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_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_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # 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. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # 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 ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = 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_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_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_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[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 aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, 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 install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_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_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_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_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_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_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' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$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' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_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 '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_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~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_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_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 ;; *) # 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. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_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_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_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_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_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_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_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) 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 # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_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]].*|aix[[5-9]]*) 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_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' 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 : else # We have old collect2 _LT_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_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no 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 _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_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_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_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 func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_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_SYS_MODULE_PATH_AIX([$1]) _LT_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_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_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*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # 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. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # 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_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_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' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_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_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $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_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${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_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_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_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_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_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_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_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_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_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_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_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' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_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} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_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_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_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_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_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_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$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_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl 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_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # 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 ;; aix[[4-9]]*) 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]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl 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 else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_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_CFLAGS=$CFLAGS 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++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_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_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_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_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_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_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 -v "^Configured with:" | $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_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) 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]].*|aix[[5-9]]*) 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_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' 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 : else # We have old collect2 _LT_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_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_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 _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_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_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_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 func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_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_SYS_MODULE_PATH_AIX([$1]) _LT_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_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_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_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # 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_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_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_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_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_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_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_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) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${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_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_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_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_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; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${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_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_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_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_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_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-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_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_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) 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_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_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; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_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_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # 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_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_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_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_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_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_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' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_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=`func_echo_all "$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; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_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 -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # 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_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_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::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_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_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_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | 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_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_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_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=`func_echo_all "$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; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_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" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_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 -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_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_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # 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_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_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_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_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -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 -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_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 -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_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. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$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_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_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... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC 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 fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([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. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= 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... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_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_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then 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 ;; aix[[4-9]]*) 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]) _LT_TAGVAR(GCC, $1)="$G77" _LT_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... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_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_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then 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 ;; aix[[4-9]]*) 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]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_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... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_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_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_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_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_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_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # 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. # m4_defun([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]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # 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 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_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=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_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=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_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=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # 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 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # 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. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # 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 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) m4_include([macros/ld-version-script.m4]) m4_include([macros/neon-test.m4]) m4_include([macros/neon-xml-parser.m4]) m4_include([macros/neon.m4]) davix-R_0_5_0/deps/libneon/autogen.sh000077500000000000000000000015231257152637300176500ustar00rootroot00000000000000#!/bin/sh rm -f ltconfig ltmain.sh config.cache aclocal.m4 config.guess config.sub # remove the autoconf cache rm -rf autom4te*.cache # create a .version file for configure.in if test ! -f .version; then # Building from SVN rather than in a release echo 0.0.0-dev > .version # for the documentation: date +"%e %B %Y" | tr -d '\n' > doc/date.xml echo -n 0.0.0-dev > doc/version.xml fi set -e echo -n "libtoolize... " LIBTOOLIZE=${LIBTOOLIZE:-libtoolize} if ${LIBTOOLIZE} --help | grep -- --install > /dev/null; then ${LIBTOOLIZE} --copy --force --install >/dev/null; else ${LIBTOOLIZE} --copy --force >/dev/null fi echo -n "aclocal... " ${ACLOCAL:-aclocal} -I macros echo -n "autoheader... " ${AUTOHEADER:-autoheader} echo -n "autoconf... " ${AUTOCONF:-autoconf} -Wall echo okay. # remove the autoconf cache rm -rf autom4te*.cache davix-R_0_5_0/deps/libneon/config.cmake.in000066400000000000000000000054621257152637300205310ustar00rootroot00000000000000#ifndef CONFIG_H #define CONFIG_H // portability mapper #include // force debug support #define NE_DEBUGGING // force dav #define NE_HAVE_DAV 1 // Force TLS and thread safety callback once forever #define HAVE_CRYPTO_SET_IDPTR_CALLBACK #define NE_HAVE_TS_SSL //has malloc #cmakedefine HAVE_MALLOC_H 1 // has errno #cmakedefine HAVE_ERRNO_H 1 // has stdlib #cmakedefine HAVE_STDLIB_H 1 // has fcntl #cmakedefine HAVE_FCNTL_H 1 // string and strings #cmakedefine HAVE_STRING_H 1 #cmakedefine HAVE_STRINGS_H 1 // has unistd #cmakedefine HAVE_UNISTD_H 1 // has I18N #cmakedefine NE_HAVE_I18N 1 // ipv6 support #cmakedefine HAVE_IPV6 1 // tcp no delay #cmakedefine TCP_NODELAY 1 // has system time #cmakedefine HAVE_SYSTIME_H 1 // has system socket #cmakedefine HAVE_SYSSOCKET_H 1 // has setsockopt #cmakedefine HAVE_SETSOCKOPT 1 // has signal support #cmakedefine HAVE_SIGNAL_H 1 #ifdef HAVE_SIGNAL_H #define HAVE_SIGNAL #endif // has getaddrinfo #cmakedefine HAVE_GETADDRINFO_H 1 #ifdef HAVE_GETADDRINFO_H #define USE_GETADDRINFO 1 #endif // has locale #cmakedefine HAVE_LOCALE_H 1 // general SSL support #cmakedefine NE_HAVE_SSL 1 // openssl support #cmakedefine HAVE_OPENSSL 1 //gnutls support #cmakedefine HAVE_GNUTLS 1 // check clock #cmakedefine HAVE_CLOCK_GETTIME 1 #cmakedefine HAVE_GETTIMEOFDAY 1 // libxml support #cmakedefine HAVE_LIBXML 1 // libexpat support #cmakedefine HAVE_EXPAT 1 // has strptime #cmakedefine HAVE_STRPTIME_H 1 #ifndef HAVE_STRPTIME_H # define strptime __strptime #endif // has mempcpy //#cmakedefine HAVE_MEMPCPY_H 1 //#include #cmakedefine HAVE_STRLCPY_H 1 // poll #cmakedefine HAVE_POLL_H 1 #ifdef HAVE_POLL_H #define NE_USE_POLL #endif //select #cmakedefine HAVE_SYS_SELECT_H 1 //net #cmakedefine HAVE_NETINET_IN_H 1 #cmakedefine HAVE_NETINET_TCP_H 1 #cmakedefine HAVE_ARPA_INET_H 1 #cmakedefine HAVE_NETDB_H 1 // in_add_t #cmakedefine HAVE_IN_ADDR_T 1 #ifndef HAVE_IN_ADDR_T #define in_addr_t unsigned int #endif // socklen_t #cmakedefine HAVE_SOCKLEN_T 1 #ifndef HAVE_SOCKLEN_T #define socklen_t int #endif // type size #define SIZEOF_INT @DEF_SIZEOF_INT@ #define SIZEOF_LONG @DEF_SIZEOF_LONG@ #define SIZEOF_SIZE_T @DEF_SIZEOF_SIZE_T@ #define SIZEOF_SSIZE_T @DEF_SIZEOF_SSIZE_T@ #define SIZEOF_OFF_T @DEF_SIZEOF_OFF_T@ #if( SIZEOF_INT == SIZEOF_SIZE_T ) # define NE_FMT_SIZE_T "d" #else # define NE_FMT_SIZE_T "ld" #endif #if( SIZEOF_INT == SIZEOF_SSIZE_T ) # define NE_FMT_SSIZE_T "d" #else # define NE_FMT_SSIZE_T "ld" #endif #if( SIZEOF_INT == SIZEOF_OFF_T ) # define NE_FMT_OFF_T "d" #else # define NE_FMT_OFF_T "ld" #endif // // Win 32 mapper #if( defined _WIN32 )|| ( defined __MINGW32__ ) // macros #define __PLATFORM_WINDOWS__ // windows headers #include #include #endif /* end of win32*/ #endif // CONFIG_H davix-R_0_5_0/deps/libneon/config.guess000077500000000000000000001274321257152637300201770ustar00rootroot00000000000000#! /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-02-10' # 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 ;; *: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 ;; *: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 ;; 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 #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # 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: davix-R_0_5_0/deps/libneon/config.h.in000066400000000000000000000313701257152637300176750ustar00rootroot00000000000000/* config.h.in. Generated from configure.in by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define to specific EGD socket path */ #undef EGD_PATH /* Define if EGD should be supported */ #undef ENABLE_EGD /* Define if GSS_C_NT_HOSTBASED_SERVICE is not defined otherwise */ #undef GSS_C_NT_HOSTBASED_SERVICE /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to 1 if you have the `bind_textdomain_codeset' function. */ #undef HAVE_BIND_TEXTDOMAIN_CODESET /* Define to 1 if you have the `CRYPTO_set_idptr_callback' function. */ #undef HAVE_CRYPTO_SET_IDPTR_CALLBACK /* Define to 1 if you have the declaration of `h_errno', and to 0 if you don't. */ #undef HAVE_DECL_H_ERRNO /* Define to 1 if you have the declaration of `stpcpy', and to 0 if you don't. */ #undef HAVE_DECL_STPCPY /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define if you have expat */ #undef HAVE_EXPAT /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fstat64' function. */ #undef HAVE_FSTAT64 /* Define to 1 if you have the `gai_strerror' function. */ #undef HAVE_GAI_STRERROR /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `getnameinfo' function. */ #undef HAVE_GETNAMEINFO /* Define to 1 if you have the `getsockopt' function. */ #undef HAVE_GETSOCKOPT /* Define if GnuTLS support is enabled */ #undef HAVE_GNUTLS /* Define to 1 if you have the `gnutls_certificate_get_x509_cas' function. */ #undef HAVE_GNUTLS_CERTIFICATE_GET_X509_CAS /* Define to 1 if you have the `gnutls_certificate_verify_peers2' function. */ #undef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS2 /* Define to 1 if you have the `gnutls_session_get_data2' function. */ #undef HAVE_GNUTLS_SESSION_GET_DATA2 /* Define to 1 if you have the `gnutls_sign_callback_set' function. */ #undef HAVE_GNUTLS_SIGN_CALLBACK_SET /* Define to 1 if you have the `gnutls_x509_dn_get_rdn_ava' function. */ #undef HAVE_GNUTLS_X509_DN_GET_RDN_AVA /* Define if GSSAPI support is enabled */ #undef HAVE_GSSAPI /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_GENERIC_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_H /* Define to 1 if you have the `gss_init_sec_context' function. */ #undef HAVE_GSS_INIT_SEC_CONTEXT /* Define to 1 if you have the `hstrerror' function. */ #undef HAVE_HSTRERROR /* Define to 1 if you have the `iconv' function. */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ #undef HAVE_ICONV_H /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if you have the `inet_pton' function. */ #undef HAVE_INET_PTON /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `isatty' function. */ #undef HAVE_ISATTY /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H /* Define if libproxy is supported */ #undef HAVE_LIBPROXY /* Define if you have libxml */ #undef HAVE_LIBXML /* Define to 1 if you have the header file. */ #undef HAVE_LIBXML_PARSER_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBXML_XMLVERSION_H /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `lseek64' function. */ #undef HAVE_LSEEK64 /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_TCP_H /* Define if NTLM is supported */ #undef HAVE_NTLM /* Define if OpenSSL support is enabled */ #undef HAVE_OPENSSL /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_OPENSSLV_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define if pakchois library supported */ #undef HAVE_PAKCHOIS /* Define to 1 if you have the `pipe' function. */ #undef HAVE_PIPE /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the `pthread_mutex_init' function. */ #undef HAVE_PTHREAD_MUTEX_INIT /* Define to 1 if you have the `pthread_mutex_lock' function. */ #undef HAVE_PTHREAD_MUTEX_LOCK /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the `setsockopt' function. */ #undef HAVE_SETSOCKOPT /* Define to 1 if you have the `setvbuf' function. */ #undef HAVE_SETVBUF /* Define to 1 if you have the `shutdown' function. */ #undef HAVE_SHUTDOWN /* Define to 1 if you have the `signal' function. */ #undef HAVE_SIGNAL /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if the system has the type `socklen_t'. */ #undef HAVE_SOCKLEN_T /* Define to 1 if you have the `SSL_SESSION_cmp' function. */ #undef HAVE_SSL_SESSION_CMP /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `stpcpy' function. */ #undef HAVE_STPCPY /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL /* Define to 1 if you have the `strtoq' function. */ #undef HAVE_STRTOQ /* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_GMTOFF /* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM___TM_GMTOFF /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define if the timezone global is available */ #undef HAVE_TIMEZONE /* Use trio printf replacement library */ #undef HAVE_TRIO /* Define to 1 if you have the header file. */ #undef HAVE_TRIO_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to be location of localedir */ #undef LOCALEDIR /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Defined when neon is built as a library */ #undef NEON_IS_LIBRARY /* Define to be the neon version string */ #undef NEON_VERSION /* Define to enable debugging */ #undef NE_DEBUGGING /* Define to be printf format string for ne_off_t */ #undef NE_FMT_NE_OFF_T /* Define to be printf format string for off64_t */ #undef NE_FMT_OFF64_T /* Define to be printf format string for off_t */ #undef NE_FMT_OFF_T /* Define to be printf format string for size_t */ #undef NE_FMT_SIZE_T /* Define to be printf format string for ssize_t */ #undef NE_FMT_SSIZE_T /* Define to be printf format string for time_t */ #undef NE_FMT_TIME_T /* Define to be printf format string for XML_Size */ #undef NE_FMT_XML_SIZE /* Defined if DAV is supported */ #undef NE_HAVE_DAV /* Defined if I18N is supported */ #undef NE_HAVE_I18N /* Defined if IPV6 is supported */ #undef NE_HAVE_IPV6 /* Defined if LFS is supported */ #undef NE_HAVE_LFS /* Defined if LIBPXY is supported */ #undef NE_HAVE_LIBPXY /* Defined if SSL is supported */ #undef NE_HAVE_SSL /* Defined if TS_SSL is supported */ #undef NE_HAVE_TS_SSL /* Defined if ZLIB is supported */ #undef NE_HAVE_ZLIB /* Define to be filename of an SSL CA root bundle */ #undef NE_SSL_CA_BUNDLE /* Define if poll() should be used */ #undef NE_USE_POLL /* Define to be neon library major version */ #undef NE_VERSION_MAJOR /* Define to be neon library minor version */ #undef NE_VERSION_MINOR /* Define to be neon library patch version */ #undef NE_VERSION_PATCH /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG /* The size of `off64_t', as computed by sizeof. */ #undef SIZEOF_OFF64_T /* The size of `off_t', as computed by sizeof. */ #undef SIZEOF_OFF_T /* The size of `size_t', as computed by sizeof. */ #undef SIZEOF_SIZE_T /* The size of `ssize_t', as computed by sizeof. */ #undef SIZEOF_SSIZE_T /* The size of `time_t', as computed by sizeof. */ #undef SIZEOF_TIME_T /* The size of `XML_Size', as computed by sizeof. */ #undef SIZEOF_XML_SIZE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if strerror_r returns char *. */ #undef STRERROR_R_CHAR_P /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define if getaddrinfo supports AI_ADDRCONFIG */ #undef USE_GAI_ADDRCONFIG /* Define if getaddrinfo() should be used */ #undef USE_GETADDRINFO /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Always defined to enable GNU extensions */ #undef _GNU_SOURCE /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define if in_addr_t is not available */ #undef in_addr_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define if socklen_t is not available */ #undef socklen_t /* Enable leak-tracking versions of ne_*alloc when NEON_MEMLEAK is enabled */ #ifdef NEON_MEMLEAK # include "memleak.h" #endif #if defined(HAVE_STPCPY) && defined(HAVE_DECL_STPCPY) && !HAVE_DECL_STPCPY && !defined(stpcpy) char *stpcpy(char *, const char *); #endif davix-R_0_5_0/deps/libneon/config.hw000066400000000000000000000042621257152637300174570ustar00rootroot00000000000000/* -*- c -*- Win32 config.h Copyright (C) 1999-2000, Peter Boos Copyright (C) 2002-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif #ifdef WIN32 #define NEON_VERSION "0.29.6" #define NE_VERSION_MAJOR (0) #define NE_VERSION_MINOR (29) #define HAVE_ERRNO_H #define HAVE_LIMITS_H #define HAVE_STDLIB_H #define HAVE_STRING_H #define HAVE_MEMCPY #define HAVE_SETSOCKOPT #define HAVE_SSPI /* Define to enable debugging */ #define NE_DEBUGGING 1 #define NE_FMT_SIZE_T "u" #define NE_FMT_SSIZE_T "d" #define NE_FMT_OFF_T "ld" #define NE_FMT_NE_OFF_T NE_FMT_OFF_T #ifndef NE_FMT_XML_SIZE #define NE_FMT_XML_SIZE "d" #endif /* needs adjusting for Win64... */ #define SIZEOF_INT 4 #define SIZEOF_LONG 4 /* Win32 uses a underscore, so we use a macro to eliminate that. */ #define snprintf _snprintf /* VS2008 has this already defined */ #if (_MSC_VER < 1500) #define vsnprintf _vsnprintf #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 #define strcasecmp _strcmpi #define strncasecmp _strnicmp #else #define strcasecmp strcmpi #define strncasecmp strnicmp #endif #define ssize_t int #define inline __inline #define off_t _off_t #ifndef USE_GETADDRINFO #define in_addr_t unsigned int #endif typedef int socklen_t; #include #define read _read #endif davix-R_0_5_0/deps/libneon/config.hw.in000066400000000000000000000043001257152637300200550ustar00rootroot00000000000000/* -*- c -*- Win32 config.h Copyright (C) 1999-2000, Peter Boos Copyright (C) 2002-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif #ifdef WIN32 #define NEON_VERSION "@VERSION@" #define NE_VERSION_MAJOR (@MAJOR@) #define NE_VERSION_MINOR (@MINOR@) #define HAVE_ERRNO_H #define HAVE_LIMITS_H #define HAVE_STDLIB_H #define HAVE_STRING_H #define HAVE_MEMCPY #define HAVE_SETSOCKOPT #define HAVE_SSPI /* Define to enable debugging */ #define NE_DEBUGGING 1 #define NE_FMT_SIZE_T "u" #define NE_FMT_SSIZE_T "d" #define NE_FMT_OFF_T "ld" #define NE_FMT_NE_OFF_T NE_FMT_OFF_T #ifndef NE_FMT_XML_SIZE #define NE_FMT_XML_SIZE "d" #endif /* needs adjusting for Win64... */ #define SIZEOF_INT 4 #define SIZEOF_LONG 4 /* Win32 uses a underscore, so we use a macro to eliminate that. */ #define snprintf _snprintf /* VS2008 has this already defined */ #if (_MSC_VER < 1500) #define vsnprintf _vsnprintf #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 #define strcasecmp _strcmpi #define strncasecmp _strnicmp #else #define strcasecmp strcmpi #define strncasecmp strnicmp #endif #define ssize_t int #define inline __inline #define off_t _off_t #ifndef USE_GETADDRINFO #define in_addr_t unsigned int #endif typedef int socklen_t; #include #define read _read #endif davix-R_0_5_0/deps/libneon/config.sub000077500000000000000000001051761257152637300176430ustar00rootroot00000000000000#! /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-02-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-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*) 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 | 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-* \ | 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 ;; 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* \ | -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* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -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 ;; 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: davix-R_0_5_0/deps/libneon/configure000077500000000000000000020046271257152637300175700ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for neon 0.29.6. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # # Copyright 2000-2010 Joe Orton and others # This configure script may be copied, distributed and modified under the # terms of the GNU Library General Public license; see src/COPYING.LIB for # more details. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do 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 as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do 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 " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: neon@lists.manyfish.co.uk about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='neon' PACKAGE_TARNAME='neon' PACKAGE_VERSION='0.29.6' PACKAGE_STRING='neon 0.29.6' PACKAGE_BUGREPORT='neon@lists.manyfish.co.uk' PACKAGE_URL='' ac_unique_file="src/ne_request.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS ALLOW_INSTALL TESTS HELPERS user_LDFLAGS top_builddir NEON_BUILD_BUNDLED NEON_VERSION ALL_LINGUAS NEON_PC_LIBS TEST_LDFLAGS PK12UTIL CERTUTIL OPENSSL NE_FLAG_I18N XML2_CONFIG NEON_LINK_FLAGS NEON_EXTRAOBJS NEONOBJS NEON_OBJEXT NEON_TARGET NE_FLAG_DAV OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL AWK RANLIB STRIP ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL NEON_LTLIBS NEON_LIBS NEON_CFLAGS NE_FLAG_LIBPXY KRB5_CONFIG NEON_SUPPORTS_SSL NE_FLAG_TS_SSL GNUTLS_CONFIG NE_FLAG_SSL PKG_CONFIG NE_FLAG_ZLIB NE_FLAG_IPV6 LIBOBJS NE_FLAG_LFS SET_MAKE EGREP GREP CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_libs enable_webdav with_zlib with_ssl with_egd with_pakchois with_ca_bundle enable_threadsafe_ssl with_gssapi with_libproxy enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock with_libxml2 with_expat enable_nls enable_debug enable_warnings enable_memleak enable_tests_install enable_ld_version_script ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures neon 0.29.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/neon] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of neon 0.29.6:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-webdav disable WebDAV support --enable-threadsafe-ssl=posix enable SSL library thread-safety using POSIX threads: suitable CC/CFLAGS/LIBS must be used to make the POSIX library interfaces available --enable-shared[=PKGS] build shared libraries [default=no] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-nls disable internationalization support --disable-debug disable runtime debugging messages --enable-warnings enable compiler warnings --enable-memleak for test builds only: enable memory leak checking --enable-tests-install enable installation of the test suite --enable-ld-version-script enable linker version script (default is enabled when possible) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-libs=DIR[:DIR2...] look for support libraries in DIR/{bin,lib,include} --without-zlib disable zlib support --with-ssl=openssl|gnutls enable SSL support (default OpenSSL) --with-egd[=PATH] enable EGD support [using EGD socket at PATH] --without-pakchois disable support for PKCS#11 using pakchois --with-ca-bundle specify filename of an SSL CA root bundle --without-gssapi disable GSSAPI support --without-libproxy disable libproxy support --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-libxml2 force use of libxml 2.x --with-expat force use of expat Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF neon configure 0.29.6 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Copyright 2000-2010 Joe Orton and others This configure script may be copied, distributed and modified under the terms of the GNU Library General Public license; see src/COPYING.LIB for more details. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ---------------------------------------- ## ## Report this to neon@lists.manyfish.co.uk ## ## ---------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by neon $as_me 0.29.6, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` 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 || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" # Check whether --with-libs was given. if test "${with_libs+set}" = set; then : withval=$with_libs; case $with_libs in yes|no) as_fn_error $? "--with-libs must be passed a directory argument" "$LINENO" 5 ;; *) ne_save_IFS=$IFS; IFS=: for dir in $with_libs; do ne_add_CPPFLAGS="$ne_add_CPPFLAGS -I${dir}/include" ne_add_LDFLAGS="$ne_add_LDFLAGS -L${dir}/lib" ne_add_PATH="${ne_add_PATH}${dir}/bin:" PKG_CONFIG_PATH=${PKG_CONFIG_PATH}${PKG_CONFIG_PATH+:}${dir}/lib/pkgconfig done IFS=$ne_save_IFS CPPFLAGS="${ne_add_CPPFLAGS} $CPPFLAGS" LDFLAGS="${ne_add_LDFLAGS} $LDFLAGS" PATH=${ne_add_PATH}$PATH export PKG_CONFIG_PATH ;; esac fi # Pass through initial LDFLAGS verbatim to neon-config, so that extra # libraries which are detected (e.g. OpenSSL) can still be found when # building using the --libs output of neon-config. user_LDFLAGS=$LDFLAGS # By default, allow 'make install' to work. ALLOW_INSTALL=yes $as_echo "#define _GNU_SOURCE 1" >>confdefs.h $as_echo "#define NEON_IS_LIBRARY 1" >>confdefs.h ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # 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" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /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 for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Check whether --enable-webdav was given. if test "${enable_webdav+set}" = set; then : enableval=$enable_webdav; fi if test "$enable_webdav" = "no"; then neon_no_webdav=yes neon_no_acl=yes NEON_NEED_XML_PARSER=no neon_xml_parser_message="none needed" else # Yes, we do need an XML parser. The _BUNDLED macros handle # this normally. NEON_NEED_XML_PARSER=yes fi # The bundled macros also set this, which makes sure we recurse # into the 'src' directory. NEON_BUILD_BUNDLED=yes # Define NEON_VERSION etc and make the appropriate substitutions. # Define the current versions. NE_VERSION_MAJOR=0 NE_VERSION_MINOR=29 NE_VERSION_PATCH=6 NE_VERSION_TAG= # 0.29.x is backwards-compatible to 0.27.x, so AGE=2 NE_LIBTOOL_VERSINFO="29:${NE_VERSION_PATCH}:2" NEON_VERSION="${NE_VERSION_MAJOR}.${NE_VERSION_MINOR}.${NE_VERSION_PATCH}${NE_VERSION_TAG}" cat >>confdefs.h <<_ACEOF #define NEON_VERSION "${NEON_VERSION}" _ACEOF cat >>confdefs.h <<_ACEOF #define NE_VERSION_MAJOR (${NE_VERSION_MAJOR}) _ACEOF cat >>confdefs.h <<_ACEOF #define NE_VERSION_MINOR (${NE_VERSION_MINOR}) _ACEOF cat >>confdefs.h <<_ACEOF #define NE_VERSION_PATCH (${NE_VERSION_PATCH}) _ACEOF ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" if test "x$ac_cv_header_minix_config_h" = xyes; then : MINIX=yes else MINIX= fi if test "$MINIX" = yes; then $as_echo "#define _POSIX_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h $as_echo "#define _MINIX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } if ${ac_cv_safe_to_define___extensions__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_safe_to_define___extensions__=yes else ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } test $ac_cv_safe_to_define___extensions__ = yes && $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h $as_echo "#define _ALL_SOURCE 1" >>confdefs.h $as_echo "#define _GNU_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi # Check for Darwin, which needs extra cpp and linker flags. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uname" >&5 $as_echo_n "checking for uname... " >&6; } if ${ne_cv_os_uname+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_os_uname=`uname -s 2>/dev/null` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_os_uname" >&5 $as_echo "$ne_cv_os_uname" >&6; } if test "$ne_cv_os_uname" = "Darwin"; then CPPFLAGS="$CPPFLAGS -no-cpp-precomp" LDFLAGS="$LDFLAGS -flat_namespace" # poll has various issues in various Darwin releases if test x${ac_cv_func_poll+set} != xset; then ac_cv_func_poll=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 $as_echo_n "checking size of long long... " >&6; } if ${ac_cv_sizeof_long_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 $as_echo "$ac_cv_sizeof_long_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF if test "$GCC" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc -Wformat -Werror sanity" >&5 $as_echo_n "checking for gcc -Wformat -Werror sanity... " >&6; } if ${ne_cv_cc_werror+:} false; then : $as_echo_n "(cached) " >&6 else # See whether a simple test program will compile without errors. ne_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -Wformat -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { int i = 42; printf("%d", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_cc_werror=yes else ne_cv_cc_werror=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CPPFLAGS=$ne_save_CPPFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_cc_werror" >&5 $as_echo "$ne_cv_cc_werror" >&6; } ne_fmt_trycompile=$ne_cv_cc_werror else ne_fmt_trycompile=no fi # These checks are done whether or not the bundled neon build # is used. for ac_header in errno.h stdarg.h string.h stdlib.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 $as_echo_n "checking size of size_t... " >&6; } if ${ac_cv_sizeof_size_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default "; then : else if test "$ac_cv_type_size_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (size_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_size_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 $as_echo "$ac_cv_sizeof_size_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SIZE_T $ac_cv_sizeof_size_t _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print size_t" >&5 $as_echo_n "checking how to print size_t... " >&6; } if ${ne_cv_fmt_size_t+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_size_t=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in u lu llu; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { size_t i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_size_t=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_size_t in $ac_cv_sizeof_int) ne_cv_fmt_size_t="u" ;; $ac_cv_sizeof_long) ne_cv_fmt_size_t="lu" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_size_t="llu" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_size_t" >&5 $as_echo "$ne_cv_fmt_size_t" >&6; } if test "x$ne_cv_fmt_size_t" = "xnone"; then as_fn_error $? "format string for size_t not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_SIZE_T "$ne_cv_fmt_size_t" _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5 $as_echo_n "checking size of off_t... " >&6; } if ${ac_cv_sizeof_off_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default "; then : else if test "$ac_cv_type_off_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (off_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_off_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5 $as_echo "$ac_cv_sizeof_off_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_OFF_T $ac_cv_sizeof_off_t _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print off_t" >&5 $as_echo_n "checking how to print off_t... " >&6; } if ${ne_cv_fmt_off_t+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_off_t=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in d ld lld; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off_t i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_off_t=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_off_t in $ac_cv_sizeof_int) ne_cv_fmt_off_t="d" ;; $ac_cv_sizeof_long) ne_cv_fmt_off_t="ld" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_off_t="lld" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_off_t" >&5 $as_echo "$ne_cv_fmt_off_t" >&6; } if test "x$ne_cv_fmt_off_t" = "xnone"; then as_fn_error $? "format string for off_t not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_OFF_T "$ne_cv_fmt_off_t" _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ssize_t" >&5 $as_echo_n "checking size of ssize_t... " >&6; } if ${ac_cv_sizeof_ssize_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ssize_t))" "ac_cv_sizeof_ssize_t" "$ac_includes_default "; then : else if test "$ac_cv_type_ssize_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (ssize_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_ssize_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ssize_t" >&5 $as_echo "$ac_cv_sizeof_ssize_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SSIZE_T $ac_cv_sizeof_ssize_t _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print ssize_t" >&5 $as_echo_n "checking how to print ssize_t... " >&6; } if ${ne_cv_fmt_ssize_t+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_ssize_t=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in d ld lld; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { ssize_t i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_ssize_t=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_ssize_t in $ac_cv_sizeof_int) ne_cv_fmt_ssize_t="d" ;; $ac_cv_sizeof_long) ne_cv_fmt_ssize_t="ld" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_ssize_t="lld" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_ssize_t" >&5 $as_echo "$ne_cv_fmt_ssize_t" >&6; } if test "x$ne_cv_fmt_ssize_t" = "xnone"; then as_fn_error $? "format string for ssize_t not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_SSIZE_T "$ne_cv_fmt_ssize_t" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac ac_fn_c_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" if test "x$ac_cv_have_decl_strerror_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR_R $ac_have_decl _ACEOF for ac_func in strerror_r do : ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r" if test "x$ac_cv_func_strerror_r" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRERROR_R 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5 $as_echo_n "checking whether strerror_r returns char *... " >&6; } if ${ac_cv_func_strerror_r_char_p+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_func_strerror_r_char_p=no if test $ac_cv_have_decl_strerror_r = yes; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); char *p = strerror_r (0, buf, sizeof buf); return !p || x; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_func_strerror_r_char_p=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else # strerror_r is not declared. Choose between # systems that have relatively inaccessible declarations for the # function. BeOS and DEC UNIX 4.0 fall in this category, but the # former has a strerror_r that returns char*, while the latter # has a strerror_r that returns `int'. # This test should segfault on the DEC system. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default extern char *strerror_r (); int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); return ! isalpha (x); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_strerror_r_char_p=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5 $as_echo "$ac_cv_func_strerror_r_char_p" >&6; } if test $ac_cv_func_strerror_r_char_p = yes; then $as_echo "#define STRERROR_R_CHAR_P 1" >>confdefs.h fi for ac_func in snprintf vsnprintf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else ne_save_LIBS=$LIBS LIBS="$LIBS -lm" # Always need -lm { $as_echo "$as_me:${as_lineno-$LINENO}: checking for trio_vsnprintf in -ltrio" >&5 $as_echo_n "checking for trio_vsnprintf in -ltrio... " >&6; } if ${ac_cv_lib_trio_trio_vsnprintf+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltrio $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char trio_vsnprintf (); int main () { return trio_vsnprintf (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_trio_trio_vsnprintf=yes else ac_cv_lib_trio_trio_vsnprintf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_trio_trio_vsnprintf" >&5 $as_echo "$ac_cv_lib_trio_trio_vsnprintf" >&6; } if test "x$ac_cv_lib_trio_trio_vsnprintf" = xyes; then : for ac_header in trio.h do : ac_fn_c_check_header_mongrel "$LINENO" "trio.h" "ac_cv_header_trio_h" "$ac_includes_default" if test "x$ac_cv_header_trio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TRIO_H 1 _ACEOF else as_fn_error $? "trio installation problem? libtrio found but not trio.h" "$LINENO" 5 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: using trio printf replacement library" >&5 $as_echo "$as_me: using trio printf replacement library" >&6;} NEON_LIBS="$NEON_LIBS -ltrio -lm" $as_echo "#define HAVE_TRIO 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: no vsnprintf/snprintf detected in C library" >&5 $as_echo "$as_me: no vsnprintf/snprintf detected in C library" >&6;} as_fn_error $? "Install the trio library from http://daniel.haxx.se/projects/trio/" "$LINENO" 5 fi LIBS=$ne_save_LIBS break fi done for ac_header in sys/time.h limits.h sys/select.h arpa/inet.h libintl.h \ signal.h sys/socket.h netinet/in.h netinet/tcp.h netdb.h sys/poll.h \ sys/limits.h fcntl.h iconv.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default /* netinet/tcp.h requires netinet/in.h on some platforms. */ #ifdef HAVE_NETINET_IN_H #include #endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for timezone global" >&5 $as_echo_n "checking for timezone global... " >&6; } if ${ne_cv_cc_timezone+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { time_t t = 0 - timezone; timezone = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_cc_timezone=yes else ne_cv_cc_timezone=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_cc_timezone" >&5 $as_echo "$ne_cv_cc_timezone" >&6; } if test "$ne_cv_cc_timezone" = "yes"; then $as_echo "#define HAVE_TIMEZONE 1" >>confdefs.h fi if test -z "$ac_cv_sizeof_off_t"; then NE_FLAG_LFS=no ne_LFS_message="LFS support omitted: off_t size unknown!" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS support omitted: off_t size unknown!" >&5 $as_echo "$as_me: LFS support omitted: off_t size unknown!" >&6;} elif test $ac_cv_sizeof_off_t != 4; then NE_FLAG_LFS=no ne_LFS_message="LFS support unnecessary, off_t is not 32-bit" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS support unnecessary, off_t is not 32-bit" >&5 $as_echo "$as_me: LFS support unnecessary, off_t is not 32-bit" >&6;} for ac_func in strtoll strtoq do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF break fi done elif test -z "$ac_cv_sizeof_long_long"; then NE_FLAG_LFS=no ne_LFS_message="LFS support omitted: long long size unknown" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS support omitted: long long size unknown" >&5 $as_echo "$as_me: LFS support omitted: long long size unknown" >&6;} elif test $ac_cv_sizeof_long_long != 8; then NE_FLAG_LFS=no ne_LFS_message="LFS support omitted: long long not 64-bit" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS support omitted: long long not 64-bit" >&5 $as_echo "$as_me: LFS support omitted: long long not 64-bit" >&6;} else ne_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" ac_fn_c_check_type "$LINENO" "off64_t" "ac_cv_type_off64_t" "$ac_includes_default" if test "x$ac_cv_type_off64_t" = xyes; then : # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off64_t" >&5 $as_echo_n "checking size of off64_t... " >&6; } if ${ac_cv_sizeof_off64_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off64_t))" "ac_cv_sizeof_off64_t" "$ac_includes_default "; then : else if test "$ac_cv_type_off64_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (off64_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_off64_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off64_t" >&5 $as_echo "$ac_cv_sizeof_off64_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_OFF64_T $ac_cv_sizeof_off64_t _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print off64_t" >&5 $as_echo_n "checking how to print off64_t... " >&6; } if ${ne_cv_fmt_off64_t+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_off64_t=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in d ld lld; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { off64_t i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_off64_t=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_off64_t in $ac_cv_sizeof_int) ne_cv_fmt_off64_t="d" ;; $ac_cv_sizeof_long) ne_cv_fmt_off64_t="ld" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_off64_t="lld" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_off64_t" >&5 $as_echo "$ne_cv_fmt_off64_t" >&6; } if test "x$ne_cv_fmt_off64_t" = "xnone"; then as_fn_error $? "format string for off64_t not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_OFF64_T "$ne_cv_fmt_off64_t" _ACEOF ne_lfsok=no for ac_func in strtoll strtoq do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF ne_lfsok=yes; break fi done for ac_func in lseek64 fstat64 do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else ne_lfsok=no; break fi done if test x$ne_lfsok = xyes; then NE_FLAG_LFS=yes $as_echo "#define NE_HAVE_LFS 1" >>confdefs.h ne_LFS_message="LFS (large file) support enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS (large file) support enabled" >&5 $as_echo "$as_me: LFS (large file) support enabled" >&6;} NEON_CFLAGS="$NEON_CFLAGS -D_LARGEFILE64_SOURCE -DNE_LFS" ne_save_CPPFLAGS="$CPPFLAGS -DNE_LFS" else NE_FLAG_LFS=no ne_LFS_message="LFS support omitted: 64-bit support functions not found" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS support omitted: 64-bit support functions not found" >&5 $as_echo "$as_me: LFS support omitted: 64-bit support functions not found" >&6;} fi else NE_FLAG_LFS=no ne_LFS_message="LFS support omitted: off64_t type not found" { $as_echo "$as_me:${as_lineno-$LINENO}: LFS support omitted: off64_t type not found" >&5 $as_echo "$as_me: LFS support omitted: off64_t type not found" >&6;} fi CPPFLAGS=$ne_save_CPPFLAGS fi if test "$NE_FLAG_LFS" = "yes"; then cat >>confdefs.h <<_ACEOF #define NE_FMT_NE_OFF_T NE_FMT_OFF64_T _ACEOF else cat >>confdefs.h <<_ACEOF #define NE_FMT_NE_OFF_T NE_FMT_OFF_T _ACEOF fi ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes; then : $as_echo "#define HAVE_STRCASECMP 1" >>confdefs.h else case " $LIBOBJS " in *" strcasecmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strcasecmp.$ac_objext" ;; esac fi for ac_func in signal setvbuf setsockopt stpcpy poll fcntl getsockopt do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x${ac_cv_func_poll}${ac_cv_header_sys_poll_h}y" = "xyesyesy"; then $as_echo "#define NE_USE_POLL 1" >>confdefs.h fi if test "$ac_cv_func_stpcpy" = "yes"; then ac_fn_c_check_decl "$LINENO" "stpcpy" "ac_cv_have_decl_stpcpy" "$ac_includes_default" if test "x$ac_cv_have_decl_stpcpy" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STPCPY $ac_have_decl _ACEOF fi # Modern AIXes with the "Linux-like" libc have an undeclared stpcpy # Unixware 7 can only link gethostbyname with -lnsl -lsocket # Pick up -lsocket first, then the gethostbyname check will work. # Haiku requires -lnetwork for socket functions. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 $as_echo_n "checking for library containing socket... " >&6; } if ${ne_cv_libsfor_socket+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { socket(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_socket="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_socket="not found" for lib in socket inet ws2_32 network; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall socket();" ;; *) ne__code="socket();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_socket="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_socket" >&5 $as_echo "$ne_cv_libsfor_socket" >&6; } if test "$ne_cv_libsfor_socket" = "not found"; then as_fn_error $? "could not find library containing socket" "$LINENO" 5 elif test "$ne_cv_libsfor_socket" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_socket $NEON_LIBS" fi # Enable getaddrinfo support if it, gai_strerror and inet_ntop are # all available. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5 $as_echo_n "checking for library containing getaddrinfo... " >&6; } if ${ne_cv_libsfor_getaddrinfo+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { getaddrinfo(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_getaddrinfo="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_getaddrinfo="not found" for lib in nsl; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall getaddrinfo();" ;; *) ne__code="getaddrinfo();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_getaddrinfo="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_getaddrinfo" >&5 $as_echo "$ne_cv_libsfor_getaddrinfo" >&6; } if test "$ne_cv_libsfor_getaddrinfo" = "not found"; then ne_enable_gai=no elif test "$ne_cv_libsfor_getaddrinfo" = "none needed"; then # HP-UX boxes commonly get into a state where getaddrinfo is present # but borked: http://marc.theaimsgroup.com/?l=apr-dev&m=107730955207120&w=2 case x`uname -sr 2>/dev/null`y in xHP-UX*11.[01]*y) { $as_echo "$as_me:${as_lineno-$LINENO}: getaddrinfo support disabled on HP-UX 11.0x/11.1x" >&5 $as_echo "$as_me: getaddrinfo support disabled on HP-UX 11.0x/11.1x" >&6;} ;; *) ne_enable_gai=yes ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in gai_strerror getnameinfo inet_ntop inet_pton do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else ne_enable_gai=no; break fi done LIBS=$ne_cf_save_LIBS ;; esac else NEON_LIBS="$ne_cv_libsfor_getaddrinfo $NEON_LIBS" # HP-UX boxes commonly get into a state where getaddrinfo is present # but borked: http://marc.theaimsgroup.com/?l=apr-dev&m=107730955207120&w=2 case x`uname -sr 2>/dev/null`y in xHP-UX*11.[01]*y) { $as_echo "$as_me:${as_lineno-$LINENO}: getaddrinfo support disabled on HP-UX 11.0x/11.1x" >&5 $as_echo "$as_me: getaddrinfo support disabled on HP-UX 11.0x/11.1x" >&6;} ;; *) ne_enable_gai=yes ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in gai_strerror getnameinfo inet_ntop inet_pton do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else ne_enable_gai=no; break fi done LIBS=$ne_cf_save_LIBS ;; esac fi if test $ne_enable_gai = yes; then NE_FLAG_IPV6=yes $as_echo "#define NE_HAVE_IPV6 1" >>confdefs.h ne_IPV6_message="IPv6 support is enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: IPv6 support is enabled" >&5 $as_echo "$as_me: IPv6 support is enabled" >&6;} $as_echo "#define USE_GETADDRINFO 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working AI_ADDRCONFIG" >&5 $as_echo_n "checking for working AI_ADDRCONFIG... " >&6; } if ${ne_cv_gai_addrconfig+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ne_cv_gai_addrconfig=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct addrinfo hints = {0}, *result; hints.ai_flags = AI_ADDRCONFIG; if (getaddrinfo("localhost", NULL, &hints, &result) != 0) return 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ne_cv_gai_addrconfig=yes else ne_cv_gai_addrconfig=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_gai_addrconfig" >&5 $as_echo "$ne_cv_gai_addrconfig" >&6; } if test $ne_cv_gai_addrconfig = yes; then $as_echo "#define USE_GAI_ADDRCONFIG 1" >>confdefs.h fi else # Checks for non-getaddrinfo() based resolver interfaces. # QNX has gethostbyname in -lsocket. BeOS only has it in -lbind. # CygWin/Winsock2 has it in -lws2_32, allegedly. # Haiku requires -lnetwork for socket functions. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 $as_echo_n "checking for library containing gethostbyname... " >&6; } if ${ne_cv_libsfor_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { gethostbyname(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_gethostbyname="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_gethostbyname="not found" for lib in socket nsl bind ws2_32 network; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall gethostbyname();" ;; *) ne__code="gethostbyname();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_gethostbyname="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_gethostbyname" >&5 $as_echo "$ne_cv_libsfor_gethostbyname" >&6; } if test "$ne_cv_libsfor_gethostbyname" = "not found"; then as_fn_error $? "could not find library containing gethostbyname" "$LINENO" 5 elif test "$ne_cv_libsfor_gethostbyname" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_gethostbyname $NEON_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing hstrerror" >&5 $as_echo_n "checking for library containing hstrerror... " >&6; } if ${ne_cv_libsfor_hstrerror+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { hstrerror(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_hstrerror="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_hstrerror="not found" for lib in resolv; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall hstrerror();" ;; *) ne__code="hstrerror();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_hstrerror="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_hstrerror" >&5 $as_echo "$ne_cv_libsfor_hstrerror" >&6; } if test "$ne_cv_libsfor_hstrerror" = "not found"; then : elif test "$ne_cv_libsfor_hstrerror" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_hstrerror $NEON_LIBS" fi ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in hstrerror do : ac_fn_c_check_func "$LINENO" "hstrerror" "ac_cv_func_hstrerror" if test "x$ac_cv_func_hstrerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_HSTRERROR 1 _ACEOF fi done LIBS=$ne_cf_save_LIBS # Older Unixes don't declare h_errno. ac_fn_c_check_decl "$LINENO" "h_errno" "ac_cv_have_decl_h_errno" "#include " if test "x$ac_cv_have_decl_h_errno" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_H_ERRNO $ac_have_decl _ACEOF ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" " #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif " if test "x$ac_cv_type_in_addr_t" = xyes; then : else $as_echo "#define in_addr_t unsigned int" >>confdefs.h fi fi ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif " if test "x$ac_cv_type_socklen_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF else # Linux accept(2) says this should be size_t for SunOS 5... gah. $as_echo "#define socklen_t int" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct tm" "tm_gmtoff" "ac_cv_member_struct_tm_tm_gmtoff" "#include " if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_TM_TM_GMTOFF 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct tm" "__tm_gmtoff" "ac_cv_member_struct_tm___tm_gmtoff" "#include " if test "x$ac_cv_member_struct_tm___tm_gmtoff" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_TM___TM_GMTOFF 1 _ACEOF fi if test ${ac_cv_member_struct_tm_tm_gmtoff}${ac_cv_member_struct_tm___tm_gmtoff}${ne_cv_cc_timezone} = nonono; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no timezone handling in date parsing on this platform" >&5 $as_echo "$as_me: WARNING: no timezone handling in date parsing on this platform" >&2;} fi # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; ne_use_zlib=$withval else ne_use_zlib=yes fi if test "$ne_use_zlib" = "yes"; then ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflate in -lz" >&5 $as_echo_n "checking for inflate in -lz... " >&6; } if ${ac_cv_lib_z_inflate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inflate (); int main () { return inflate (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_inflate=yes else ac_cv_lib_z_inflate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflate" >&5 $as_echo "$ac_cv_lib_z_inflate" >&6; } if test "x$ac_cv_lib_z_inflate" = xyes; then : NEON_LIBS="$NEON_LIBS -lz" NE_FLAG_ZLIB=yes $as_echo "#define NE_HAVE_ZLIB 1" >>confdefs.h ne_ZLIB_message="zlib support enabled, using -lz" { $as_echo "$as_me:${as_lineno-$LINENO}: zlib support enabled, using -lz" >&5 $as_echo "$as_me: zlib support enabled, using -lz" >&6;} else NE_FLAG_ZLIB=no ne_ZLIB_message="zlib library not found" { $as_echo "$as_me:${as_lineno-$LINENO}: zlib library not found" >&5 $as_echo "$as_me: zlib library not found" >&6;} fi else NE_FLAG_ZLIB=no ne_ZLIB_message="zlib header not found" { $as_echo "$as_me:${as_lineno-$LINENO}: zlib header not found" >&5 $as_echo "$as_me: zlib header not found" >&6;} fi else NE_FLAG_ZLIB=no ne_ZLIB_message="zlib not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: zlib not enabled" >&5 $as_echo "$as_me: zlib not enabled" >&6;} fi # Conditionally enable ACL support { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ACL support in neon" >&5 $as_echo_n "checking whether to enable ACL support in neon... " >&6; } if test "x$neon_no_acl" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_oldacl ne_acl3744" fi # Check whether --with-ssl was given. if test "${with_ssl+set}" = set; then : withval=$with_ssl; fi # Check whether --with-egd was given. if test "${with_egd+set}" = set; then : withval=$with_egd; fi # Check whether --with-pakchois was given. if test "${with_pakchois+set}" = set; then : withval=$with_pakchois; fi case $with_ssl in /*) { $as_echo "$as_me:${as_lineno-$LINENO}: to use SSL libraries in non-standard locations, try --with-ssl --with-libs=$with_ssl" >&5 $as_echo "$as_me: to use SSL libraries in non-standard locations, try --with-ssl --with-libs=$with_ssl" >&6;} as_fn_error $? "--with-ssl does not take a path argument" "$LINENO" 5 ;; yes|openssl) # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKG_CONFIG" = "no"; then : Not using pkg-config # Either OpenSSL library may require -ldl if built with dynamic engine support { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing RSA_new" >&5 $as_echo_n "checking for library containing RSA_new... " >&6; } if ${ne_cv_libsfor_RSA_new+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { RSA_new(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_RSA_new="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_RSA_new="not found" for lib in crypto; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall RSA_new();" ;; *) ne__code="RSA_new();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_RSA_new="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ne_sl_save_LIBS -l$lib -ldl $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_RSA_new="-l$lib -ldl"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_RSA_new" >&5 $as_echo "$ne_cv_libsfor_RSA_new" >&6; } if test "$ne_cv_libsfor_RSA_new" = "not found"; then as_fn_error $? "could not find library containing RSA_new" "$LINENO" 5 elif test "$ne_cv_libsfor_RSA_new" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_RSA_new $NEON_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5 $as_echo_n "checking for library containing SSL_library_init... " >&6; } if ${ne_cv_libsfor_SSL_library_init+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { SSL_library_init(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_SSL_library_init="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_SSL_library_init="not found" for lib in ssl; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall SSL_library_init();" ;; *) ne__code="SSL_library_init();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_SSL_library_init="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ne_sl_save_LIBS -l$lib -ldl $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_SSL_library_init="-l$lib -ldl"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_SSL_library_init" >&5 $as_echo "$ne_cv_libsfor_SSL_library_init" >&6; } if test "$ne_cv_libsfor_SSL_library_init" = "not found"; then as_fn_error $? "could not find library containing SSL_library_init" "$LINENO" 5 elif test "$ne_cv_libsfor_SSL_library_init" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_SSL_library_init $NEON_LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl pkg-config data" >&5 $as_echo_n "checking for openssl pkg-config data... " >&6; } if ${ne_cv_pkg_openssl+:} false; then : $as_echo_n "(cached) " >&6 else if $PKG_CONFIG openssl; then ne_cv_pkg_openssl=yes else ne_cv_pkg_openssl=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_pkg_openssl" >&5 $as_echo "$ne_cv_pkg_openssl" >&6; } if test "$ne_cv_pkg_openssl" = "yes"; then NE_SSL_CFLAGS=`$PKG_CONFIG --cflags openssl` NE_SSL_LIBS=`$PKG_CONFIG --libs openssl` : Using provided pkg-config data { $as_echo "$as_me:${as_lineno-$LINENO}: using SSL library configuration from pkg-config" >&5 $as_echo "$as_me: using SSL library configuration from pkg-config" >&6;} CPPFLAGS="$CPPFLAGS ${NE_SSL_CFLAGS}" NEON_LIBS="$NEON_LIBS ${NE_SSL_LIBS}" else : No pkg-config for openssl provided # Either OpenSSL library may require -ldl if built with dynamic engine support { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing RSA_new" >&5 $as_echo_n "checking for library containing RSA_new... " >&6; } if ${ne_cv_libsfor_RSA_new+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { RSA_new(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_RSA_new="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_RSA_new="not found" for lib in crypto; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall RSA_new();" ;; *) ne__code="RSA_new();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_RSA_new="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ne_sl_save_LIBS -l$lib -ldl $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_RSA_new="-l$lib -ldl"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_RSA_new" >&5 $as_echo "$ne_cv_libsfor_RSA_new" >&6; } if test "$ne_cv_libsfor_RSA_new" = "not found"; then as_fn_error $? "could not find library containing RSA_new" "$LINENO" 5 elif test "$ne_cv_libsfor_RSA_new" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_RSA_new $NEON_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5 $as_echo_n "checking for library containing SSL_library_init... " >&6; } if ${ne_cv_libsfor_SSL_library_init+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { SSL_library_init(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_SSL_library_init="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_SSL_library_init="not found" for lib in ssl; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall SSL_library_init();" ;; *) ne__code="SSL_library_init();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_SSL_library_init="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ne_sl_save_LIBS -l$lib -ldl $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_SSL_library_init="-l$lib -ldl"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_SSL_library_init" >&5 $as_echo "$ne_cv_libsfor_SSL_library_init" >&6; } if test "$ne_cv_libsfor_SSL_library_init" = "not found"; then as_fn_error $? "could not find library containing SSL_library_init" "$LINENO" 5 elif test "$ne_cv_libsfor_SSL_library_init" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_SSL_library_init $NEON_LIBS" fi fi fi for ac_header in openssl/ssl.h openssl/opensslv.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else as_fn_error $? "OpenSSL headers not found, cannot enable SSL support" "$LINENO" 5 fi done # Enable EGD support if using 0.9.7 or newer { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL version is >= 0.9.7" >&5 $as_echo_n "checking OpenSSL version is >= 0.9.7... " >&6; } if ${ne_cv_lib_ssl097+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if OPENSSL_VERSION_NUMBER >= 0x00907000L good #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "good" >/dev/null 2>&1; then : ne_cv_lib_ssl097=yes else ne_cv_lib_ssl097=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_lib_ssl097" >&5 $as_echo "$ne_cv_lib_ssl097" >&6; } if test "$ne_cv_lib_ssl097" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: OpenSSL >= 0.9.7; EGD support not needed in neon" >&5 $as_echo "$as_me: OpenSSL >= 0.9.7; EGD support not needed in neon" >&6;} NE_FLAG_SSL=yes $as_echo "#define NE_HAVE_SSL 1" >>confdefs.h ne_SSL_message="SSL support enabled, using OpenSSL (0.9.7 or later)" { $as_echo "$as_me:${as_lineno-$LINENO}: SSL support enabled, using OpenSSL (0.9.7 or later)" >&5 $as_echo "$as_me: SSL support enabled, using OpenSSL (0.9.7 or later)" >&6;} ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in CRYPTO_set_idptr_callback SSL_SESSION_cmp do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS=$ne_cf_save_LIBS else # Fail if OpenSSL is older than 0.9.6 { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL version is >= 0.9.6" >&5 $as_echo_n "checking OpenSSL version is >= 0.9.6... " >&6; } if ${ne_cv_lib_ssl096+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if OPENSSL_VERSION_NUMBER >= 0x00906000L good #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "good" >/dev/null 2>&1; then : ne_cv_lib_ssl096=yes else ne_cv_lib_ssl096=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_lib_ssl096" >&5 $as_echo "$ne_cv_lib_ssl096" >&6; } if test "$ne_cv_lib_ssl096" != "yes"; then as_fn_error $? "OpenSSL 0.9.6 or later is required" "$LINENO" 5 fi NE_FLAG_SSL=yes $as_echo "#define NE_HAVE_SSL 1" >>confdefs.h ne_SSL_message="SSL support enabled, using OpenSSL (0.9.6 or later)" { $as_echo "$as_me:${as_lineno-$LINENO}: SSL support enabled, using OpenSSL (0.9.6 or later)" >&5 $as_echo "$as_me: SSL support enabled, using OpenSSL (0.9.6 or later)" >&6;} case "$with_egd" in yes|no) ne_cv_lib_sslegd=$with_egd ;; /*) ne_cv_lib_sslegd=yes cat >>confdefs.h <<_ACEOF #define EGD_PATH "$with_egd" _ACEOF ;; *) # Guess whether EGD support is needed { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable EGD support" >&5 $as_echo_n "checking whether to enable EGD support... " >&6; } if ${ne_cv_lib_sslegd+:} false; then : $as_echo_n "(cached) " >&6 else if test -r /dev/random || test -r /dev/urandom; then ne_cv_lib_sslegd=no else ne_cv_lib_sslegd=yes fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_lib_sslegd" >&5 $as_echo "$ne_cv_lib_sslegd" >&6; } ;; esac if test "$ne_cv_lib_sslegd" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: EGD support enabled for seeding OpenSSL PRNG" >&5 $as_echo "$as_me: EGD support enabled for seeding OpenSSL PRNG" >&6;} $as_echo "#define ENABLE_EGD 1" >>confdefs.h fi fi $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_openssl" $as_echo "#define HAVE_NTLM 1" >>confdefs.h ;; gnutls) # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKG_CONFIG" = "no"; then : Not using pkg-config # Fall back on libgnutls-config script # Extract the first word of "libgnutls-config", so it can be a program name with args. set dummy libgnutls-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GNUTLS_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $GNUTLS_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_GNUTLS_CONFIG="$GNUTLS_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GNUTLS_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GNUTLS_CONFIG" && ac_cv_path_GNUTLS_CONFIG="no" ;; esac fi GNUTLS_CONFIG=$ac_cv_path_GNUTLS_CONFIG if test -n "$GNUTLS_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNUTLS_CONFIG" >&5 $as_echo "$GNUTLS_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GNUTLS_CONFIG" = "no"; then as_fn_error $? "could not find libgnutls-config in \$PATH" "$LINENO" 5 fi CPPFLAGS="$CPPFLAGS `$GNUTLS_CONFIG --cflags`" NEON_LIBS="$NEON_LIBS `$GNUTLS_CONFIG --libs`" ne_gnutls_ver=`$GNUTLS_CONFIG --version` else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gnutls pkg-config data" >&5 $as_echo_n "checking for gnutls pkg-config data... " >&6; } if ${ne_cv_pkg_gnutls+:} false; then : $as_echo_n "(cached) " >&6 else if $PKG_CONFIG gnutls; then ne_cv_pkg_gnutls=yes else ne_cv_pkg_gnutls=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_pkg_gnutls" >&5 $as_echo "$ne_cv_pkg_gnutls" >&6; } if test "$ne_cv_pkg_gnutls" = "yes"; then NE_SSL_CFLAGS=`$PKG_CONFIG --cflags gnutls` NE_SSL_LIBS=`$PKG_CONFIG --libs gnutls` : Using provided pkg-config data { $as_echo "$as_me:${as_lineno-$LINENO}: using GnuTLS configuration from pkg-config" >&5 $as_echo "$as_me: using GnuTLS configuration from pkg-config" >&6;} CPPFLAGS="$CPPFLAGS ${NE_SSL_CFLAGS}" NEON_LIBS="$NEON_LIBS ${NE_SSL_LIBS}" ne_gnutls_ver=`$PKG_CONFIG --modversion gnutls` else : No pkg-config for gnutls provided # Fall back on libgnutls-config script # Extract the first word of "libgnutls-config", so it can be a program name with args. set dummy libgnutls-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GNUTLS_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $GNUTLS_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_GNUTLS_CONFIG="$GNUTLS_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GNUTLS_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GNUTLS_CONFIG" && ac_cv_path_GNUTLS_CONFIG="no" ;; esac fi GNUTLS_CONFIG=$ac_cv_path_GNUTLS_CONFIG if test -n "$GNUTLS_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNUTLS_CONFIG" >&5 $as_echo "$GNUTLS_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GNUTLS_CONFIG" = "no"; then as_fn_error $? "could not find libgnutls-config in \$PATH" "$LINENO" 5 fi CPPFLAGS="$CPPFLAGS `$GNUTLS_CONFIG --cflags`" NEON_LIBS="$NEON_LIBS `$GNUTLS_CONFIG --libs`" ne_gnutls_ver=`$GNUTLS_CONFIG --version` fi fi ac_fn_c_check_header_mongrel "$LINENO" "gnutls/gnutls.h" "ac_cv_header_gnutls_gnutls_h" "$ac_includes_default" if test "x$ac_cv_header_gnutls_gnutls_h" = xyes; then : else as_fn_error $? "could not find gnutls/gnutls.h in include path" "$LINENO" 5 fi NE_FLAG_SSL=yes $as_echo "#define NE_HAVE_SSL 1" >>confdefs.h ne_SSL_message="SSL support enabled, using GnuTLS $ne_gnutls_ver" { $as_echo "$as_me:${as_lineno-$LINENO}: SSL support enabled, using GnuTLS $ne_gnutls_ver" >&5 $as_echo "$as_me: SSL support enabled, using GnuTLS $ne_gnutls_ver" >&6;} NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_gnutls" $as_echo "#define HAVE_GNUTLS 1" >>confdefs.h # Check for functions in later releases ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in gnutls_session_get_data2 gnutls_x509_dn_get_rdn_ava \ gnutls_sign_callback_set \ gnutls_certificate_get_x509_cas \ gnutls_certificate_verify_peers2 do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS=$ne_cf_save_LIBS # fail if gnutls_certificate_verify_peers2 is not found if test x${ac_cv_func_gnutls_certificate_verify_peers2} != xyes; then as_fn_error $? "GnuTLS version predates gnutls_certificate_verify_peers2, newer version required" "$LINENO" 5 fi # Check for iconv support if using the new RDN access functions: if test ${ac_cv_func_gnutls_x509_dn_get_rdn_ava}X${ac_cv_header_iconv_h} = yesXyes; then for ac_func in iconv do : ac_fn_c_check_func "$LINENO" "iconv" "ac_cv_func_iconv" if test "x$ac_cv_func_iconv" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ICONV 1 _ACEOF fi done fi ;; *) # Default to off; only create crypto-enabled binaries if requested. NE_FLAG_SSL=no ne_SSL_message="SSL support is not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: SSL support is not enabled" >&5 $as_echo "$as_me: SSL support is not enabled" >&6;} NE_FLAG_TS_SSL=no ne_TS_SSL_message="Thread-safe SSL support is not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: Thread-safe SSL support is not enabled" >&5 $as_echo "$as_me: Thread-safe SSL support is not enabled" >&6;} NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_stubssl" ;; esac # Check whether --with-ca-bundle was given. if test "${with_ca_bundle+set}" = set; then : withval=$with_ca_bundle; else with_ca_bundle=no fi case ${NE_FLAG_SSL}-${with_ca_bundle} in *-no) ;; yes-*) cat >>confdefs.h <<_ACEOF #define NE_SSL_CA_BUNDLE "${with_ca_bundle}" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: Using ${with_ca_bundle} as default SSL CA bundle" >&5 $as_echo "$as_me: Using ${with_ca_bundle} as default SSL CA bundle" >&6;} ;; esac # Check whether --enable-threadsafe-ssl was given. if test "${enable_threadsafe_ssl+set}" = set; then : enableval=$enable_threadsafe_ssl; else enable_threadsafe_ssl=no fi case $enable_threadsafe_ssl in posix|yes) ne_pthr_ok=yes for ac_func in pthread_mutex_init pthread_mutex_lock do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else ne_pthr_ok=no fi done if test "${ne_pthr_ok}" = "no"; then as_fn_error $? "could not find POSIX mutex interfaces; (try CC=\"${CC} -pthread\"?)" "$LINENO" 5 fi NE_FLAG_TS_SSL=yes $as_echo "#define NE_HAVE_TS_SSL 1" >>confdefs.h ne_TS_SSL_message="Thread-safe SSL supported using POSIX threads" { $as_echo "$as_me:${as_lineno-$LINENO}: Thread-safe SSL supported using POSIX threads" >&5 $as_echo "$as_me: Thread-safe SSL supported using POSIX threads" >&6;} ;; *) NE_FLAG_TS_SSL=no ne_TS_SSL_message="Thread-safe SSL not supported" { $as_echo "$as_me:${as_lineno-$LINENO}: Thread-safe SSL not supported" >&5 $as_echo "$as_me: Thread-safe SSL not supported" >&6;} ;; esac case ${with_pakchois}X${ac_cv_func_gnutls_sign_callback_set}Y${ne_cv_lib_ssl097} in noX*Y*) ;; *X*Yyes|*XyesY*) # PKCS#11... ho! # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKG_CONFIG" = "no"; then : Not using pkg-config { $as_echo "$as_me:${as_lineno-$LINENO}: pakchois library not found; no PKCS#11 support" >&5 $as_echo "$as_me: pakchois library not found; no PKCS#11 support" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pakchois pkg-config data" >&5 $as_echo_n "checking for pakchois pkg-config data... " >&6; } if ${ne_cv_pkg_pakchois+:} false; then : $as_echo_n "(cached) " >&6 else if $PKG_CONFIG pakchois; then ne_cv_pkg_pakchois=yes else ne_cv_pkg_pakchois=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_pkg_pakchois" >&5 $as_echo "$ne_cv_pkg_pakchois" >&6; } if test "$ne_cv_pkg_pakchois" = "yes"; then NE_PK11_CFLAGS=`$PKG_CONFIG --cflags pakchois` NE_PK11_LIBS=`$PKG_CONFIG --libs pakchois` : Using provided pkg-config data { $as_echo "$as_me:${as_lineno-$LINENO}: using pakchois for PKCS#11 support" >&5 $as_echo "$as_me: using pakchois for PKCS#11 support" >&6;} $as_echo "#define HAVE_PAKCHOIS 1" >>confdefs.h CPPFLAGS="$CPPFLAGS ${NE_PK11_CFLAGS}" NEON_LIBS="${NEON_LIBS} ${NE_PK11_LIBS}" else : No pkg-config for pakchois provided { $as_echo "$as_me:${as_lineno-$LINENO}: pakchois library not found; no PKCS#11 support" >&5 $as_echo "$as_me: pakchois library not found; no PKCS#11 support" >&6;} fi fi ;; esac # Check whether --with-gssapi was given. if test "${with_gssapi+set}" = set; then : withval=$with_gssapi; fi if test "$with_gssapi" != "no"; then # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KRB5_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $KRB5_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$PATH:/usr/kerberos/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_KRB5_CONFIG" && ac_cv_path_KRB5_CONFIG="none" ;; esac fi KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG if test -n "$KRB5_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5_CONFIG" >&5 $as_echo "$KRB5_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else KRB5_CONFIG=none fi if test "x$KRB5_CONFIG" != "xnone"; then ne_save_CPPFLAGS=$CPPFLAGS ne_save_LIBS=$NEON_LIBS NEON_LIBS="$NEON_LIBS `${KRB5_CONFIG} --libs gssapi`" CPPFLAGS="$CPPFLAGS `${KRB5_CONFIG} --cflags gssapi`" # MIT and Heimdal put gssapi.h in different places for ac_header in gssapi/gssapi.h gssapi.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in gss_init_sec_context do : ac_fn_c_check_func "$LINENO" "gss_init_sec_context" "ac_cv_func_gss_init_sec_context" if test "x$ac_cv_func_gss_init_sec_context" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GSS_INIT_SEC_CONTEXT 1 _ACEOF ne_save_CPPFLAGS=$CPPFLAGS ne_save_LIBS=$NEON_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: GSSAPI authentication support enabled" >&5 $as_echo "$as_me: GSSAPI authentication support enabled" >&6;} $as_echo "#define HAVE_GSSAPI 1" >>confdefs.h for ac_header in gssapi/gssapi_generic.h do : ac_fn_c_check_header_mongrel "$LINENO" "gssapi/gssapi_generic.h" "ac_cv_header_gssapi_gssapi_generic_h" "$ac_includes_default" if test "x$ac_cv_header_gssapi_gssapi_generic_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GSSAPI_GSSAPI_GENERIC_H 1 _ACEOF fi done # Older versions of MIT Kerberos lack GSS_C_NT_HOSTBASED_SERVICE ac_fn_c_check_decl "$LINENO" "GSS_C_NT_HOSTBASED_SERVICE" "ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE" "#ifdef HAVE_GSSAPI_GSSAPI_H #include #else #include #endif " if test "x$ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE" = xyes; then : else $as_echo "#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name" >>confdefs.h fi fi done LIBS=$ne_cf_save_LIBS break fi done CPPFLAGS=$ne_save_CPPFLAGS NEON_LIBS=$ne_save_LIBS fi # Check whether --with-libproxy was given. if test "${with_libproxy+set}" = set; then : withval=$with_libproxy; fi if test "x$with_libproxy" != "xno"; then # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKG_CONFIG" = "no"; then : Not using pkg-config NE_FLAG_LIBPXY=no ne_LIBPXY_message="libproxy support not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: libproxy support not enabled" >&5 $as_echo "$as_me: libproxy support not enabled" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libproxy-1.0 pkg-config data" >&5 $as_echo_n "checking for libproxy-1.0 pkg-config data... " >&6; } if ${ne_cv_pkg_libproxy_1_0+:} false; then : $as_echo_n "(cached) " >&6 else if $PKG_CONFIG libproxy-1.0; then ne_cv_pkg_libproxy_1_0=yes else ne_cv_pkg_libproxy_1_0=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_pkg_libproxy_1_0" >&5 $as_echo "$ne_cv_pkg_libproxy_1_0" >&6; } if test "$ne_cv_pkg_libproxy_1_0" = "yes"; then NE_PXY_CFLAGS=`$PKG_CONFIG --cflags libproxy-1.0` NE_PXY_LIBS=`$PKG_CONFIG --libs libproxy-1.0` : Using provided pkg-config data $as_echo "#define HAVE_LIBPROXY 1" >>confdefs.h CPPFLAGS="$CPPFLAGS $NE_PXY_CFLAGS" NEON_LIBS="$NEON_LIBS ${NE_PXY_LIBS}" NE_FLAG_LIBPXY=yes $as_echo "#define NE_HAVE_LIBPXY 1" >>confdefs.h ne_LIBPXY_message="libproxy support enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: libproxy support enabled" >&5 $as_echo "$as_me: libproxy support enabled" >&6;} else : No pkg-config for libproxy-1.0 provided NE_FLAG_LIBPXY=no ne_LIBPXY_message="libproxy support not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: libproxy support not enabled" >&5 $as_echo "$as_me: libproxy support not enabled" >&6;} fi fi else NE_FLAG_LIBPXY=no ne_LIBPXY_message="libproxy support not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: libproxy support not enabled" >&5 $as_echo "$as_me: libproxy support not enabled" >&6;} fi # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. 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 else enable_shared=no fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. 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 delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else 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 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else 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 : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else 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* | cegcc*) # 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; ;; mint*) # On MiNT this can take a long time and run out of memory. 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 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; 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 ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then 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` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # 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. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` 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` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|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 ;; haiku*) 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])(-bit)?( [LM]SB)? 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 ;; interix[3-9]*) # 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 glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) 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=pass_all ;; 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 ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) 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 ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi 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 if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' 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 \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done # 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 # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' 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 # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \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\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # 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 # Try without a prefix underscore, 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. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && 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 <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; 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-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) 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" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. 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 else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. 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 else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else 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 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF 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 # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else 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 ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else 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 ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # 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 # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$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* ac_outfile=conftest.$ac_objext echo "$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 -r conftest* if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # 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:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 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 "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # 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_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # 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). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # 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_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # 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_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-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_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # 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:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 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 "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$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>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$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:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 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 "$_lt_compiler_boilerplate" | $SED '/^$/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_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $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 .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$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:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 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 "$_lt_compiler_boilerplate" | $SED '/^$/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_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $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 .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an 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'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # 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. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # 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 ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = 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 hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${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 whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [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 aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, 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 install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$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... archive_expsym_cmds='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 ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${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. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='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' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$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' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $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 ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=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 ;; *) # 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. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) 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 # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$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].*|aix[5-9]*) 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. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' 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 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no 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 export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $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. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${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. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$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*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # 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. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # 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. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=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. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$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>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_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 hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$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. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # 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. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi 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" 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 # correct to gnu/linux during the next big refactor 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' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor 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*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) 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=`func_echo_all "$lib" | $SED '\''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' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor 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* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc 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~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' 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="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; 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 dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. 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 # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # 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' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # 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}${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`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor 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 ;; 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[23].*) 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 ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor 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 ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" 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=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' 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' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor 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 # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # 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 # 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/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $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' ;; netbsdelf*-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='NetBSD ld.elf_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 # correct to gnu/linux during the next big refactor 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=qnx 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='ldqnx.so' ;; 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" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 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 # correct to gnu/linux during the next big refactor 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 shlibpath_overrides_runpath=yes 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' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' 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' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } 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 if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; 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 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* | cegcc*) 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #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 /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 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; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #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 /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 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; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } 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" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } 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" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } 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 ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: # Checks to compile test suite # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5 $as_echo_n "checking size of time_t... " >&6; } if ${ac_cv_sizeof_time_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" "$ac_includes_default #ifdef HAVE_SYS_TIME_H #include #endif "; then : else if test "$ac_cv_type_time_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (time_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_time_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5 $as_echo "$ac_cv_sizeof_time_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_TIME_T $ac_cv_sizeof_time_t _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print time_t" >&5 $as_echo_n "checking how to print time_t... " >&6; } if ${ne_cv_fmt_time_t+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_time_t=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in d ld lld; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include int main () { time_t i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_time_t=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_time_t in $ac_cv_sizeof_int) ne_cv_fmt_time_t="d" ;; $ac_cv_sizeof_long) ne_cv_fmt_time_t="ld" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_time_t="lld" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_time_t" >&5 $as_echo "$ne_cv_fmt_time_t" >&6; } if test "x$ne_cv_fmt_time_t" = "xnone"; then as_fn_error $? "format string for time_t not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_TIME_T "$ne_cv_fmt_time_t" _ACEOF ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi # Search in /usr/ccs/bin for Solaris ne_PATH=$PATH:/usr/ccs/bin if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AR+:} false; then : $as_echo_n "(cached) " >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $ne_PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_AR"; then ac_pt_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_AR+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_AR in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_AR="$ac_pt_AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $ne_PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_AR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_AR=$ac_cv_path_ac_pt_AR if test -n "$ac_pt_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_AR" >&5 $as_echo "$ac_pt_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_AR" = x; then AR="notfound" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_pt_AR fi else AR="$ac_cv_path_AR" fi if test "x$AR" = "xnotfound"; then as_fn_error $? "could not find ar tool" "$LINENO" 5 fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else case $RANLIB in [\\/]* | ?:[\\/]*) ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $ne_PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi RANLIB=$ac_cv_path_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_RANLIB"; then ac_pt_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_RANLIB in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_RANLIB="$ac_pt_RANLIB" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $ne_PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_RANLIB="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_RANLIB=$ac_cv_path_ac_pt_RANLIB if test -n "$ac_pt_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_RANLIB" >&5 $as_echo "$ac_pt_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_pt_RANLIB fi else RANLIB="$ac_cv_path_RANLIB" fi for ac_header in sys/time.h stdint.h locale.h signal.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in pipe isatty usleep shutdown setlocale gethostname do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # Use the libtool-type build. NEON_TARGET=libneon.la NEON_OBJEXT=lo # Using the default set of object files to build. # Add the extension to EXTRAOBJS ne="$NEON_EXTRAOBJS" NEON_EXTRAOBJS= for o in $ne; do NEON_EXTRAOBJS="$NEON_EXTRAOBJS $o.$NEON_OBJEXT" done # Was DAV support explicitly turned off? if test "x$neon_no_webdav" = "xyes"; then # No WebDAV support NEONOBJS="$NEONOBJS \$(NEON_BASEOBJS)" NE_FLAG_DAV=no ne_DAV_message="WebDAV support is not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: WebDAV support is not enabled" >&5 $as_echo "$as_me: WebDAV support is not enabled" >&6;} if test "x${NE_LIBTOOL_RELEASE}y" = "xy"; then NE_LIBTOOL_RELEASE="NODAV" else NE_LIBTOOL_RELEASE="${NE_LIBTOOL_RELEASE}-NODAV" fi else # WebDAV support NEONOBJS="$NEONOBJS \$(NEON_DAVOBJS)" NE_FLAG_DAV=yes $as_echo "#define NE_HAVE_DAV 1" >>confdefs.h ne_DAV_message="WebDAV support is enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: WebDAV support is enabled" >&5 $as_echo "$as_me: WebDAV support is enabled" >&6;} fi # Find an XML parser # Check whether --with-libxml2 was given. if test "${with_libxml2+set}" = set; then : withval=$with_libxml2; fi # Check whether --with-expat was given. if test "${with_expat+set}" = set; then : withval=$with_expat; fi with_included_expat=no if test "$NEON_NEED_XML_PARSER" = "yes"; then # Find an XML parser neon_xml_parser=none # Forced choice of expat: case $with_expat in yes) ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default" if test "x$ac_cv_header_expat_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_SetXmlDeclHandler in -lexpat" >&5 $as_echo_n "checking for XML_SetXmlDeclHandler in -lexpat... " >&6; } if ${ac_cv_lib_expat_XML_SetXmlDeclHandler+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexpat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XML_SetXmlDeclHandler (); int main () { return XML_SetXmlDeclHandler (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_expat_XML_SetXmlDeclHandler=yes else ac_cv_lib_expat_XML_SetXmlDeclHandler=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_SetXmlDeclHandler" >&5 $as_echo "$ac_cv_lib_expat_XML_SetXmlDeclHandler" >&6; } if test "x$ac_cv_lib_expat_XML_SetXmlDeclHandler" = xyes; then : $as_echo "#define HAVE_EXPAT 1" >>confdefs.h neon_xml_parser_message="expat" NEON_LIBS="$NEON_LIBS -lexpat" neon_xml_parser=expat ac_fn_c_check_type "$LINENO" "XML_Size" "ac_cv_type_XML_Size" "#include " if test "x$ac_cv_type_XML_Size" = xyes; then : # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of XML_Size" >&5 $as_echo_n "checking size of XML_Size... " >&6; } if ${ac_cv_sizeof_XML_Size+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (XML_Size))" "ac_cv_sizeof_XML_Size" "$ac_includes_default #include "; then : else if test "$ac_cv_type_XML_Size" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (XML_Size) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_XML_Size=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_XML_Size" >&5 $as_echo "$ac_cv_sizeof_XML_Size" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_XML_SIZE $ac_cv_sizeof_XML_Size _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print XML_Size" >&5 $as_echo_n "checking how to print XML_Size... " >&6; } if ${ne_cv_fmt_XML_Size+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_XML_Size=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in d ld lld; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { XML_Size i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_XML_Size=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_XML_Size in $ac_cv_sizeof_int) ne_cv_fmt_XML_Size="d" ;; $ac_cv_sizeof_long) ne_cv_fmt_XML_Size="ld" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_XML_Size="lld" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_XML_Size" >&5 $as_echo "$ne_cv_fmt_XML_Size" >&6; } if test "x$ne_cv_fmt_XML_Size" = "xnone"; then as_fn_error $? "format string for XML_Size not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_XML_SIZE "$ne_cv_fmt_XML_Size" _ACEOF else cat >>confdefs.h <<_ACEOF #define NE_FMT_XML_SIZE "d" _ACEOF fi else as_fn_error $? "expat library not found, cannot proceed" "$LINENO" 5 fi else as_fn_error $? "expat library not found, cannot proceed" "$LINENO" 5 fi ;; no) ;; */libexpat.la) # Special case for Subversion ne_expdir=`echo $with_expat | sed 's:/libexpat.la$::'` $as_echo "#define HAVE_EXPAT 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define NE_FMT_XML_SIZE "d" _ACEOF CPPFLAGS="$CPPFLAGS -I$ne_expdir" if test "x${NEON_TARGET}" = "xlibneon.la"; then NEON_LTLIBS=$with_expat else # no dependency on libexpat => crippled libneon, so do partial install ALLOW_INSTALL=lib fi neon_xml_parser=expat neon_xml_parser_message="expat in $ne_expdir" ;; /*) as_fn_error $? "--with-expat does not take a directory argument" "$LINENO" 5 ;; esac # If expat wasn't specifically enabled and libxml was: if test "${neon_xml_parser}-${with_libxml2}-${with_included_expat}" = "none-yes-no"; then # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_XML2_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$XML2_CONFIG"; then ac_cv_prog_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_XML2_CONFIG="xml2-config" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi XML2_CONFIG=$ac_cv_prog_XML2_CONFIG if test -n "$XML2_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2_CONFIG" >&5 $as_echo "$XML2_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -n "$XML2_CONFIG"; then neon_xml_parser_message="libxml `$XML2_CONFIG --version`" $as_echo "#define HAVE_LIBXML 1" >>confdefs.h # xml2-config in some versions erroneously includes -I/include # in the --cflags output. CPPFLAGS="$CPPFLAGS `$XML2_CONFIG --cflags | sed 's| -I/include||g'`" NEON_LIBS="$NEON_LIBS `$XML2_CONFIG --libs | sed 's|-L/usr/lib ||g'`" for ac_header in libxml/xmlversion.h libxml/parser.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else as_fn_error $? "could not find parser.h, libxml installation problem?" "$LINENO" 5 fi done neon_xml_parser=libxml2 else as_fn_error $? "libxml2.x library not found, cannot proceed" "$LINENO" 5 fi fi # Otherwise, by default search for expat then libxml2: if test "${neon_xml_parser}-${with_included_expat}" = "none-no"; then ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default" if test "x$ac_cv_header_expat_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_SetXmlDeclHandler in -lexpat" >&5 $as_echo_n "checking for XML_SetXmlDeclHandler in -lexpat... " >&6; } if ${ac_cv_lib_expat_XML_SetXmlDeclHandler+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexpat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XML_SetXmlDeclHandler (); int main () { return XML_SetXmlDeclHandler (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_expat_XML_SetXmlDeclHandler=yes else ac_cv_lib_expat_XML_SetXmlDeclHandler=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_SetXmlDeclHandler" >&5 $as_echo "$ac_cv_lib_expat_XML_SetXmlDeclHandler" >&6; } if test "x$ac_cv_lib_expat_XML_SetXmlDeclHandler" = xyes; then : $as_echo "#define HAVE_EXPAT 1" >>confdefs.h neon_xml_parser_message="expat" NEON_LIBS="$NEON_LIBS -lexpat" neon_xml_parser=expat ac_fn_c_check_type "$LINENO" "XML_Size" "ac_cv_type_XML_Size" "#include " if test "x$ac_cv_type_XML_Size" = xyes; then : # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of XML_Size" >&5 $as_echo_n "checking size of XML_Size... " >&6; } if ${ac_cv_sizeof_XML_Size+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (XML_Size))" "ac_cv_sizeof_XML_Size" "$ac_includes_default #include "; then : else if test "$ac_cv_type_XML_Size" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (XML_Size) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_XML_Size=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_XML_Size" >&5 $as_echo "$ac_cv_sizeof_XML_Size" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_XML_SIZE $ac_cv_sizeof_XML_Size _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print XML_Size" >&5 $as_echo_n "checking how to print XML_Size... " >&6; } if ${ne_cv_fmt_XML_Size+:} false; then : $as_echo_n "(cached) " >&6 else ne_cv_fmt_XML_Size=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" for str in d ld lld; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { XML_Size i = 1; printf("%$str", i); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ne_cv_fmt_XML_Size=$str; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_XML_Size in $ac_cv_sizeof_int) ne_cv_fmt_XML_Size="d" ;; $ac_cv_sizeof_long) ne_cv_fmt_XML_Size="ld" ;; $ac_cv_sizeof_long_long) ne_cv_fmt_XML_Size="lld" ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_fmt_XML_Size" >&5 $as_echo "$ne_cv_fmt_XML_Size" >&6; } if test "x$ne_cv_fmt_XML_Size" = "xnone"; then as_fn_error $? "format string for XML_Size not found" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define NE_FMT_XML_SIZE "$ne_cv_fmt_XML_Size" _ACEOF else cat >>confdefs.h <<_ACEOF #define NE_FMT_XML_SIZE "d" _ACEOF fi else # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_XML2_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$XML2_CONFIG"; then ac_cv_prog_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_XML2_CONFIG="xml2-config" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi XML2_CONFIG=$ac_cv_prog_XML2_CONFIG if test -n "$XML2_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2_CONFIG" >&5 $as_echo "$XML2_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -n "$XML2_CONFIG"; then neon_xml_parser_message="libxml `$XML2_CONFIG --version`" $as_echo "#define HAVE_LIBXML 1" >>confdefs.h # xml2-config in some versions erroneously includes -I/include # in the --cflags output. CPPFLAGS="$CPPFLAGS `$XML2_CONFIG --cflags | sed 's| -I/include||g'`" NEON_LIBS="$NEON_LIBS `$XML2_CONFIG --libs | sed 's|-L/usr/lib ||g'`" for ac_header in libxml/xmlversion.h libxml/parser.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else as_fn_error $? "could not find parser.h, libxml installation problem?" "$LINENO" 5 fi done neon_xml_parser=libxml2 else : fi fi else # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_XML2_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$XML2_CONFIG"; then ac_cv_prog_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_XML2_CONFIG="xml2-config" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi XML2_CONFIG=$ac_cv_prog_XML2_CONFIG if test -n "$XML2_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2_CONFIG" >&5 $as_echo "$XML2_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -n "$XML2_CONFIG"; then neon_xml_parser_message="libxml `$XML2_CONFIG --version`" $as_echo "#define HAVE_LIBXML 1" >>confdefs.h # xml2-config in some versions erroneously includes -I/include # in the --cflags output. CPPFLAGS="$CPPFLAGS `$XML2_CONFIG --cflags | sed 's| -I/include||g'`" NEON_LIBS="$NEON_LIBS `$XML2_CONFIG --libs | sed 's|-L/usr/lib ||g'`" for ac_header in libxml/xmlversion.h libxml/parser.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else as_fn_error $? "could not find parser.h, libxml installation problem?" "$LINENO" 5 fi done neon_xml_parser=libxml2 else : fi fi fi # If an XML parser still has not been found, fail or use the bundled expat if test "$neon_xml_parser" = "none"; then as_fn_error $? "no XML parser was found: expat or libxml 2.x required" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: XML parser used: $neon_xml_parser_message" >&5 $as_echo "$as_me: XML parser used: $neon_xml_parser_message" >&6;} fi # Internationalization support. # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; else enable_nls=${ac_cv_header_libintl_h} fi if test x${enable_nls} = xyes; then # presume that dgettext() is available if bindtextdomain() is... # checking for dgettext() itself is awkward because gcc has a # builtin of that function, which confuses AC_CHECK_FUNCS et al. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing bindtextdomain" >&5 $as_echo_n "checking for library containing bindtextdomain... " >&6; } if ${ne_cv_libsfor_bindtextdomain+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { bindtextdomain(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_bindtextdomain="none needed" else ne_sl_save_LIBS=$LIBS ne_cv_libsfor_bindtextdomain="not found" for lib in intl; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall bindtextdomain();" ;; *) ne__code="bindtextdomain();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { $ne__code ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ne_cv_libsfor_bindtextdomain="-l$lib"; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done LIBS=$ne_sl_save_LIBS fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ne_cv_libsfor_bindtextdomain" >&5 $as_echo "$ne_cv_libsfor_bindtextdomain" >&6; } if test "$ne_cv_libsfor_bindtextdomain" = "not found"; then enable_nls=no elif test "$ne_cv_libsfor_bindtextdomain" = "none needed"; then : else NEON_LIBS="$ne_cv_libsfor_bindtextdomain $NEON_LIBS" fi ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" for ac_func in bind_textdomain_codeset do : ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BIND_TEXTDOMAIN_CODESET 1 _ACEOF fi done LIBS=$ne_cf_save_LIBS fi if test "$enable_nls" = "no"; then NE_FLAG_I18N=no ne_I18N_message="Internationalization support not enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: Internationalization support not enabled" >&5 $as_echo "$as_me: Internationalization support not enabled" >&6;} else NE_FLAG_I18N=yes $as_echo "#define NE_HAVE_I18N 1" >>confdefs.h ne_I18N_message="Internationalization support enabled" { $as_echo "$as_me:${as_lineno-$LINENO}: Internationalization support enabled" >&5 $as_echo "$as_me: Internationalization support enabled" >&6;} eval localedir="${datadir}/locale" cat >>confdefs.h <<_ACEOF #define LOCALEDIR "$localedir" _ACEOF fi # Extra checks for debugging, compiler warnings # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; fi # default is to enable debugging case $enable_debug in no) { $as_echo "$as_me:${as_lineno-$LINENO}: debugging is disabled" >&5 $as_echo "$as_me: debugging is disabled" >&6;} ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: debugging is enabled" >&5 $as_echo "$as_me: debugging is enabled" >&6;} $as_echo "#define NE_DEBUGGING 1" >>confdefs.h ;; esac # Leave till last to prevent CFLAGS affecting checks. # Check whether --enable-warnings was given. if test "${enable_warnings+set}" = set; then : enableval=$enable_warnings; fi if test "$enable_warnings" = "yes"; then case $GCC:`uname` in yes:*) CFLAGS="$CFLAGS -Wall -Wmissing-declarations -Wshadow -Wreturn-type -Wsign-compare -Wundef -Wpointer-arith -Wbad-function-cast -Wformat-security" if test -z "$with_ssl" -o "$with_ssl" = "no"; then # OpenSSL headers fail strict prototypes checks CFLAGS="$CFLAGS -Wstrict-prototypes" fi ;; no:OSF1) CFLAGS="$CFLAGS -check -msg_disable returnchecks -msg_disable alignment -msg_disable overflow" ;; no:IRIX) CFLAGS="$CFLAGS -fullwarn" ;; no:UnixWare) CFLAGS="$CFLAGS -v" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: warning flags unknown for compiler on this platform" >&5 $as_echo "$as_me: WARNING: warning flags unknown for compiler on this platform" >&2;} ;; esac fi CPPFLAGS="$CPPFLAGS -I\${top_builddir}" # Check whether --enable-memleak was given. if test "${enable_memleak+set}" = set; then : enableval=$enable_memleak; fi if test "$enable_memleak" = "yes"; then CPPFLAGS="$CPPFLAGS -DNEON_MEMLEAK -I\$(top_srcdir)/src" # disable 'make install' ALLOW_INSTALL=memleak fi # Enable tests for optional features TESTS="\$(BASIC_TESTS)" HELPERS="" if test $NE_FLAG_SSL = yes; then # Only enable SSL tests if an openssl binary is found (needed to make # certs etc). # Extract the first word of "openssl", so it can be a program name with args. set dummy openssl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_OPENSSL+:} false; then : $as_echo_n "(cached) " >&6 else case $OPENSSL in [\\/]* | ?:[\\/]*) ac_cv_path_OPENSSL="$OPENSSL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OPENSSL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_OPENSSL" && ac_cv_path_OPENSSL="notfound" ;; esac fi OPENSSL=$ac_cv_path_OPENSSL if test -n "$OPENSSL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL" >&5 $as_echo "$OPENSSL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$OPENSSL" != "notfound"; then TESTS="$TESTS \$(SSL_TESTS)" HELPERS="$HELPERS \$(SSL_HELPERS)" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no openssl binary in \$PATH: SSL tests disabled" >&5 $as_echo "$as_me: WARNING: no openssl binary in \$PATH: SSL tests disabled" >&2;} fi # Extract the first word of "certutil", so it can be a program name with args. set dummy certutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CERTUTIL+:} false; then : $as_echo_n "(cached) " >&6 else case $CERTUTIL in [\\/]* | ?:[\\/]*) ac_cv_path_CERTUTIL="$CERTUTIL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CERTUTIL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CERTUTIL" && ac_cv_path_CERTUTIL="notfound" ;; esac fi CERTUTIL=$ac_cv_path_CERTUTIL if test -n "$CERTUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CERTUTIL" >&5 $as_echo "$CERTUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "pk12util", so it can be a program name with args. set dummy pk12util; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PK12UTIL+:} false; then : $as_echo_n "(cached) " >&6 else case $PK12UTIL in [\\/]* | ?:[\\/]*) ac_cv_path_PK12UTIL="$PK12UTIL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PK12UTIL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PK12UTIL" && ac_cv_path_PK12UTIL="notfound" ;; esac fi PK12UTIL=$ac_cv_path_PK12UTIL if test -n "$PK12UTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PK12UTIL" >&5 $as_echo "$PK12UTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test $NE_FLAG_ZLIB = yes; then TESTS="$TESTS \$(ZLIB_TESTS)" HELPERS="$HELPERS \$(ZLIB_HELPERS)" fi if test x$enable_webdav != xno; then TESTS="$TESTS \$(DAV_TESTS)" fi # Check whether --enable-tests-install was given. if test "${enable_tests_install+set}" = set; then : enableval=$enable_tests_install; else enable_tests_install=no fi # If test suite installation is not required, it's more # efficient to link the test programs using -no-install: if test "$enable_tests_install" = "no"; then TEST_LDFLAGS="-no-install" fi # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PKG_CONFIG" != "no"; then # pkg-config >= 0.18 will use "Libs.private" iff necessary, # older versions which don't recognize that field may always # need all libraries in Libs. if $PKG_CONFIG --atleast-pkgconfig-version=0.18; then :; else NEON_PC_LIBS=${NEON_LIBS} fi fi # Pass the interface version on to libtool when linking libneon.la NEON_LINK_FLAGS="-version-info ${NE_LIBTOOL_VERSINFO}" # If any non-default ABI variations are used, add them to the SONAME: if test "x${NE_LIBTOOL_RELEASE}y" != "xy"; then NEON_LINK_FLAGS="${NEON_LINK_FLAGS} -release ${NE_LIBTOOL_RELEASE}" fi # Check whether --enable-ld-version-script was given. if test "${enable_ld_version_script+set}" = set; then : enableval=$enable_ld_version_script; have_ld_version_script=$enableval fi if test -z "$have_ld_version_script"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if LD -Wl,--version-script works" >&5 $as_echo_n "checking if LD -Wl,--version-script works... " >&6; } save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" cat > conftest.map <conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_ld_version_script=yes else have_ld_version_script=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext rm -f conftest.map LDFLAGS="$save_LDFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ld_version_script" >&5 $as_echo "$have_ld_version_script" >&6; } fi # If ld version scripts are supported, enable symbol versioning. # Otherwise, fall back to any libtool-supported symbol export # restrictions; ne__* symbols are not exported. if test "x$have_ld_version_script" = "xyes"; then NEON_LINK_FLAGS="$NEON_LINK_FLAGS -Wl,--version-script=\$(top_srcdir)/src/neon.vers" else NEON_LINK_FLAGS="$NEON_LINK_FLAGS -export-symbols-regex '^ne_[^_]'" fi if test x${enable_shared}${pic_mode}z = xnodefaultz; then CFLAGS="$CFLAGS -prefer-pic" { $as_echo "$as_me:${as_lineno-$LINENO}: Using PIC for static library build" >&5 $as_echo "$as_me: Using PIC for static library build" >&6;} fi if test x${enable_shared} = xno; then # Defining NE_PRIVATE as the empty string would work; using a # non-empty but redundant string 'extern' avoids any possible cpp # confusion with from an empty macro. CPPFLAGS="$CPPFLAGS -DNE_PRIVATE=extern" { $as_echo "$as_me:${as_lineno-$LINENO}: Private symbol suppression disabled for static library build" >&5 $as_echo "$as_me: Private symbol suppression disabled for static library build" >&6;} fi # Bundled language catalogs ALL_LINGUAS="cs de fr ja nn pl ru tr zh_CN" ac_config_files="$ac_config_files neon-config" ac_config_files="$ac_config_files Makefile src/Makefile test/Makefile neon.pc" ac_config_files="$ac_config_files test/makekeys:test/makekeys.sh" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do 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 as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by neon $as_me 0.29.6, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ neon config.status 0.29.6 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # # 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 sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "neon-config") CONFIG_FILES="$CONFIG_FILES neon-config" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; "neon.pc") CONFIG_FILES="$CONFIG_FILES neon.pc" ;; "test/makekeys") CONFIG_FILES="$CONFIG_FILES test/makekeys:test/makekeys.sh" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # 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 # 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//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # 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 # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # 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 # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # 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 # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # 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 # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # 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 # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # 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=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_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 _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # 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) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; "neon-config":F) chmod +x neon-config ;; "test/makekeys":F) chmod +x test/makekeys ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # for VPATH builds: test -d test/common || mkdir test/common { $as_echo "$as_me:${as_lineno-$LINENO}: Configured to build neon 0.29.6: Install prefix: ${prefix} Compiler: ${CC} XML Parser: ${neon_xml_parser_message} SSL library: ${ne_SSL_message} zlib support: ${ne_ZLIB_message} Build libraries: Shared=${enable_shared}, Static=${enable_static} " >&5 $as_echo "$as_me: Configured to build neon 0.29.6: Install prefix: ${prefix} Compiler: ${CC} XML Parser: ${neon_xml_parser_message} SSL library: ${ne_SSL_message} zlib support: ${ne_ZLIB_message} Build libraries: Shared=${enable_shared}, Static=${enable_static} " >&6;} case $ALLOW_INSTALL in memleak) { $as_echo "$as_me:${as_lineno-$LINENO}: Configured with development-only flags: WARNING: This copy of neon has been configured with memory leak checking WARNING: enabled, which should only be used in a development build of neon. WARNING: This neon library should not be installed for use by applications. " >&5 $as_echo "$as_me: Configured with development-only flags: WARNING: This copy of neon has been configured with memory leak checking WARNING: enabled, which should only be used in a development build of neon. WARNING: This neon library should not be installed for use by applications. " >&6;};; esac davix-R_0_5_0/deps/libneon/configure.in000066400000000000000000000142271257152637300201650ustar00rootroot00000000000000AC_PREREQ(2.58) dnl 2.58 required for AS_HELP_STRING dnl Extract the version (sans LF) from .version, created at release-time. m4_define(ne_version, [m4_translit(m4_include(.version), [ ])]) AC_INIT(neon, ne_version, [neon@lists.manyfish.co.uk]) AC_COPYRIGHT([Copyright 2000-2010 Joe Orton and others This configure script may be copied, distributed and modified under the terms of the GNU Library General Public license; see src/COPYING.LIB for more details.]) AC_CONFIG_HEADER(config.h) AC_CONFIG_SRCDIR(src/ne_request.c) NEON_WITH_LIBS # Pass through initial LDFLAGS verbatim to neon-config, so that extra # libraries which are detected (e.g. OpenSSL) can still be found when # building using the --libs output of neon-config. user_LDFLAGS=$LDFLAGS # By default, allow 'make install' to work. ALLOW_INSTALL=yes AC_DEFINE([_GNU_SOURCE], 1, [Always defined to enable GNU extensions]) AC_DEFINE([NEON_IS_LIBRARY], 1, [Defined when neon is built as a library]) AH_BOTTOM([ /* Enable leak-tracking versions of ne_*alloc when NEON_MEMLEAK is enabled */ #ifdef NEON_MEMLEAK # include "memleak.h" #endif]) AC_PROG_INSTALL AC_ARG_ENABLE(webdav, AS_HELP_STRING([--disable-webdav],[disable WebDAV support])) if test "$enable_webdav" = "no"; then NEON_WITHOUT_WEBDAV else # Yes, we do need an XML parser. The _BUNDLED macros handle # this normally. NEON_NEED_XML_PARSER=yes fi # The bundled macros also set this, which makes sure we recurse # into the 'src' directory. NEON_BUILD_BUNDLED=yes # Define NEON_VERSION etc and make the appropriate substitutions. NE_VERSIONS_BUNDLED LIBNEON_SOURCE_CHECKS dnl Avoid libtool 1.5 bug where configure fails if a C++ compiler dnl is not available. m4_ifdef([AC_LIBTOOL_TAGS], [AC_LIBTOOL_TAGS([])]) AC_DISABLE_SHARED m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL]) AC_EXEEXT # Checks to compile test suite NEON_TEST # Use the libtool-type build. NEON_LIBTOOL_BUILD # Find an XML parser NEON_XML_PARSER # Internationalization support. NEON_I18N() # Extra checks for debugging, compiler warnings NEON_DEBUG # Leave till last to prevent CFLAGS affecting checks. NEON_WARNINGS CPPFLAGS="$CPPFLAGS -I\${top_builddir}" AC_ARG_ENABLE(memleak, AS_HELP_STRING([--enable-memleak], [for test builds only: enable memory leak checking])) if test "$enable_memleak" = "yes"; then CPPFLAGS="$CPPFLAGS -DNEON_MEMLEAK -I\$(top_srcdir)/src" # disable 'make install' ALLOW_INSTALL=memleak fi # Enable tests for optional features TESTS="\$(BASIC_TESTS)" HELPERS="" if test $NE_FLAG_SSL = yes; then # Only enable SSL tests if an openssl binary is found (needed to make # certs etc). AC_PATH_PROG(OPENSSL, openssl, notfound) if test "$OPENSSL" != "notfound"; then TESTS="$TESTS \$(SSL_TESTS)" HELPERS="$HELPERS \$(SSL_HELPERS)" else AC_MSG_WARN([no openssl binary in \$PATH: SSL tests disabled]) fi AC_PATH_PROG(CERTUTIL, certutil, notfound) AC_PATH_PROG(PK12UTIL, pk12util, notfound) fi if test $NE_FLAG_ZLIB = yes; then TESTS="$TESTS \$(ZLIB_TESTS)" HELPERS="$HELPERS \$(ZLIB_HELPERS)" fi if test x$enable_webdav != xno; then TESTS="$TESTS \$(DAV_TESTS)" fi AC_ARG_ENABLE(tests-install, AS_HELP_STRING([--enable-tests-install], [enable installation of the test suite]),, [enable_tests_install=no]) # If test suite installation is not required, it's more # efficient to link the test programs using -no-install: if test "$enable_tests_install" = "no"; then TEST_LDFLAGS="-no-install" fi AC_SUBST(TEST_LDFLAGS) AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test "$PKG_CONFIG" != "no"; then # pkg-config >= 0.18 will use "Libs.private" iff necessary, # older versions which don't recognize that field may always # need all libraries in Libs. if $PKG_CONFIG --atleast-pkgconfig-version=0.18; then :; else NEON_PC_LIBS=${NEON_LIBS} fi fi AC_SUBST(NEON_PC_LIBS) # Pass the interface version on to libtool when linking libneon.la NEON_LINK_FLAGS="-version-info ${NE_LIBTOOL_VERSINFO}" # If any non-default ABI variations are used, add them to the SONAME: if test "x${NE_LIBTOOL_RELEASE}y" != "xy"; then NEON_LINK_FLAGS="${NEON_LINK_FLAGS} -release ${NE_LIBTOOL_RELEASE}" fi gl_LD_VERSION_SCRIPT # If ld version scripts are supported, enable symbol versioning. # Otherwise, fall back to any libtool-supported symbol export # restrictions; ne__* symbols are not exported. if test "x$have_ld_version_script" = "xyes"; then NEON_LINK_FLAGS="$NEON_LINK_FLAGS -Wl,--version-script=\$(top_srcdir)/src/neon.vers" else NEON_LINK_FLAGS="$NEON_LINK_FLAGS -export-symbols-regex '^ne_[[^_]]'" fi if test x${enable_shared}${pic_mode}z = xnodefaultz; then CFLAGS="$CFLAGS -prefer-pic" AC_MSG_NOTICE([Using PIC for static library build]) fi if test x${enable_shared} = xno; then # Defining NE_PRIVATE as the empty string would work; using a # non-empty but redundant string 'extern' avoids any possible cpp # confusion with from an empty macro. CPPFLAGS="$CPPFLAGS -DNE_PRIVATE=extern" AC_MSG_NOTICE([Private symbol suppression disabled for static library build]) fi # Bundled language catalogs ALL_LINGUAS="cs de fr ja nn pl ru tr zh_CN" AC_SUBST(ALL_LINGUAS) AC_CONFIG_FILES([neon-config], [chmod +x neon-config]) AC_CONFIG_FILES([Makefile src/Makefile test/Makefile neon.pc]) AC_CONFIG_FILES([test/makekeys:test/makekeys.sh], [chmod +x test/makekeys]) AC_SUBST(NEON_VERSION) AC_SUBST(NEON_BUILD_BUNDLED) AC_SUBST(top_builddir) AC_SUBST(user_LDFLAGS) AC_SUBST(HELPERS) AC_SUBST(TESTS) AC_SUBST(ALLOW_INSTALL) AC_OUTPUT # for VPATH builds: test -d test/common || mkdir test/common AC_MSG_NOTICE([Configured to build AC_PACKAGE_STRING: Install prefix: ${prefix} Compiler: ${CC} XML Parser: ${neon_xml_parser_message} SSL library: ${ne_SSL_message} zlib support: ${ne_ZLIB_message} Build libraries: Shared=${enable_shared}, Static=${enable_static} ]) case $ALLOW_INSTALL in memleak) AC_MSG_NOTICE([Configured with development-only flags: WARNING: This copy of neon has been configured with memory leak checking WARNING: enabled, which should only be used in a development build of neon. WARNING: This neon library should not be installed for use by applications. ]);; esac davix-R_0_5_0/deps/libneon/doc/000077500000000000000000000000001257152637300164135ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/doc/TODO000066400000000000000000000134131257152637300171050ustar00rootroot00000000000000/* List of interfaces needing reference documentation. -*- c -*- */ /* ne_session.h */ ### DONE: basics ne_session *ne_session_create(const char *scheme, const char *hostname, int port); void ne_session_destroy(ne_session *sess); void ne_close_connection(ne_session *sess); void ne_session_proxy(ne_session *sess, const char *hostname, int port); ### DONE: error handling void ne_set_error(ne_session *sess, const char *format, ...); const char *ne_get_error(ne_session *sess); ### DONE: options void ne_set_useragent(ne_session *sess, const char *product); void ne_set_expect100(ne_session *sess, int use_expect100); void ne_set_persist(ne_session *sess, int persist); void ne_set_read_timeout(ne_session *sess, int timeout); ### TODO: progress + status callbcacks void ne_set_progress(ne_session *sess, ne_progress progress, void *userdata); ### TODO: status callback typedef enum ne_conn_status; typedef void (*ne_notify_status)(void *userdata, ne_conn_status status, const char *info); void ne_set_status(ne_session *sess, ne_notify_status status, void *userdata); ### DONE: SSL verification typedef struct ne_ssl_dname; char *ne_ssl_readable_dname(const ne_ssl_dname *dn); typedef struct ne_ssl_certificate; #define NE_SSL_* typedef int (*ne_ssl_verify_fn)(void *userdata, int failures, const ne_ssl_certificate *cert); void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdata); ### DONE: SSL server certs int ne_ssl_load_ca(ne_session *sess, const char *file); int ne_ssl_load_default_ca(ne_session *sess); ### TODO: SSL client certs typedef int (*ne_ssl_keypw_fn)(void *userdata, char *pwbuf, size_t len); void ne_ssl_keypw_prompt(ne_session *sess, ne_ssl_keypw_fn fn, void *ud); int ne_ssl_load_pkcs12(ne_session *sess, const char *fn); int ne_ssl_load_pem(ne_session *sess, const char *certfn, const char *keyfn); typedef void (*ne_ssl_provide_fn)(void *userdata, ne_session *sess, const ne_ssl_dname *server); void ne_ssl_provide_ccert(ne_session *sess, ne_ssl_provide_fn fn, void *userdata); #ifdef NEON_SSL SSL_CTX *ne_ssl_get_context(ne_session *sess); X509 *ne_ssl_server_cert(ne_session *req); #endif ### TODO: utility functions int ne_version_pre_http11(ne_session *sess); const char *ne_get_server_hostport(ne_session *sess); const char *ne_get_scheme(ne_session *sess); void ne_fill_server_uri(ne_session *sess, ne_uri *uri); /* end of ne_session.h *****************************************/ /* ne_request.h */ ### DONE: request basics ne_request *ne_request_create(ne_session *sess, const char *method, const char *path); int ne_request_dispatch(ne_request *req); void ne_request_destroy(ne_request *req); ### DONE: request status const ne_status *ne_get_status(ne_request *req); ### TODO: request bodies void ne_set_request_body_buffer(ne_request *req, const char *buf, size_t count); int ne_set_request_body_fd(ne_request *req, int fd, size_t count); typedef ssize_t (*ne_provide_body)(void *userdata, char *buffer, size_t buflen); void ne_set_request_body_provider(ne_request *req, size_t size, ne_provide_body provider, void *userdata); ### TODO: response bodies typedef int (*ne_accept_response)(void *userdata, ne_request *req, ne_status *st); int ne_accept_2xx(void *userdata, ne_request *req, ne_status *st); int ne_accept_always(void *userdata, ne_request *req, ne_status *st); void ne_add_response_body_reader(ne_request *req, ne_accept_response accpt, ne_block_reader reader, void *userdata); ### TODO: response headers typedef void (*ne_header_handler)(void *userdata, const char *value); void ne_add_response_header_handler(ne_request *req, const char *name, ne_header_handler hdl, void *userdata); void ne_add_response_header_catcher(ne_request *req, ne_header_handler hdl, void *userdata); void ne_duplicate_header(void *userdata, const char *value); void ne_handle_numeric_header(void *userdata, const char *value); ### DONE: request headers void ne_add_request_header(ne_request *req, const char *name, const char *value); void ne_print_request_header(ne_request *req, const char *name, const char *format, ...); ### TODO: misc ne_session *ne_get_session(ne_request *req); ### TODO: caller-pulls request interface int ne_begin_request(ne_request *req); int ne_end_request(ne_request *req); ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen); ### TODO: hooks typedef void (*ne_free_hooks)(void *cookie); typedef void (*ne_create_request_fn)(void *userdata, ne_request *req, const char *method, const char *path); void ne_hook_create_request(ne_session *sess, ne_create_request_fn fn, void *userdata); typedef void (*ne_pre_send_fn)(void *userdata, ne_buffer *header); void ne_hook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata); typedef int (*ne_post_send_fn)(void *userdata, const ne_status *status); void ne_hook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata); typedef void (*ne_destroy_fn)(void *userdata); void ne_hook_destroy_request(ne_session *sess, ne_destroy_fn fn, void *userdata); void ne_hook_destroy_session(ne_session *sess, ne_destroy_fn fn, void *userdata); typedef void *(*ne_accessor_fn)(void *userdata); void ne_hook_session_accessor(ne_session *sess, const char *id, ne_accessor_fn, void *userdata); void ne_hook_request_accessor(ne_request *req, const char *id, ne_accessor_fn, void *userdata); void *ne_null_accessor(void *userdata); void *ne_session_hook_private(ne_session *sess, const char *id); void *ne_request_hook_private(ne_request *req, const char *id); /* ne_207.h */ /* ne_acl.h */ /* DONE: ne_alloc.h */ /* DONE: ne_auth.h */ /* ne_basic.h */ /* ne_compress.h */ /* ne_cookies.h */ /* ne_dates.h */ /* ne_locks.h */ /* ne_props.h */ /* ne_redirect.h */ /* ne_socket.h */ /* MOSTLY DONE: ne_string.h */ /* ne_uri.h */ /* ne_utils.h */ /* ne_xml.h */ davix-R_0_5_0/deps/libneon/doc/biblio.xml000066400000000000000000000057601257152637300204050ustar00rootroot00000000000000 SSL-and-TLS <ulink url="http://www.rtfm.com/sslbook/">SSL and TLS: Designing and Building Secure Systems</ulink> EricRescorla 0-201-62598-3 Addison-Wesley March 2001 REC-XML-names World Wide Web Consortium <ulink url="http://www.w3.org/TR/REC-xml-names">Namespaces in XML</ulink> January 1999 RFC2616 <ulink url="http://www.ietf.org/rfc/rfc2616.txt">Hypertext Transfer Protocol—HTTP/1.1</ulink> RoyFielding JimGettys JeffMogul HenrikFrystyk LarryMasinter PaulLeach TimBerners-Lee IETF June 1999 RFC2518 <ulink url="http://www.ietf.org/rfc/rfc2518.txt">HTTP Extensions for Distributed Authoring—WEBDAV</ulink> YaronGoland JimWhitehead AsadFaizi SteveCarter DelJensen IETF February 1999 RFC3280 <ulink url="http://www.ietf.org/rfc/rfc3280.txt">Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile</ulink> RusselHousley WarwickFord TimPolk DavidSolo IETF April 2002 davix-R_0_5_0/deps/libneon/doc/date.xml000066400000000000000000000000131257152637300200440ustar00rootroot00000000000000 3 May 2011davix-R_0_5_0/deps/libneon/doc/feat.xml000066400000000000000000000061751257152637300200650ustar00rootroot00000000000000 Feature list The major features of the neon library are as follows: A high-level interface to common HTTP and WebDAV methods. This allows you to easily dispatch a GET or a MKCOL request against a resource with a single function call. A low-level interface for HTTP request handling; allowing you to implement requests using arbitrary methods and request headers, capture arbitrary response headers, and so on. Persistent connection support; neon groups a set of requests to a server into a "session"; requests within that session can use a persistent (also known as "keep-alive") connection. Modern HTTP authentication support: a complete implementation of the new authentication standard, RFC2617, supporting the Digest, Basic, and Negotiate protocols. Credentials are supplied by an application-defined callback as appropriate. Proxy server support; a session can be set to use a proxy server. Authentication is supported for the Proxy as well as the origin server. The system's proxy configuration can be optionally used, on some platforms. Complete SSL support; a simple interface for enabling SSL, hiding the complexity of using an SSL library directly. Client certificate support, callback-based server certificate verification, along with functions to load trusted CA certificates. Smartcard-based client certs are also supported via a wrapper interface for PKCS#11 modules. Compressed response support: responses compressed using the "deflate" algorithm can be transparently decompressed. Generic XML parsing interface for handling XML response bodies using SAX-like callbacks. Both the expat and libxml XML parser libraries are supported. WebDAV metadata support; set and remove properties, query properties (PROPFIND); simple interface for retrieving "flat" byte-string properties, more advanced support for parsing "complex" structured XML properties. Build environment support: the neon source tree is designed so that it can be embedded in your application's build tree; autoconf macros are supplied for integration. To get started quickly a script is included, to easily determine how to compile and link against an installed copy of neon Complete test suite: the neon test suite comprises half as many lines of source code as the library itself, including many tests for protocol compliance in network behaviour, and that the library implementation meets the guarantees made by the API. davix-R_0_5_0/deps/libneon/doc/html.xsl000066400000000000000000000046031257152637300201120ustar00rootroot00000000000000 ../manual.css programlisting
davix-R_0_5_0/deps/libneon/doc/html/000077500000000000000000000000001257152637300173575ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/doc/html/api.html000066400000000000000000000047711257152637300210270ustar00rootroot00000000000000Chapter 2. The neon C language interface

Chapter 2. The neon C language interface

The documentation for the neon interface is split between this chapter, which gives a broad introduction to the abstractions exposed by the library, and neon API reference, which gives a function-by-function breakdown of the interface.

davix-R_0_5_0/deps/libneon/doc/html/biblio.html000066400000000000000000000116271257152637300215140ustar00rootroot00000000000000Bibliography

Bibliography

[SSL-and-TLS] SSL and TLS: Designing and Building Secure Systems. Eric Rescorla. 0-201-62598-3. Addison-Wesley. March 2001.

[REC-XML-names] World Wide Web Consortium. Namespaces in XML. January 1999.

[RFC2616] Hypertext Transfer Protocol—HTTP/1.1. Roy Fielding, Jim Gettys, Jeff Mogul, Henrik Frystyk, Larry Masinter, Paul Leach, and Tim Berners-Lee. IETF. June 1999.

[RFC2518] HTTP Extensions for Distributed Authoring—WEBDAV. Yaron Goland, Jim Whitehead, Asad Faizi, Steve Carter, and Del Jensen. IETF. February 1999.

[RFC3280] Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. Russel Housley, Warwick Ford, Tim Polk, and David Solo. IETF. April 2002.

davix-R_0_5_0/deps/libneon/doc/html/compliance.html000066400000000000000000000124631257152637300223650ustar00rootroot00000000000000Standards compliance

Standards compliance

neon is intended to be compliant with the IETF and W3C standards which it implements, with a few exceptions due to practical necessity or interoperability issues. These exceptions are documented in this section.

RFC 2518, HTTP Extensions for Distributed Authoring—WebDAV

neon is deliberately not compliant with section 23.4.2, and treats property names as a (namespace-URI, name) pair. This is generally considered to be correct behaviour by the WebDAV working group, and is likely to formally adopted in a future revision of the specification.

RFC 2616, Hypertext Transfer Protocol—HTTP/1.1

There is some confusion in this specification about the use of the identity transfer-coding. neon ignores the Transfer-Encoding response header if it contains only the (now deprecated) identity token, and will determine the response message length as if the header was not present. neon will give an error if a response includes a Transfer-Encoding header with a value other than identity or chunked.

RFC 2617, HTTP Authentication: Basic and Digest Access Authentication

neon is not strictly compliant with the quoting rules given in the grammar for the Authorization header. The grammar requires that the qop and algorithm parameters are not quoted, however one widely deployed server implementation (Microsoft® IIS 5) rejects the request if these parameters are not quoted. neon sends these parameters with quotes—this is not known to cause any problems with other server implementations.

Namespaces in XML

The neon XML parser interface will accept and parse without error some XML documents which are well-formed according to the XML specification but do not conform to the "Namespaces in XML" specification [REC-XML-names]. Specifically: the restrictions on the first character of the NCName rule are not all implemented; neon will allow any CombiningChar, Extender and some characters from the Digit class in this position.

davix-R_0_5_0/deps/libneon/doc/html/features.html000066400000000000000000000111321257152637300220610ustar00rootroot00000000000000Feature list

Feature list

The major features of the neon library are as follows:

  • A high-level interface to common HTTP and WebDAV methods. This allows you to easily dispatch a GET or a MKCOL request against a resource with a single function call.

  • A low-level interface for HTTP request handling; allowing you to implement requests using arbitrary methods and request headers, capture arbitrary response headers, and so on.

  • Persistent connection support; neon groups a set of requests to a server into a "session"; requests within that session can use a persistent (also known as "keep-alive") connection.

  • Modern HTTP authentication support: a complete implementation of the new authentication standard, RFC2617, supporting the Digest, Basic, and Negotiate protocols. Credentials are supplied by an application-defined callback as appropriate.

  • Proxy server support; a session can be set to use a proxy server. Authentication is supported for the Proxy as well as the origin server. The system's proxy configuration can be optionally used, on some platforms.

  • Complete SSL support; a simple interface for enabling SSL, hiding the complexity of using an SSL library directly. Client certificate support, callback-based server certificate verification, along with functions to load trusted CA certificates. Smartcard-based client certs are also supported via a wrapper interface for PKCS#11 modules.

  • Compressed response support: responses compressed using the "deflate" algorithm can be transparently decompressed.

  • Generic XML parsing interface for handling XML response bodies using SAX-like callbacks. Both the expat and libxml XML parser libraries are supported.

  • WebDAV metadata support; set and remove properties, query properties (PROPFIND); simple interface for retrieving "flat" byte-string properties, more advanced support for parsing "complex" structured XML properties.

  • Build environment support: the neon source tree is designed so that it can be embedded in your application's build tree; autoconf macros are supplied for integration. To get started quickly a neon-config script is included, to easily determine how to compile and link against an installed copy of neon

  • Complete test suite: the neon test suite comprises half as many lines of source code as the library itself, including many tests for protocol compliance in network behaviour, and that the library implementation meets the guarantees made by the API.

davix-R_0_5_0/deps/libneon/doc/html/index.html000066400000000000000000000251651257152637300213650ustar00rootroot00000000000000neon HTTP/WebDAV client library

neon HTTP/WebDAV client library

This document is free documentation; 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 document 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.


Table of Contents

1. Introduction
Feature list
How to use neon from your application
Standards compliance
RFC 2518, HTTP Extensions for Distributed Authoring—WebDAV
RFC 2616, Hypertext Transfer Protocol—HTTP/1.1
RFC 2617, HTTP Authentication: Basic and Digest Access Authentication
Namespaces in XML
HTTP Client Security
CPU or memory consumption attacks
SSL/TLS connection security
Control character insertion in error messages
Attacks against authentication credentials
2. The neon C language interface
Parsing XML
Introduction to SAX
Stacked SAX handlers
Maintaining state
XML namespaces
I. neon API reference
neon — HTTP and WebDAV client library
neon-config — script providing information about installed copy of neon library
ne_addr_resolve — functions to resolve hostnames to addresses
ne_buffer — string buffer handling
ne_buffer_append — append data to a string buffer
ne_buffer_clear — clear, grow, or mark as altered a string buffer
ne_buffer_create — create a string buffer
ne_buffer_destroy — destroy a buffer object
ne_get_error — error handling for HTTP sessions
ne_get_status — retrieve HTTP response status for request
ne_has_support — determine feature support status
ne_i18n_init — functions to initialize internationalization support
ne_iaddr_make — functions to manipulate network addresses
ne_malloc — memory allocation wrappers
ne_session_create — set up HTTP sessions
ne_set_session_flag — set and retrieve session flags
ne_request_create — low-level HTTP request handling
ne_add_request_header — add headers to a request
ne_get_response_header — functions to access response headers
ne_set_useragent — common properties for HTTP sessions
ne_set_request_flag — set and retrieve per-request flags
ne_set_request_body_buffer — include a message body with a request
ne_set_server_auth — register authentication callbacks
ne_shave — trim whitespace from a string
ne_sock_init — perform library initialization
ne_ssl_cert_identity — functions to access certificate properties
ne_ssl_cert_cmp — functions to operate on certificate objects
ne_ssl_cert_read — functions to read or write certificates to and from files or strings
ne_ssl_dname — SSL distinguished name handling
ne_ssl_trust_cert — functions to indicate that certificates are trusted
ne_ssl_set_verify — register an SSL certificate verification callback
ne_ssl_client_cert — SSL client certificate handling
ne_status — HTTP status structure
ne_token — string tokenizers
ne_version_match — library versioning
ne_xml_create — create and destroy an XML parser
Bibliography

List of Examples

2.1. An example XML document
davix-R_0_5_0/deps/libneon/doc/html/intro.html000066400000000000000000000067331257152637300214110ustar00rootroot00000000000000Chapter 1. Introduction

Chapter 1. Introduction

This chapter provides an introduction to neon, giving an overview of the range of features offered, and some general guidelines for using the neon API.

neon aims to provide a modern, flexible, and simple API in the C programming language for implementing HTTP and WebDAV support. The WebDAV functionality is entirely separate from the basic HTTP functionality; neon can be used simply as an HTTP client library, ignoring the WebDAV support if desired.

davix-R_0_5_0/deps/libneon/doc/html/ref.html000066400000000000000000000163541257152637300210320ustar00rootroot00000000000000neon API reference

neon API reference


Table of Contents

neon — HTTP and WebDAV client library
neon-config — script providing information about installed copy of neon library
ne_addr_resolve — functions to resolve hostnames to addresses
ne_buffer — string buffer handling
ne_buffer_append — append data to a string buffer
ne_buffer_clear — clear, grow, or mark as altered a string buffer
ne_buffer_create — create a string buffer
ne_buffer_destroy — destroy a buffer object
ne_get_error — error handling for HTTP sessions
ne_get_status — retrieve HTTP response status for request
ne_has_support — determine feature support status
ne_i18n_init — functions to initialize internationalization support
ne_iaddr_make — functions to manipulate network addresses
ne_malloc — memory allocation wrappers
ne_session_create — set up HTTP sessions
ne_set_session_flag — set and retrieve session flags
ne_request_create — low-level HTTP request handling
ne_add_request_header — add headers to a request
ne_get_response_header — functions to access response headers
ne_set_useragent — common properties for HTTP sessions
ne_set_request_flag — set and retrieve per-request flags
ne_set_request_body_buffer — include a message body with a request
ne_set_server_auth — register authentication callbacks
ne_shave — trim whitespace from a string
ne_sock_init — perform library initialization
ne_ssl_cert_identity — functions to access certificate properties
ne_ssl_cert_cmp — functions to operate on certificate objects
ne_ssl_cert_read — functions to read or write certificates to and from files or strings
ne_ssl_dname — SSL distinguished name handling
ne_ssl_trust_cert — functions to indicate that certificates are trusted
ne_ssl_set_verify — register an SSL certificate verification callback
ne_ssl_client_cert — SSL client certificate handling
ne_status — HTTP status structure
ne_token — string tokenizers
ne_version_match — library versioning
ne_xml_create — create and destroy an XML parser
davix-R_0_5_0/deps/libneon/doc/html/refalloc.html000066400000000000000000000115751257152637300220450ustar00rootroot00000000000000ne_malloc

Name

ne_malloc, ne_calloc, ne_realloc, ne_strdup, ne_strndup, ne_oom_callback — memory allocation wrappers

Synopsis

#include <ne_alloc.h>
void *ne_malloc(size_t size);
 
void *ne_calloc(size_t size);
 
void *ne_realloc(void *size,
 size_t len);
 
char *ne_strdup(const char *s);
 
char *ne_strndup(const char *s,
 size_t size);
 
void ne_oom_callback(void (*callback)(void));
 

Description

The functions ne_malloc, ne_calloc, ne_realloc, ne_strdup and ne_strdnup provide wrappers for the equivalent functions in the standard C library. The wrappers provide the extra guarantee that if the C library equivalent returns NULL when no memory is available, an optional callback will be called, and the library will then call abort().

ne_oom_callback registers a callback which will be invoked if an out of memory error is detected.

Notes

If the operating system uses optimistic memory allocation, the C library memory allocation routines will not return NULL, so it is not possible to gracefully handle memory allocation failures.

davix-R_0_5_0/deps/libneon/doc/html/refauth.html000066400000000000000000000136031257152637300217060ustar00rootroot00000000000000ne_set_server_auth

Name

ne_set_server_auth, ne_set_proxy_auth, ne_forget_auth — register authentication callbacks

Synopsis

#include <ne_auth.h>
typedef int (*ne_auth_creds)(void *userdata,
 const char *realm,
 int attempt,
 char *username,
 char *password);
 
void ne_set_server_auth(ne_session *session,
 ne_auth_creds callback,
 void *userdata);
 
void ne_set_proxy_auth(ne_session *session,
 ne_auth_creds callback,
 void *userdata);
 
void ne_forget_auth(ne_session *session);
 

Description

The ne_auth_creds function type defines a callback which is invoked when a server or proxy server requires user authentication for a particular request. The realm string is supplied by the server. The attempt is a counter giving the number of times the request has been retried with different authentication credentials. The first time the callback is invoked for a particular request, attempt will be zero.

To retry the request using new authentication credentials, the callback should return zero, and the username and password buffers must contain NUL-terminated strings. The NE_ABUFSIZ constant gives the size of these buffers.

Tip

If you only wish to allow the user one attempt to enter credentials, use the value of the attempt parameter as the return value of the callback.

To abort the request, the callback should return a non-zero value; in which case the contents of the username and password buffers are ignored.

The ne_forget_auth function can be used to discard the cached authentication credentials.

Examples

/* Function which prompts for a line of user input: */
extern char *prompt_for(const char *prompt);

static int
my_auth(void *userdata, const char *realm, int attempts,
        char *username, char *password)
{
   strncpy(username, prompt_for("Username: "), NE_ABUFSIZ);
   strncpy(password, prompt_for("Password: "), NE_ABUFSIZ);
   return attempts;
}

int main(...)
{
   ne_session *sess = ne_session_create(...);

   ne_set_server_auth(sess, my_auth, NULL);

   /* ... */
}
davix-R_0_5_0/deps/libneon/doc/html/refbuf.html000066400000000000000000000070021257152637300215150ustar00rootroot00000000000000ne_buffer

Name

ne_buffer — string buffer handling

Synopsis

#include <ne_string.h>

typedef struct {
    char *data;
    size_t used;
    size_t length;
} ne_buffer;

Description

The ne_buffer type represents an expandable memory buffer for holding NUL-terminated strings. The data field points to the beginnning of the string, the length of which is given by the used field. The current size of memory allocated is given by the length field. It is not recommended that the fields of a buffer are manipulated directly. The data pointer may change when the buffer is modified.

A buffer is created using ne_buffer_create or ne_buffer_ncreate, and destroyed using ne_buffer_destroy or ne_buffer_finish. The functions ne_buffer_append, ne_buffer_zappend and ne_buffer_concat are used to append data to a buffer.

If the string referenced by the data pointer is modified directly (rather than using one of the functions listed above), ne_buffer_altered must be called.

davix-R_0_5_0/deps/libneon/doc/html/refbufapp.html000066400000000000000000000120171257152637300222200ustar00rootroot00000000000000ne_buffer_append

Name

ne_buffer_append, ne_buffer_zappend, ne_buffer_concat — append data to a string buffer

Synopsis

#include <ne_string.h>
void ne_buffer_append(ne_buffer *buf,
 const char *string,
 size_t len);
 
void ne_buffer_zappend(ne_buffer *buf,
 const char *string);
 
void ne_buffer_concat(ne_buffer *buf,
 const char *str,
 ...);
 

Description

The ne_buffer_append and ne_buffer_zappend functions append a string to the end of a buffer; extending the buffer as necessary. The len passed to ne_buffer_append specifies the length of the string to append; there must be no NUL terminator in the first len bytes of the string. ne_buffer_zappend must be passed a NUL-terminated string.

The ne_buffer_concat function takes a variable-length argument list following str; each argument must be a char * pointer to a NUL-terminated string. A NULL pointer must be given as the last argument to mark the end of the list. The strings (including str) are appended to the buffer in the order given. None of the strings passed to ne_buffer_concat are modified.

Examples

The following code will output "Hello, world. And goodbye.".

ne_buffer *buf = ne_buffer_create();
ne_buffer_zappend(buf, "Hello");
ne_buffer_concat(buf, ", world. ", "And ", "goodbye.", NULL);
puts(buf->data);
ne_buffer_destroy(buf);
davix-R_0_5_0/deps/libneon/doc/html/refbufcr.html000066400000000000000000000064531257152637300220530ustar00rootroot00000000000000ne_buffer_create

Name

ne_buffer_create, ne_buffer_ncreate — create a string buffer

Synopsis

#include <ne_alloc.h>
ne_buffer *ne_buffer_create(void); 
 
ne_buffer *ne_buffer_ncreate(size_t size);
 

Description

ne_buffer_create creates a new buffer object, with an implementation-defined initial size. ne_buffer_ncreate creates an ne_buffer where the minimum initial size is given in the size parameter. The buffer created will contain the empty string ("").

Return value

Both functions return a pointer to a new buffer object, and never NULL.

See also

ne_buffer

davix-R_0_5_0/deps/libneon/doc/html/refbufdest.html000066400000000000000000000100001257152637300223650ustar00rootroot00000000000000ne_buffer_destroy

Name

ne_buffer_destroy, ne_buffer_finish — destroy a buffer object

Synopsis

#include <ne_string.h>
void ne_buffer_destroy(ne_buffer *buf);
 
char *ne_buffer_finish(ne_buffer *buf);
 

Description

ne_buffer_destroy frees all memory associated with the buffer. ne_buffer_finish frees the buffer structure, but not the actual string stored in the buffer, which is returned and must be free()d by the caller.

Any use of the buffer object after calling either of these functions gives undefined behaviour.

Return value

ne_buffer_finish returns the malloc-allocated string stored in the buffer.

Examples

An example use of ne_buffer_finish; the duplicate function returns a string made up of n copies of str:

static char *duplicate(int n, const char *str)
{
  ne_buffer *buf = ne_buffer_create();
  while (n--) {
    ne_buffer_zappend(buf, str);
  }
  return ne_buffer_finish(buf);
}
davix-R_0_5_0/deps/libneon/doc/html/refbufutil.html000066400000000000000000000075641257152637300224300ustar00rootroot00000000000000ne_buffer_clear

Name

ne_buffer_clear, ne_buffer_grow, ne_buffer_altered — clear, grow, or mark as altered a string buffer

Synopsis

#include <ne_string.h>
void ne_buffer_clear(ne_buffer *buf);
 
void ne_buffer_altered(ne_buffer *buf);
 
void ne_buffer_grow(ne_buffer *buf,
 size_t size);
 

Description

The ne_buffer_clear function sets the string stored in buf to be the empty string ("").

The ne_buffer_altered function must be used after the string stored in the buffer buf is modified by directly rather than using ne_buffer_append, ne_buffer_zappend or ne_buffer_concat.

The ne_buffer_grow function ensures that at least size bytes are allocated for the string; this can be used if a large amount of data is going to be appended to the buffer and may result in more efficient memory allocation.

davix-R_0_5_0/deps/libneon/doc/html/refcert.html000066400000000000000000000135471257152637300217110ustar00rootroot00000000000000ne_ssl_cert_identity

Name

ne_ssl_cert_identity, ne_ssl_cert_signedby, ne_ssl_cert_issuer, ne_ssl_cert_subject — functions to access certificate properties

Synopsis

#include <ne_ssl.h>
const char *ne_ssl_cert_identity(const ne_ssl_certificate *cert);
 
const ne_ssl_certificate *ne_ssl_cert_signedby(const ne_ssl_certificate *cert);
 
const ne_ssl_dname *ne_ssl_cert_subject(const ne_ssl_certificate *cert);
 
const ne_ssl_dname *ne_ssl_cert_issuer(const ne_ssl_certificate *cert);
 

Description

The function ne_ssl_cert_identity retrieves the identity of a certificate; for an SSL server certificate, this will be the hostname for which the certificate was issued. In PKI parlance, the identity is the common name attribute of the distinguished name of the certificate subject.

The functions ne_ssl_cert_subject and ne_ssl_cert_issuer can be used to access the objects representing the distinguished name of the subject and of the issuer of a certificate, respectively.

If a certificate object is part of a certificate chain, then ne_ssl_cert_signedby can be used to find the certificate which signed a particular certificate. For a self-signed certificate or a certificate for which the full chain is not available, this function will return NULL.

Return value

ne_ssl_cert_issuer and ne_ssl_cert_subject are guaranteed to never return NULL. ne_ssl_cert_identity may return NULL if the certificate has no specific identity. ne_ssl_cert_signedby may return NULL as covered above.

Examples

The following function could be used to display information about a given certificate:

void dump_cert(const ne_ssl_certificate *cert) {
  const char *id = ne_ssl_cert_identity(cert);
  char *dn;

  if (id) 
    printf("Certificate was issued for '%s'.\n", id);

  dn = ne_ssl_readable_dname(ne_ssl_cert_subject(cert));
  printf("Subject: %s\n", dn);
  free(dn);

  dn = ne_ssl_readable_dname(ne_ssl_cert_issuer(cert));
  printf("Issuer: %s\n", dn);
  free(dn);
}
davix-R_0_5_0/deps/libneon/doc/html/refclicert.html000066400000000000000000000175271257152637300224030ustar00rootroot00000000000000ne_ssl_client_cert

Name

ne_ssl_clicert_read, ne_ssl_clicert_name, ne_ssl_clicert_encrypted, ne_ssl_clicert_decrypt, ne_ssl_clicert_owner, ne_ssl_clicert_free — SSL client certificate handling

Synopsis

#include <ne_ssl.h>
ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename);
 
const char *ne_ssl_clicert_name(const ne_ssl_client_cert *ccert);
 
int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *ccert);
 
int ne_ssl_clicert_decrypt(ne_ssl_client_cert *ccert,
 const char *password);
 
const ne_ssl_certificate *ne_ssl_clicert_owner(const ne_ssl_client_cert *ccert);
 
void ne_ssl_clicert_free(ne_ssl_client_cert *ccert);
 

Description

The ne_ssl_clicert_read function reads a client certificate from a PKCS#12-formatted file, and returns an ne_ssl_client_cert object. If the client certificate is encrypted, it must be decrypted before it is used. An ne_ssl_client_cert object holds a client certificate and the associated private key, not just a certificate; the term "client certificate" will used to refer to this pair.

A client certificate can be in one of two states: encrypted or decrypted. The ne_ssl_clicert_encrypted function will return non-zero if the client certificate is in the encrypted state. A client certificate object returned by ne_ssl_clicert_read may be initially in either state, depending on whether the file was encrypted or not.

ne_ssl_clicert_decrypt can be used to decrypt a client certificate using the appropriate password. This function must only be called if the object is in the encrypted state; if decryption fails, the certificate state does not change, so decryption can be attempted more than once using different passwords.

A client certificate can be given a "friendly name" when it is created; ne_ssl_clicert_name will return this name (or NULL if no friendly name was specified). ne_ssl_clicert_name can be used when the client certificate is in either the encrypted or decrypted state, and will return the same string for the lifetime of the object.

The function ne_ssl_clicert_owner returns the certificate part of the client certificate; it must only be called if the client certificate is in the decrypted state.

When the client certificate is no longer needed, the ne_ssl_clicert_free function should be used to destroy the object.

Return value

ne_ssl_clicert_read returns a client certificate object, or NULL if the file could not be read. ne_ssl_clicert_encrypted returns zero if the object is in the decrypted state, or non-zero if it is in the encrypted state. ne_ssl_clicert_name returns a NUL-terminated friendly name string, or NULL. ne_ssl_clicert_owner returns a certificate object.

Examples

The following code reads a client certificate and decrypts it if necessary, then loads it into an HTTP session.

ne_ssl_client_cert *ccert;

ccert = ne_ssl_clicert_read("/path/to/client.p12");

if (ccert == NULL) {
   /* handle error... */
} else if (ne_ssl_clicert_encrypted(ccert)) {
   char *password = prompt_for_password();

   if (ne_ssl_clicert_decrypt(ccert, password)) {
      /* could not decrypt! handle error... */
   }
}

ne_ssl_set_clicert(sess, ccert);
davix-R_0_5_0/deps/libneon/doc/html/refconfig.html000066400000000000000000000121271257152637300222120ustar00rootroot00000000000000neon-config

Name

neon-config — script providing information about installed copy of neon library

Synopsis

neon-config [--prefix] [[--cflags] | [--libs] | [--la-file] | [--support feature] | [--help] | [--version]]

Description

The neon-config script provides information about an installed copy of the neon library. The --cflags and --libs options instruct how to compile and link an application against the library; the --version and --support options can help determine whether the library meets the applications requirements.

Options

--cflags

Print the flags which should be passed to the C compiler when compiling object files, when the object files use neon header files.

--libs

Print the flags which should be passed to the linker when linking an application which uses the neon library

--la-file

Print the location of the libtool library script, libneon.la, which can be used to link against neon by applications using libtool.

--version

Print the version of the library

--prefix dir

If dir is given; relocate output of --cflags and --libs as if neon was installed in given prefix directory. Otherwise, print the installation prefix of the library.

--support feature

The script exits with success if feature is supported by the library.

--help

Print help message; includes list of known features and whether they are supported or not.

Example

Below is a Makefile fragment which could be used to build an application against an installed neon library, when the neon-config script can be found in $PATH.

CFLAGS = `neon-config --cflags`
LIBS = `neon-config --libs`
OBJECTS = myapp.o
TARGET = myapp

$(TARGET): $(OBJECTS)
	$(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)

myapp.o: myapp.c
	$(CC) $(CFLAGS) -c myapp.c -o myapp.o
davix-R_0_5_0/deps/libneon/doc/html/referr.html000066400000000000000000000104701257152637300215340ustar00rootroot00000000000000ne_get_error

Name

ne_get_error, ne_set_error — error handling for HTTP sessions

Synopsis

#include <ne_session.h>
const char *ne_get_error(ne_sesssion *session);
 
void ne_set_error(ne_sesssion *session,
 const char *format,
 ...);
 

Description

The session error string is used to store any human-readable error information associated with any errors which occur whilst using the HTTP session.

The ne_get_error function returns the current session error string. This string persists only until it is changed by a subsequent operation on the session. If localisation was enabled at build time, and if necessary enabled at run-time if necessary using ne_i18n_init, the returned string may have been translated into the user's current locale.

The ne_set_error function can be used to set a new session error string, using a printf-style format string interface.

Return value

ne_set_error returns a constant NUL-terminated string. In the default English locale, the returned string will not have a terminating . period character.

Examples

Retrieve the current error string:

ne_session *sess = ne_session_create(...);
...
printf("Error was: %s\n", ne_get_error(sess));

Set a new error string:

ne_session *sess = ne_session_create(...);
...
ne_set_error(sess, "Response missing header %s", "somestring");
davix-R_0_5_0/deps/libneon/doc/html/reffeat.html000066400000000000000000000100461257152637300216620ustar00rootroot00000000000000ne_has_support

Name

ne_has_support — determine feature support status

Synopsis

#include <ne_utils.h>
int ne_has_support(int feature);
 

Description

The ne_has_support function can be used to determine whether a particular optional feature, given by the feature code feature, is supported. The following feature codes are available:

NE_FEATURE_SSL

Indicates support for SSL/TLS

NE_FEATURE_ZLIB

Indicates support for compressed responses

NE_FEATURE_IPV6

Indicates support for IPv6

NE_FEATURE_LFS

Indicates support for large files

NE_FEATURE_SOCKS

Indicates support for SOCKSv5

NE_FEATURE_TS_SSL

Indicates support for thread-safe SSL initialization — see ne_sock_init

Return value

ne_has_support returns non-zero if the given feature is supported, or zero otherwise.

davix-R_0_5_0/deps/libneon/doc/html/refgetst.html000066400000000000000000000066051257152637300220770ustar00rootroot00000000000000ne_get_status

Name

ne_get_status — retrieve HTTP response status for request

Synopsis

#include <ne_request.h>
const ne_status *ne_get_status(const ne_request *request);
 

Description

The ne_get_status function returns a pointer to the HTTP status object giving the result of a request. The object returned only becomes valid once the request has been successfully dispatched (the return value of ne_request_dispatch or ne_begin_request was zero). The object remains valid until the associated request object is destroyed.

Example

Display the response status code of applying the HEAD method to some resource.

ne_request *req = ne_request_create(sess, "HEAD", "/foo/bar");
if (ne_request_dispatch(req))
   /* handle errors... */
else
   printf("Response status code was %d\n", ne_get_status(req)->code);
ne_request_destroy(req);
davix-R_0_5_0/deps/libneon/doc/html/refi18n.html000066400000000000000000000074561257152637300215350ustar00rootroot00000000000000ne_i18n_init

Name

ne_i18n_init — functions to initialize internationalization support

Synopsis

#include <ne_i18n.h>
void ne_i18n_init(const char *encoding);
 

Description

The ne_i18n_init function can be used to enable support for translated messages in the neon library. The encoding parameter, if non-NULL, specifies the character encoding required for generated translated string. If it is NULL, the appropriate character encoding for the process locale will be used.

This call is only strictly necessary if either:

  1. neon has been installed into a different prefix than the gettext implementation on which it depends for i18n purposes, or
  2. the caller requires that translated messages are in a particular character encoding.

If ne_i18n_init is never called, the message catalogs will not be found if case (a) applies (and so English error messages will be used), and will use the default character encoding specified by the process locale. The library will otherwise operate correctly.

Note that the encoding used is a process-global setting and so results may be unexpected if other users of neon within the process call ne_i18n_init with a different encoding parameter.

See also

ne_sock_init

davix-R_0_5_0/deps/libneon/doc/html/refiaddr.html000066400000000000000000000216761257152637300220410ustar00rootroot00000000000000ne_iaddr_make

Name

ne_iaddr_make, ne_iaddr_cmp, ne_iaddr_print, ne_iaddr_typeof, ne_iaddr_parse, ne_iaddr_raw, ne_iaddr_reverse, ne_iaddr_free — functions to manipulate network addresses

Synopsis

#include <ne_socket.h>

typedef enum {
    ne_iaddr_ipv4 = 0,
    ne_iaddr_ipv6
} ne_iaddr_type;
ne_inet_addr *ne_iaddr_make(ne_iaddr_type type,
 const unsigned char *raw);
 
int ne_iaddr_cmp(const ne_inet_addr *ia1,
 const ne_inet_addr *ia2);
 
char *ne_iaddr_print(const ne_inet_addr *ia,
 char *buffer,
 size_t bufsiz);
 
ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia);
 
ne_inet_addr *ne_iaddr_parse(const char *address,
 ne_iaddr_type type);
 
unsigned char *ne_iaddr_raw(const ne_inet_addr *ia,
 unsigned char *buffer);
 
int ne_iaddr_reverse(const ne_inet_addr *ia,
 char *buffer,
 size_t buflen);
 
void ne_iaddr_free(const ne_inet_addr *ia);
 

Description

ne_iaddr_make creates an ne_inet_addr object from a raw binary network address; for instance the four bytes 0x7f 0x00 0x00 0x01 represent the IPv4 address 127.0.0.1. The object returned is suitable for passing to ne_sock_connect. A binary IPv4 address contains four bytes; a binary IPv6 address contains sixteen bytes; addresses passed must be in network byte order.

ne_iaddr_cmp compares two network address objects; returning zero only if they are identical. The objects need not have the same address type; if the addresses are not of the same type, the return value is guaranteed to be non-zero.

ne_iaddr_print prints a human-readable string representation of a network address into a buffer, for instance the string "127.0.0.1".

ne_iaddr_typeof returns the type of the given network address object.

ne_iaddr_parse parses a string representation of a network address (such as "127.0.0.1" and creates a network address object to represent the parsed address.

ne_iaddr_raw writes the raw byte representation of a network address to the provided buffer. The bytes are written in network byte order; the buffer must be of suitable length for the type of address (4 bytes for an IPv4 address, 16 bytes for an IPv6 address).

ne_iaddr_reverse performs a reverse name lookup on the address object, writing the (first) hostname associated with the IP address to the provided buffer. If the hostname is longer than the buffer it will be silently truncated; on success the string written to the buffer is always NUL-terminated.

ne_iaddr_free releases the memory associated with a network address object.

Return value

ne_iaddr_make returns NULL if the address type passed is not supported (for instance on a platform which does not support IPv6).

ne_iaddr_print returns the buffer pointer, and never NULL.

ne_iaddr_parse returns a network address object on success, or NULL on failure to parse the address parameter.

ne_iaddr_reverse returns zero on success or non-zero if no hostname is associated with the address.

ne_iaddr_raw returns the buffer parameter, and never NULL.

Examples

The following example connects a socket to port 80 at the address 127.0.0.1.

unsigned char addr[] = "\0x7f\0x00\0x00\0x01";
ne_inet_addr *ia;

ia = ne_iaddr_make(ne_iaddr_ipv4, addr);
if (ia != NULL) {
    ne_socket *sock = ne_sock_connect(ia, 80);
    ne_iaddr_free(ia);
    /* ... */
} else {
    /* ... */
}
davix-R_0_5_0/deps/libneon/doc/html/refneon.html000066400000000000000000000307441257152637300217110ustar00rootroot00000000000000neon

Name

neon — HTTP and WebDAV client library

Description

neon is an HTTP and WebDAV client library. The major abstractions exposed are the HTTP session, created by ne_session_create; and the HTTP request, created by ne_request_create. HTTP authentication is handled transparently for server and proxy servers, see ne_set_server_auth; complete SSL/TLS support is also included, see ne_ssl_set_verify.

Conventions

Some conventions are used throughout the neon API, to provide a consistent and simple interface; these are documented below.

Thread-safeness and global initialization

neon itself is implemented to be thread-safe (avoiding any use of global state), but relies on the operating system providing a thread-safe resolver interface. Modern operating systems offer the thread-safe getaddrinfo interface, which neon supports; some others implement gethostbyname using thread-local storage.

To allow thread-safe use of SSL in the OpenSSL and GnuTLS libraries neon must be configured using the --enable-threadsafe-ssl; if this is done, locking callbacks will be registered by ne_sock_init; note that care must be exercised if neon is used in conjunction with another library which uses OpenSSL or GnuTLS.

Some platforms and libraries used by neon require global initialization before use; notably:

  • The SIGPIPE signal disposition must be set to ignored or otherwise handled to avoid process termination when writing to a socket which has been shutdown by the peer.
  • OpenSSL and GnuTLS require global initialization to load shared lookup tables.
  • The Win32 socket library requires initialization before use.

The ne_sock_init function should be called before any other use of neon to perform any necessary initialization needed for the particular platform. Applications wishing to perform all the necessary process-global initialization steps themselves may omit to call ne_sock_init (and ne_sock_exit); neon neither checks whether these functions are called nor calls them itself.

For some applications and configurations it may be necessary to call ne_i18n_init to initialize the support for internationalization in neon.

Asynchronous signal safety

No function in neon is defined to be async-signal safe - that is, no function is safe to call from a signal handler. Any call into the neon library from a signal handler will have undefined behaviour - in other words, it may crash the process.

Functions using global state

Any function in neon may modify the errno global variable as a side-effect. Except where explicitly documented, the value of errno is unspecified after any neon function call.

Other than in the use of errno, the only functions which use or modify process-global state in neon are as follows:

Namespaces

To avoid possible collisions between names used for symbols and preprocessor macros by an application and the libraries it uses, it is good practice for each library to reserve a particular namespace prefix. An application which ensures it uses no names with these prefixes is then guaranteed to avoid such collisions.

The neon library reserves the use of the namespace prefixes ne_ and NE_. The libraries used by neon may also reserve certain namespaces; collisions between these libraries and a neon-based application will not be detected at compile time, since the underlying library interfaces are not exposed through the neon header files. Such collisions can only be detected at link time, when the linker attempts to resolve symbols. The following list documents some of the namespaces claimed by libraries used by neon; this list may be incomplete.

SSL, ssl, TLS, tls, ERR_, BIO_, d2i_, i2d_, ASN1_

Some of the many prefixes used by the OpenSSL library; little attempt has been made to keep exported symbols within any particular prefixes for this library.

gnutls_, gcry_, gpg_

Namespaces used by the GnuTLS library (and dependencies thereof)

XML_, Xml[A-Z]

Namespaces used by the expat library.

xml[A-Z], html[A-Z], docb[A-Z]

Namespaces used by the libxml2 library; a relatively small number of symbols are used without these prefixes.

inflate, deflate, crc32, compress, uncompres, adler32, zlib

Namespaces used by the zlib library; a relatively small number of symbols are used without these prefixes.

krb5, gss, GSS, asn1, decode_krb5, encode_krb5, profile, mit

Some of the prefixes used by the MIT GSSAPI library and dependencies thereof; a number of symbols lie outside these prefixes.

pakchois_

Namespace used by the pakchois library.

px_

Namespace used by the libproxy library.

Argument validation

neon does not attempt to validate that the parameters passed to functions conform to the API (for instance, checking that pointer arguments are not NULL). Any use of the neon API which is not documented to produce a certain behaviour results is said to produce undefined behaviour; it is likely that neon will segfault under these conditions.

URI paths, WebDAV metadata

The path strings passed to any function must be URI-encoded by the application; neon never performs any URI encoding or decoding internally. WebDAV property names and values must be valid UTF-8 encoded Unicode strings.

User interaction

As a pure library interface, neon will never produce output on stdout or stderr; all user interaction is the responsibilty of the application.

Memory handling

neon does not attempt to cope gracefully with an out-of-memory situation; instead, by default, the abort function is called to immediately terminate the process. An application may register a custom function which will be called before abort in such a situation; see ne_oom_callback.

Callbacks and userdata

Whenever a callback is registered, a userdata pointer is also used to allow the application to associate a context with the callback. The userdata is of type void *, allowing any pointer to be used.

Large File Support

Since version 0.27.0, neon transparently uses the "LFS transitional" interfaces in places where file-backed file descriptors are manipulated. This means files larger than 2GiB can be handled on platforms with a native 32-bit off_t type, where LFS support is available.

Some interfaces use the ne_off_t type, which is defined to be either off_t or off64_t according to whether LFS support is detected at build time. neon does not use or require the -D_FILE_OFFSET_BITS=64 macro definition.

davix-R_0_5_0/deps/libneon/doc/html/refopts.html000066400000000000000000000143721257152637300217360ustar00rootroot00000000000000ne_set_useragent

Name

ne_set_useragent, ne_set_read_timeout, ne_set_connect_timeout, ne_get_scheme, ne_get_server_hostport — common properties for HTTP sessions

Synopsis

#include <ne_session.h>
void ne_set_useragent(ne_session *session,
 const char *product);
 
void ne_set_read_timeout(ne_session *session,
 int timeout);
 
void ne_set_connect_timeout(ne_session *session,
 int timeout);
 
const char *ne_get_scheme(ne_sesssion *session);
 
const char *ne_get_server_hostport(ne_sesssion *session);
 

Description

The User-Agent request header is used to identify the software which generated the request for statistical or debugging purposes. neon does not send a User-Agent header unless a call is made to the ne_set_useragent. ne_set_useragent must be passed a product string conforming to RFC2616's product token grammar; of the form "Product/Version".

When neon reads from a socket, by default the read operation will time out after 60 seconds, and the request will fail giving an NE_TIMEOUT error. To configure this timeout interval, call ne_set_read_timeout giving the desired number of seconds as the timeout parameter.

When a connection is being established to a server, normally only the system's TCP timeout handling will apply. To configure a specific (and probably shorter) timeout, the ne_set_connect_timeout can be used, giving the desired number of seconds as the timeout parameter. If 0 is passed, then the default behaviour of using the system TCP timeout will be used.

The scheme used to initially create the session will be returned by ne_get_scheme.

The hostport pair with which the session is associated will be returned by the ne_get_server_hostport; for example www.example.com:8080. Note that the :port will be omitted if the default port for the scheme is used.

Examples

Set a user-agent string:

ne_session *sess = ne_session_create(...);
ne_set_useragent(sess, "MyApplication/2.1");

Set a 30 second read timeout:

ne_session *sess = ne_session_create(...);
ne_set_read_timeout(sess, 30);
davix-R_0_5_0/deps/libneon/doc/html/refreq.html000066400000000000000000000210451257152637300215330ustar00rootroot00000000000000ne_request_create

Name

ne_request_create, ne_request_dispatch, ne_request_destroy — low-level HTTP request handling

Synopsis

#include <ne_request.h>
ne_request *ne_request_create(ne_session *session,
 const char *method,
 const char *path);
 
int ne_request_dispatch(ne_request *req);
 
void ne_request_destroy(ne_request *req);
 

Description

An HTTP request, represented by the ne_request type, specifies that some operation is to be performed on some resource. The ne_request_create function creates a request object, specifying the operation in the method parameter. The location of the resource is determined by the server in use for the session given by the sess parameter, combined with the path parameter.

The path string used must conform to the abs_path definition given in RFC2396, with an optional "?query" part, and must be URI-escaped by the caller (for instance, using ne_path_escape). If the string comes from an untrusted source, failure to perform URI-escaping results in a security vulnerability.

To dispatch a request, and process the response, the ne_request_dispatch function can be used. An alternative is to use the (more complex, but more flexible) combination of the ne_begin_request, ne_end_request, and ne_read_response_block functions; see ne_begin_request.

To add extra headers in the request, the functions ne_add_request_header and ne_print_request_header can be used. To include a message body with the request, one of the functions ne_set_request_body_buffer, ne_set_request_body_fd, or ne_set_request_body_provider can be used.

The return value of ne_request_dispatch indicates merely whether the request was sent and the response read successfully. To discover the result of the operation, ne_get_status, along with any processing of the response headers and message body.

A request can only be dispatched once: calling ne_request_dispatch more than once on a single ne_request object produces undefined behaviour. Once all processing associated with the request object is complete, use the ne_request_destroy function to destroy the resources associated with it. Any subsequent use of the request object produces undefined behaviour.

If a request is being using a non-idempotent method such as POST, the NE_REQFLAG_IDEMPOTENT flag should be disabled; see ne_set_request_flag.

Return value

The ne_request_create function returns a pointer to a request object (and never NULL).

The ne_request_dispatch function returns zero if the request was dispatched successfully, and a non-zero error code otherwise.

Errors

NE_ERROR

Request failed (see session error string)

NE_LOOKUP

The DNS lookup for the server (or proxy server) failed.

NE_AUTH

Authentication failed on the server.

NE_PROXYAUTH

Authentication failed on the proxy server.

NE_CONNECT

A connection to the server could not be established.

NE_TIMEOUT

A timeout occurred while waiting for the server to respond.

Example

An example of applying a MKCOL operation to the resource at the location http://www.example.com/foo/bar/:

ne_session *sess = ne_session_create("http", "www.example.com", 80);
ne_request *req = ne_request_create(sess, "MKCOL", "/foo/bar/");
if (ne_request_dispatch(req)) {
   printf("Request failed: %s\n", ne_get_error(sess));
}
ne_request_destroy(req);
davix-R_0_5_0/deps/libneon/doc/html/refreqbody.html000066400000000000000000000105151257152637300224110ustar00rootroot00000000000000ne_set_request_body_buffer

Name

ne_set_request_body_buffer, ne_set_request_body_fd, ne_set_request_body_fd64 — include a message body with a request

Synopsis

#include <ne_request.h>
void ne_set_request_body_buffer(ne_request *req,
 const char *buf,
 size_t count);
 
int ne_set_request_body_fd(ne_request *req,
 int fd,
 off_t begin,
 off_t length);
 

Description

The ne_set_request_body_buffer function specifies that a message body should be included with the body, which is stored in the count bytes buffer buf.

The ne_set_request_body_fd function can be used to include a message body with a request which is read from a file descriptor. The body is read from the file descriptor fd, which must be a associated with a seekable file (not a pipe, socket, or FIFO). count bytes are read, beginning at offset begin (hence, passing begin as zero means the body is read from the beginning of the file).

For all the above functions, the source of the request body must survive until the request has been dispatched; neither the memory buffer passed to ne_set_request_body_buffer nor the file descriptor passed to ne_set_request_body_fd are copied internally.

davix-R_0_5_0/deps/libneon/doc/html/refreqflags.html000066400000000000000000000105601257152637300225500ustar00rootroot00000000000000ne_set_request_flag

Name

ne_set_request_flag, ne_get_request_flag — set and retrieve per-request flags

Synopsis

#include <ne_request.h>
void ne_set_request_flag(ne_request *req,
 ne_request_flag flag,
 int value);
 
int ne_get_request_flag(ne_request *req,
 ne_request_flag flag);
 

Description

The ne_set_request_flag function enables or disables a per-request flag. Passing a non-zero value argument enables the flag, and zero disables it.

The following flags are defined:

NE_REQFLAG_EXPECT100

enable this flag to use the "Expect: 100-continue" feature of HTTP/1.1, which allows the server to process request headers without reading the entire request body. This saves time and bandwidth if the server gives an authentication challenge (requiring the request to be resent), but has interoperability problems with some older servers.

NE_REQFLAG_IDEMPOTENT

disable this flag if the request uses a non-idempotent method such as POST

Return value

The ne_get_request_flag function returns zero if a flag is disabled, less than zero if the flag is not supported, or greater than zero if the flag is enabled.

davix-R_0_5_0/deps/libneon/doc/html/refreqhdr.html000066400000000000000000000074071257152637300222370ustar00rootroot00000000000000ne_add_request_header

Name

ne_add_request_header, ne_print_request_header — add headers to a request

Synopsis

#include <ne_request.h>
void ne_add_request_header(ne_request *request,
 const char *name,
 const char *value);
 
void ne_print_request_header(ne_request *request,
 const char *name,
 const char *format,
 ...);
 

Description

The functions ne_add_request_header and ne_print_request_header can be used to add headers to a request, before it is sent.

ne_add_request_header simply adds a header of given name, with given value.

ne_print_request_header adds a header of given name, taking the value from the printf-like format string parameter and subsequent variable-length argument list.

davix-R_0_5_0/deps/libneon/doc/html/refresolve.html000066400000000000000000000165311257152637300224270ustar00rootroot00000000000000ne_addr_resolve

Name

ne_addr_resolve, ne_addr_result, ne_addr_first, ne_addr_next, ne_addr_error, ne_addr_destroy — functions to resolve hostnames to addresses

Synopsis

#include <ne_socket.h>
ne_sock_addr *ne_addr_resolve(const char *hostname,
 int flags);
 
int ne_addr_result(const ne_sock_addr *addr);
 
const ne_inet_addr *ne_addr_first(ne_sock_addr *addr);
 
const ne_inet_addr *ne_addr_next(ne_sock_addr *addr);
 
char *ne_addr_error(const ne_sock_addr *addr,
 char *buffer,
 size_t bufsiz);
 
void ne_addr_destroy(ne_sock_addr *addr);
 

Description

The ne_addr_resolve function resolves the given hostname, returning an ne_sock_addr object representing the address (or addresses) associated with the hostname. The flags parameter is currently unused, and must be passed as 0.

The hostname passed to ne_addr_resolve can be a DNS hostname (e.g. "www.example.com") or an IPv4 dotted quad (e.g. "192.0.34.72"); or, on systems which support IPv6, an IPv6 hex address, which may be enclosed in brackets, e.g. "[::1]".

To determine whether the hostname was successfully resolved, the ne_addr_result function is used, which returns non-zero if an error occurred. If an error did occur, the ne_addr_error function can be used, which will copy the error string into a given buffer (of size bufsiz).

The functions ne_addr_first and ne_addr_next are used to retrieve the Internet addresses associated with an address object which has been successfully resolved. ne_addr_first returns the first address; ne_addr_next returns the next address after the most recent call to ne_addr_next or ne_addr_first, or NULL if there are no more addresses. The ne_inet_addr pointer returned by these functions can be passed to ne_sock_connect to connect a socket.

After the address object has been used, it should be destroyed using ne_addr_destroy.

Return value

ne_addr_resolve returns a pointer to an address object, and never NULL. ne_addr_error returns the buffer parameter .

Examples

The code below prints out the set of addresses associated with the hostname www.google.com.

ne_sock_addr *addr;
char buf[256];

addr = ne_addr_resolve("www.google.com", 0);
if (ne_addr_result(addr)) {
    printf("Could not resolve www.google.com: %s\n",
           ne_addr_error(addr, buf, sizeof buf));
} else {
    const ne_inet_addr *ia;
    printf("www.google.com:");
    for (ia = ne_addr_first(addr); ia != NULL; ia = ne_addr_next(addr)) {
        printf(" %s", ne_iaddr_print(ia, buf, sizeof buf));
    }
    putchar('\n');
}
ne_addr_destroy(addr);
davix-R_0_5_0/deps/libneon/doc/html/refresphdr.html000066400000000000000000000123061257152637300224130ustar00rootroot00000000000000ne_get_response_header

Name

ne_get_response_header, ne_response_header_iterate — functions to access response headers

Synopsis

#include <ne_request.h>
const char *ne_get_response_header(ne_request *request,
 const char *name);
 
void *ne_response_header_iterate(ne_request *request,
 void *cursor,
 const char **name,
 const char **value);
 

Description

To retrieve the value of a response header field, the ne_get_response_header function can be used, and is given the name of the header to return.

To iterate over all the response headers returned, the ne_response_header_iterate function can be used. This function takes a cursor parameter which should be NULL to retrieve the first header. The function stores the name and value of the next header header in the name and value parameters, and returns a new cursor pointer which can be passed to ne_response_header_iterate to retrieve the next header.

Return value

ne_get_response_header returns a string, or NULL if no header with that name was given. If used during request processing, the return value pointer is valid only until the next call to ne_begin_request, or else, until the request object is destroyed.

Likewise, the cursor, names, and values returned by ne_response_header_iterate are only valid until the next call to ne_begin_request or until the request object is destroyed.

Examples

The following code will output the value of the Last-Modified header for a resource:

ne_request *req = ne_request_create(sess, "GET", "/foo.txt");
if (ne_request_dispatch(req) == NE_OK) {
    const char *mtime = ne_get_response_header(req, "Last-Modified");
    if (mtime) {
        printf("/foo.txt has last-modified value %s\n", mtime);
    }
}
ne_request_destroy(req);
davix-R_0_5_0/deps/libneon/doc/html/refsess.html000066400000000000000000000161661257152637300217310ustar00rootroot00000000000000ne_session_create

Name

ne_session_create, ne_close_connection, ne_session_proxy, ne_session_destroy — set up HTTP sessions

Synopsis

#include <ne_session.h>
ne_session *ne_session_create(const char *scheme,
 const char *hostname,
 unsigned int port);
 
void ne_session_proxy(ne_session *session,
 const char *hostname,
 unsigned int port);
 
void ne_close_connection(ne_session *session);
 
void ne_session_destroy(ne_session *session);
 

Description

An ne_session object represents an HTTP session - a logical grouping of a sequence of HTTP requests made to a certain server. Any requests made using the session can use a persistent connection, share cached authentication credentials and any other common attributes.

A new HTTP session is created using ne_session_create, giving the hostname and port of the server to use, along with the scheme used to contact the server (usually "http"). Before the first use of ne_session_create in a process, ne_sock_init must have been called to perform any global initialization needed by any libraries used by neon.

To enable SSL/TLS for the session, pass the string "https" as the scheme parameter, and either register a certificate verification function (see ne_ssl_set_verify) or trust the appropriate certificate (see ne_ssl_trust_cert, ne_ssl_trust_default_ca).

If an HTTP proxy server should be used for the session, ne_session_proxy must be called giving the hostname and port on which to contact the proxy.

Further per-session options may be changed using the ne_set_request_flag interface.

If it is known that the session will not be used for a significant period of time, ne_close_connection can be called to close the connection, if one remains open. Use of this function is entirely optional, but it must not be called if there is a request active using the session.

Once a session has been completed, ne_session_destroy must be called to destroy the resources associated with the session. Any subsequent use of the session pointer produces undefined behaviour.

Notes

The hostname passed to ne_session_create is resolved when the first request using the session is dispatched; a DNS resolution failure can only be detected at that time (using the NE_LOOKUP error code); see ne_request_dispatch for details.

Return Values

ne_session_create will return a pointer to a new session object (and never NULL).

Examples

Create and destroy a session:

ne_session *sess;
sess = ne_session_create("http", "host.example.com", 80);
/* ... use sess ... */
ne_session_destroy(sess);
davix-R_0_5_0/deps/libneon/doc/html/refsessflags.html000066400000000000000000000122201257152637300227310ustar00rootroot00000000000000ne_set_session_flag

Name

ne_set_session_flag, ne_get_session_flag — set and retrieve session flags

Synopsis

#include <ne_request.h>
void ne_set_session_flag(ne_session *sess,
 ne_session_flag flag,
 int value);
 
int ne_get_session_flag(ne_session *sess,
 ne_session_flag flag);
 

Description

The ne_set_session_flag function enables or disables a session flag. Passing a non-zero value argument enables the flag, and zero disables it.

The following flags are defined:

NE_SESSFLAG_PERSIST

disable this flag to prevent use of persistent connections

NE_SESSFLAG_ICYPROTO

enable this flag to enable support for non-HTTP ShoutCast-style "ICY" responses

NE_SESSFLAG_SSLv2

disable this flag to disable support for the SSLv2 protocol

NE_SESSFLAG_RFC4918

enable this flag to enable support for RFC4918-only WebDAV features; losing backwards-compatibility with RFC2518 servers

NE_SESSFLAG_CONNAUTH

enable this flag if an RFC-violating connection-based HTTP authentication scheme is in use

NE_SESSFLAG_TLS_SNI

disable this flag if a server is used which does not correctly support the TLS SNI extension

NE_SESSFLAG_EXPECT100

enable this flag to enable the request flag NE_REQFLAG_EXPECT100 for new requests

Return value

The ne_get_session_flag function returns zero if a flag is disabled, less than zero if the flag is not supported, or greater than zero if the flag is enabled.

davix-R_0_5_0/deps/libneon/doc/html/refshave.html000066400000000000000000000055671257152637300220650ustar00rootroot00000000000000ne_shave

Name

ne_shave — trim whitespace from a string

Synopsis

#include <ne_string.h>
char *ne_shave(char *str,
 const char *whitespace);
 

Description

ne_shave returns a portion of str with any leading or trailing characters in the whitespace array removed. str may be modified. Note that the return value may not be equal to str.

Examples

The following code segment will output "fish":

char s[] = ".!.fish!.!";
puts(ne_shave(s, ".!"));
davix-R_0_5_0/deps/libneon/doc/html/refsockinit.html000066400000000000000000000152311257152637300225670ustar00rootroot00000000000000ne_sock_init

Name

ne_sock_init, ne_sock_exit — perform library initialization

Synopsis

#include <ne_socket.h>
int ne_sock_init(void); 
 
void ne_sock_exit(void); 
 

Description

In some platforms and configurations, neon may be using some socket or SSL libraries which require global initialization before use. To perform this initialization, the ne_sock_init function must be called before any other library functions are used.

Once all use of neon is complete, ne_sock_exit can be called to perform de-initialization of socket or SSL libraries, if necessary. Uses of ne_sock_init and ne_sock_exit are "reference counted"; if N calls to ne_sock_init are made, only the Nth call to ne_sock_exit will have effect.

ne_sock_init will set the disposition of the SIGPIPE signal to ignored. No change is made to the SIGPIPE disposition by ne_sock_exit.

Both the SSL libraries supported by neon — OpenSSL and GnuTLS — require callbacks to be registered to allow thread-safe use of SSL. These callbacks are stored as global variables and so their state persists for as long as the library in question is loaded into the process. If multiple users of the SSL library exist within the process, this can be problematic, particularly if one is dynamically loaded (and may subsequently be unloaded).

If neon is configured using the --enable-threadsafe-ssl flag, thread-safe SSL support will be enabled automatically, as covered in the following section. Otherwise, it is not safe to use neon with SSL in a multi-threaded process. The ne_has_support function can be used to determine whether neon is built to enable thread-safety support in the SSL library.

Thread-safe SSL with OpenSSL

neon follows two simple rules when dealing with the OpenSSL locking callbacks:

  • ne_sock_init will set thread-safety locking callbacks if and only if no locking callbacks are already registered.
  • ne_sock_exit will unset the thread-safety locking callbacks if and only if the locking callbacks registered are those registered by ne_sock_init.

Applications and libraries should be able to co-operate to ensure that SSL use is always thread-safe if similar rules are always followed.

Thread-safe SSL with GnuTLS

The cryptography library used by GnuTLS, libgcrypt, only supports an initialization operation to register thread-safety callbacks. ne_sock_init will register the thread-safe locking callbacks on first use; ne_sock_exit cannot unregister them. If multiple users of GnuTLS are present within the process, it is unsafe to dynamically unload neon from the process if neon is configured with thread-safe SSL support enabled (since the callbacks would be left pointing at unmapped memory once neon is unloaded).

Return value

ne_sock_init returns zero on success, or non-zero on error. If an error occurs, no further use of the neon library should be attempted.

davix-R_0_5_0/deps/libneon/doc/html/refsslca.html000066400000000000000000000077021257152637300220550ustar00rootroot00000000000000ne_ssl_trust_cert

Name

ne_ssl_trust_cert, ne_ssl_trust_default_ca — functions to indicate that certificates are trusted

Synopsis

#include <ne_session.h>
void ne_ssl_trust_cert(ne_session *session,
 const ne_ssl_certificate *cert);
 
void ne_ssl_trust_default_ca(ne_session *session);
 

Description

To indicate that a given certificate is trusted by the user, the certificate object can be passed to ne_ssl_trust_cert. The certificate object is duplicated internally and can subsequently be destroyed.

The SSL library in use by neon may include a default set of CA certificates; calling the ne_ssl_trust_default_ca function will indicate that these CAs are trusted by the user.

Examples

Load the CA certificate stored in /path/to/cacert.pem:

ne_session *sess = ne_session_create(...);
ne_ssl_certificate *cert = ne_ssl_cert_read("/path/to/cacert.pem");

if (cert) {
   ne_ssl_trust_cert(sess, cert);
   ne_ssl_cert_free(cert);
} else {
   printf("Could not load CA cert: %s\n", ne_get_error(sess));
}
davix-R_0_5_0/deps/libneon/doc/html/refsslcert2.html000066400000000000000000000060601257152637300225050ustar00rootroot00000000000000ne_ssl_cert_cmp

Name

ne_ssl_cert_cmp, ne_ssl_cert_free — functions to operate on certificate objects

Synopsis

#include <ne_header.h>
int ne_ssl_cert_cmp(const ne_ssl_certificate *c1,
 const ne_ssl_certificate *c2);
 
void ne_ssl_cert_free(ne_ssl_certificate *cert);
 

Description

The ne_ssl_cert_cmp function can be used to compare two certificate objects; it returns zero if they refer to the same certificate, and non-zero otherwise.

The ne_ssl_cert_free function can be used to destroy a certificate object when it is no longer needed.

davix-R_0_5_0/deps/libneon/doc/html/refsslcertio.html000066400000000000000000000130341257152637300227520ustar00rootroot00000000000000ne_ssl_cert_read

Name

ne_ssl_cert_read, ne_ssl_cert_write, ne_ssl_cert_import, ne_ssl_cert_export — functions to read or write certificates to and from files or strings

Synopsis

#include <ne_ssl.h>
ne_ssl_certificate *ne_ssl_cert_read(const char *filename);
 
int ne_ssl_cert_write(const ne_ssl_certificate *cert,
 const char *filename);
 
ne_ssl_certificate *ne_ssl_cert_import(const char *data);
 
char *ne_ssl_cert_export(const ne_ssl_certificate *cert);
 

Description

The ne_ssl_cert_write function writes a certificate to a file using the PEM encoding. The ne_ssl_cert_export function returns a base64-encoded NUL-terminated string representing the certificate. This string is malloc-allocated and should be destroyed using free by the caller.

The ne_ssl_cert_read function reads a certificate from a PEM-encoded file, and returns a certificate object. The ne_ssl_cert_import function returns a certificate object from a base64-encoded string, data, as returned by ne_ssl_cert_export. The certificate object returned by these functions should be destroyed using ne_ssl_cert_free after use.

Return value

ne_ssl_cert_read returns NULL if a certificate could not be read from the file. ne_ssl_cert_write returns non-zero if the certificate could not be written to the file. ne_ssl_cert_export always returns a NUL-terminated string, and never NULL. ne_ssl_cert_import returns NULL if the string was not a valid base64-encoded certificate.

Encoding Formats

The string produced by ne_ssl_cert_export is the base64 encoding of the DER representation of the certificate. The file written by ne_ssl_cert_write uses the PEM format: this is the base64 encoding of the DER representation with newlines every 64 characters, and start and end marker lines.

davix-R_0_5_0/deps/libneon/doc/html/refssldname.html000066400000000000000000000075231257152637300225570ustar00rootroot00000000000000ne_ssl_dname

Name

ne_ssl_readable_dname, ne_ssl_dname_cmp — SSL distinguished name handling

Synopsis

#include <ne_ssl.h>
const char *ne_ssl_readable_dname(const ne_ssl_dname *dname);
 
int ne_ssl_dname_cmp(const ne_ssl_dname *dn1,
 const ne_ssl_dname *dn2);
 

Description

The ne_ssl_readable_dname function creates a single-line, human-readable string out of an ne_ssl_dname object. The returned string is malloc()-allocated, and must be free()d by the caller.

The ne_ssl_dname_cmp function compares two distinguished names, and returns zero if they are equal, or non-zero otherwise.

Return value

ne_ssl_readable_dname returns a malloc-allocated string, and never NULL.

Examples

See ne_ssl_cert_subject for an example use of ne_ssl_readable_dname.

davix-R_0_5_0/deps/libneon/doc/html/refsslvfy.html000066400000000000000000000161711257152637300222760ustar00rootroot00000000000000ne_ssl_set_verify

Name

ne_ssl_set_verify — register an SSL certificate verification callback

Synopsis

#include <ne_session.h>
typedef int ne_ssl_verify_fn(void *userdata,
 int failures,
 const ne_ssl_certificate *cert);
 
void ne_ssl_set_verify(ne_session *session,
 ne_ssl_verify_fn verify_fn,
 void *userdata);
 

Description

To enable manual SSL certificate verification, a callback can be registered using ne_ssl_set_verify. If such a callback is not registered, when a connection is established to an SSL server which does not present a certificate signed by a trusted CA (see ne_ssl_trust_cert), or if the certificate presented is invalid in some way, the connection will fail.

When the callback is invoked, the failures parameter gives a bitmask indicating in what way the automatic certificate verification failed. The value is equal to the bit-wise OR of one or more of the following constants (and is guaranteed to be non-zero):

NE_SSL_NOTYETVALID

The certificate is not yet valid.

NE_SSL_EXPIRED

The certificate has expired.

NE_SSL_IDMISMATCH

The hostname used for the session does not match the hostname to which the certificate was issued.

NE_SSL_UNTRUSTED

The Certificate Authority which signed the certificate is not trusted.

Note that if either of the NE_SSL_IDMISMATCH or NE_SSL_UNTRUSTED failures is given, the connection may have been intercepted by a third party, and must not be presumed to be secure.

The cert parameter passed to the callback represents the certificate which was presented by the server. If the server presented a chain of certificates, the chain can be accessed using ne_ssl_cert_signedby. The cert object given is not valid after the callback returns.

Return value

The verification callback must return zero to indicate that the certificate should be trusted; and non-zero otherwise (in which case, the connection will fail).

Examples

The following code implements an example verification callback, using the dump_cert function from ne_ssl_cert_subject to display certification information. Notice that the hostname of the server used for the session is passed as the userdata parameter to the callback.

static int
my_verify(void *userdata, int failures, const ne_ssl_certificate *cert)
{
  const char *hostname = userdata;

  dump_cert(cert);

  puts("Certificate verification failed - the connection may have been "
       "intercepted by a third party!");

  if (failures & NE_SSL_IDMISMATCH) { 
    const char *id = ne_ssl_cert_identity(cert);
    if (id) 
      printf("Server certificate was issued to '%s' not '%s'.\n",
             id, hostname);
    else
      printf("The certificate was not issued for '%s'\n", hostname);
  }

  if (failures & NE_SSL_UNTRUSTED)
    puts("The certificate is not signed by a trusted Certificate Authority.");

  /* ... check for validity failures ... */

  if (prompt_user())
    return 1; /* fail verification */
  else
    return 0; /* trust the certificate anyway */
}

int
main(...)
{
  ne_session *sess = ne_session_create("https", "some.host.name", 443);
  ne_ssl_set_verify(sess, my_verify, "some.host.name");
  ...
}
davix-R_0_5_0/deps/libneon/doc/html/refstatus.html000066400000000000000000000101251257152637300222640ustar00rootroot00000000000000ne_status

Name

ne_status — HTTP status structure

Synopsis

#include <ne_utils.h>

typedef struct {
    int major_version, minor_version;
    int code, klass;
    const char *reason_phrase;
} ne_status;

Description

An ne_status type represents an HTTP response status; used in response messages giving a result of request. The major_version and minor_version fields give the HTTP version supported by the server issuing the response. The code field gives the status code of the result (lying between 100 and 999 inclusive), and the klass field gives the class[2], which is equal to the most significant digit of the status.

There are five classes of HTTP status code defined by RFC2616:

1xx

Informational response.

2xx

Success: the operation was successful

3xx

Redirection

4xx

Client error: the request made was incorrect in some manner.

5xx

Server error

See also

ne_get_status.



[2] the field is named klass not class so that the header can be used from a C++ program, in which class is a reserved word)

davix-R_0_5_0/deps/libneon/doc/html/reftok.html000066400000000000000000000077521257152637300215520ustar00rootroot00000000000000ne_token

Name

ne_token, ne_qtoken — string tokenizers

Synopsis

#include <ne_string.h>
char *ne_token(char **str,
 char sep);
 
char *ne_qtoken(char **str,
 char sep,
 const char *quotes);
 

Description

ne_token and ne_qtoken tokenize the string at the location stored in the pointer str. Each time the function is called, it returns the next token, and modifies the str pointer to point to the remainer of the string, or NULL if there are no more tokens in the string. A token is delimited by the separator character sep; if ne_qtoken is used any quoted segments of the string are skipped when searching for a separator. A quoted segment is enclosed in a pair of one of the characters given in the quotes string.

The string being tokenized is modified each time the tokenizing function is called; replacing the next separator character with a NUL terminator.

Examples

The following function prints out each token in a comma-separated string list, which is modified in-place:

static void splitter(char *list)
{
  do {
    printf("Token: %s\n", ne_token(&list, ','));
  while (list);
}
davix-R_0_5_0/deps/libneon/doc/html/refvers.html000066400000000000000000000065421257152637300217300ustar00rootroot00000000000000ne_version_match

Name

ne_version_match, ne_version_string — library versioning

Synopsis

#include <ne_utils.h>
int ne_version_match(int major,
 int minor);
 
const char *ne_version_string(void); 
 

Description

The ne_version_match function returns non-zero if the library version is not of major version major, or the minor version is less than minor. For neon versions 0.x, every minor version is assumed to be incompatible with every other minor version.

The ne_version_string function returns a string giving the library version.

Examples

To require neon 1.x, version 1.2 or later:

if (ne_version_match(1, 2)) {
    printf("Library version out of date: 1.2 required, found %s.",
           ne_version_string());
    exit(1);
}
davix-R_0_5_0/deps/libneon/doc/html/refxml.html000066400000000000000000000060221257152637300215420ustar00rootroot00000000000000ne_xml_create

Name

ne_xml_create, ne_xml_destroy — create and destroy an XML parser

Synopsis

#include <ne_xml.h>
ne_xml_parser *ne_xml_create(void); 
 
void ne_xml_destroy(ne_xml_parser *parser);
 

Description

The ne_xml_create function creates an XML parser object, which can be used for parsing XML documents using stacked SAX handlers.

Return value

ne_xml_create returns a pointer to an XML parser object, and never NULL

See also

XXX

davix-R_0_5_0/deps/libneon/doc/html/security.html000066400000000000000000000157011257152637300221200ustar00rootroot00000000000000HTTP Client Security

HTTP Client Security

neon is intended to be secure against a specific threat model: use of a malicious HTTP server. Under this threat model, a range of attacks are possible against a client when the user (or application) can be tricked into accessing an HTTP server which is controlled by an attacker. This section documents various types of possible attack and describes what mitigation is used in neon.

CPU or memory consumption attacks

neon uses fixed resource limits to prevent the following attacks:

  • memory/CPU consumption attack using an unbounded number of response header fields

  • memory consumption attack using an unbounded length of individual response header lines (or continuation headers)

  • memory consumption attack against the PROPFIND code using an unbounded number of properties (propstat elements) per resource

  • memory consumption attack against the PROPFIND code using an unbounded CDATA element in a "flat property" value

Memory consumption attacks against applications based on neon by use of unbounded response length are also possible, but must be mitigated at application level. Memory consumption in neon itself is fixed and is not proportional to the response size.

Test cases for all the above attacks are present in the neon test suite.

SSL/TLS connection security

When using a connection secured by SSL/TLS, it is necessary for clients to verify that the X.509 certificate presented by the server matches the server's expected identity. The algorithm required for this purpose is described in RFC 2818 and RFC 3280, and is implemented by neon in the following manner:

  • the hostname argument passed to ne_session_create is the expected identity of the server

  • the subjectAltName extension of the certificate is used for comparision against the expected identity, in preference to the Subject name's commonName attribute.

  • the dNSName, iPAddress, and uniformResourceIdentifier classes of GeneralName are supported in subjectAltName comparison.

  • if no subjectAltName is present in the certificate, the most specific commonName attribute in the Subject name is used for comparison instead.

In the case where a server certificate is presented that does not match the expected identity (or is otherwise not trusted), neon will fail the request by default. This behaviour can be overridden by the use of a callback installed using ne_ssl_set_verify, which allows the application to present the certificate details to a user for manual/off-line verification, if possible.

Test cases for the correctness of the implementation of the identity verification algorithm are present in the neon test suite.

Control character insertion in error messages

Where error messages (as returned by (ne_get_error) contain data supplied by the server, the untrusted data is sanitised to remove both control characters and non-ASCII characters. This prevents any attacks where such error messages are exposed to the user and can potentially distort the presentation of the interface (for example, through the use of a carriage return character in a text user interface).

Attacks against authentication credentials

Authentication credentials can be compromised by a "downgrade attack" by an active attacker; for example, where a MITM presents a Basic authentication challenge in place of the server's Digest challenge. neon mitigates these attacks by allowing the application (and hence, user) to specify that only a specific set of authentication protocols is permitted.

neon supports the Digest and Negotiate authentication schemes, which both allow authentication of users without passing credentials in cleartext over the wire. The "domain" parameter is supported in Digest, allowing the server to restrict an authentication session to a particular set of URIs.

davix-R_0_5_0/deps/libneon/doc/html/using.html000066400000000000000000000114161257152637300213750ustar00rootroot00000000000000How to use neon from your application

How to use neon from your application

This section describes how to add neon support to an application. If you just want to quickly try out neon, use the neon-config script.

The neon source code is designed to be easily embedded into an application source tree. neon has no dependencies on libraries other than an SSL toolkit and XML parser, though the source tree can be configured to have no support for SSL or XML if desired. To configure the neon source code some GNU autoconf macros are supplied, which can be used in a number of ways, as follows:

  • autoconf macros are distributed in the 'macros' subdirectory of the neon distribution. Use the NEON_LIBRARY macro from your configure.in to check for the presence of the neon library installed on the system. The macro adds an '--with-neon=...' argument to configure, which allows the user to specify a location for the library (the standard /usr and /usr/local directories are checked automatically without having to be specified).

  • The 'src' directory of the neon package can be imported directly into your application, if you do not wish to add an external dependency. If you wish to bundle, use the NEON_BUNDLED macro to configure neon in your application: here, the neon sources are bundled in a directory called 'libneon':

    NEON_BUNDLED(libneon, ...)

    If your application supports builds where srcdir != builddir, you should use the NEON_VPATH_BUNDLED macro like this:

    NEON_VPATH_BUNDLED(${srcdir}/libneon, libneon, ...)

    If you use this macro, a '--with-included-neon' option will be added to the generated configure script. This allows the user to force the bundled neon to be used in the application, rather than any neon library found on the system. If you allow neon to be configured this way, you must also configure an XML parser. Use the NEON_XML_PARSER macro to do this.

  • The final argument to the _BUNDLED macros is a set of actions which are executed if the bundled build *is* chosen (rather than an external neon which might have been found on the user's system). In here, use either the NEON_LIBTOOL_BUILD or NEON_NORMAL_BUILD macro to set up the neon Makefile appropriately: including adding the neon source directory to the recursive make.

A full fragment might be:

NEON_BUNDLED(libneon, [
  NEON_NORMAL_BUILD
  NEON_XML_PARSER
  SUBDIRS="libneon $SUBDIRS"
])

This means the bundled neon source directory (called 'libneon') is used if no neon is found on the system, and the standard XML parser search is used.

davix-R_0_5_0/deps/libneon/doc/html/xml.html000066400000000000000000000261511257152637300210520ustar00rootroot00000000000000Parsing XML

Parsing XML

The neon XML interface is exposed by the ne_xml.h header file. This interface gives a wrapper around the standard SAX API used by XML parsers, with an additional abstraction, stacked SAX handlers, and also giving consistent XML Namespace support.

Introduction to SAX

A SAX-based parser works by emitting a sequence of events to reflect the tokens being parsed from the XML document. For example, parsing the following document fragment:

<hello>world</hello>

results in the following events:

  1. start-element "hello"
  2. character-data "world"
  3. end-element "hello"

This example demonstrates the three event types used used in the subset of SAX exposed by the neon XML interface: start-element, character-data and end-element. In a C API, an event is implemented as a function callback; three callback types are used in neon, one for each type of event.

Stacked SAX handlers

WebDAV property values are represented as fragments of XML, transmitted as parts of larger XML documents over HTTP (notably in the body of the response to a PROPFIND request). When neon parses such documents, the SAX events generated for these property value fragments may need to be handled by the application, since neon has no knowledge of the structure of properties used by the application.

To solve this problem[1] the neon XML interface introduces the concept of a SAX handler. A SAX handler comprises a start-element, character-data and end-element callback; the start-element callback being defined such that each handler may accept or decline the start-element event. Handlers are composed into a handler stack before parsing a document. When a new start-element event is generated by the XML parser, neon invokes each start-element callback in the handler stack in turn until one accepts the event. The handler which accepts the event will then be subsequently be passed character-data events if the element contains character data, followed by an end-element event when the element is closed. If no handler in the stack accepts a start-element event, the branch of the tree is ignored.

To illustrate, given a handler A, which accepts the cat and age elements, and a handler B, which accepts the name element, the following document:

Example 2.1. An example XML document

<cat>
  <age>3</age>    
  <name>Bob</name>
</cat>


would be parsed as follows:

  1. A start-element "cat" → accept
  2. A start-element "age" → accept
  3. A character-data "3"
  4. A end-element "age"
  5. A start-element "name" → decline
  6. B start-element "name" → accept
  7. B character-data "Bob"
  8. B end-element "name"
  9. A end-element "cat"

The search for a handler which will accept a start-element event begins at the handler of the parent element and continues toward the top of the stack. For the root element, it begins at the base of the stack. In the above example, handler A is at the base, and handler B at the top; if the name element had any children, only B's start-element would be invoked to accept them.

Maintaining state

To facilitate communication between independent handlers, a state integer is associated with each element being parsed. This integer is returned by start-element callback and is passed to the subsequent character-data and end-element callbacks associated with the element. The state integer of the parent element is also passed to each start-element callback, the value zero used for the root element (which by definition has no parent).

To further extend Example 2.1, “An example XML document”: if handler A defines that the state of the root element cat will be 42, the event trace would be as follows:

  1. A start-element (parent = 0, "cat") → accept, state = 42
  2. A start-element (parent = 42, "age") → accept, state = 50
  3. A character-data (state = 50, "3")
  4. A end-element (state = 50, "age")
  5. A start-element (parent = 42, "name") → decline
  6. B start-element (parent = 42, "name") → accept, state = 99
  7. B character-data (state = 99, "Bob")
  8. B end-element (state = 99, "name")
  9. A end-element (state = 42, "cat")

To avoid collisions between state integers used by different handlers, the interface definition of any handler includes the range of integers it will use.

XML namespaces

To support XML namespaces, every element name is represented as a (namespace, name) pair. The start-element and end-element callbacks are passed namespace and name strings accordingly. If an element in the XML document has no declared namespace, the namespace given will be the empty string, "".



[1] This problem only needs solving because the SAX interface is so inflexible when implemented as C function callbacks; a better approach would be to use an XML parser interface which is not based on callbacks.

davix-R_0_5_0/deps/libneon/doc/man.xsl000066400000000000000000000015721257152637300177230ustar00rootroot00000000000000 davix-R_0_5_0/deps/libneon/doc/man/000077500000000000000000000000001257152637300171665ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/doc/man/ne_add_request_header.3000066400000000000000000000043521257152637300235500ustar00rootroot00000000000000'\" t .\" Title: ne_add_request_header .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_ADD_REQUEST_HEADE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_add_request_header, ne_print_request_header \- add headers to a request .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_add_request_header('u .BI "void ne_add_request_header(ne_request\ *" "request" ", const\ char\ *" "name" ", const\ char\ *" "value" ");" .HP \w'void\ ne_print_request_header('u .BI "void ne_print_request_header(ne_request\ *" "request" ", const\ char\ *" "name" ", const\ char\ *" "format" ", \&.\&.\&.);" .SH "DESCRIPTION" .PP The functions \fBne_add_request_header\fR and \fBne_print_request_header\fR can be used to add headers to a request, before it is sent\&. .PP \fBne_add_request_header\fR simply adds a header of given \fIname\fR, with given \fIvalue\fR\&. .PP \fBne_print_request_header\fR adds a header of given \fIname\fR, taking the value from the \fBprintf\fR\-like \fIformat\fR string parameter and subsequent variable\-length argument list\&. .SH "SEE ALSO" .PP ne_request_create .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_addr_destroy.3000066400000000000000000000000261257152637300224150ustar00rootroot00000000000000.so ne_addr_resolve.3 davix-R_0_5_0/deps/libneon/doc/man/ne_addr_error.3000066400000000000000000000000261257152637300220550ustar00rootroot00000000000000.so ne_addr_resolve.3 davix-R_0_5_0/deps/libneon/doc/man/ne_addr_first.3000066400000000000000000000000261257152637300220530ustar00rootroot00000000000000.so ne_addr_resolve.3 davix-R_0_5_0/deps/libneon/doc/man/ne_addr_next.3000066400000000000000000000000261257152637300217020ustar00rootroot00000000000000.so ne_addr_resolve.3 davix-R_0_5_0/deps/libneon/doc/man/ne_addr_resolve.3000066400000000000000000000106271257152637300224130ustar00rootroot00000000000000'\" t .\" Title: ne_addr_resolve .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_ADDR_RESOLVE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_addr_resolve, ne_addr_result, ne_addr_first, ne_addr_next, ne_addr_error, ne_addr_destroy \- functions to resolve hostnames to addresses .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_sock_addr\ *ne_addr_resolve('u .BI "ne_sock_addr *ne_addr_resolve(const\ char\ *" "hostname" ", int\ " "flags" ");" .HP \w'int\ ne_addr_result('u .BI "int ne_addr_result(const\ ne_sock_addr\ *" "addr" ");" .HP \w'const\ ne_inet_addr\ *ne_addr_first('u .BI "const ne_inet_addr *ne_addr_first(ne_sock_addr\ *" "addr" ");" .HP \w'const\ ne_inet_addr\ *ne_addr_next('u .BI "const ne_inet_addr *ne_addr_next(ne_sock_addr\ *" "addr" ");" .HP \w'char\ *ne_addr_error('u .BI "char *ne_addr_error(const\ ne_sock_addr\ *" "addr" ", char\ *" "buffer" ", size_t\ " "bufsiz" ");" .HP \w'void\ ne_addr_destroy('u .BI "void ne_addr_destroy(ne_sock_addr\ *" "addr" ");" .SH "DESCRIPTION" .PP The \fBne_addr_resolve\fR function resolves the given \fIhostname\fR, returning an \fBne_sock_addr\fR object representing the address (or addresses) associated with the hostname\&. The \fIflags\fR parameter is currently unused, and must be passed as 0\&. .PP The \fIhostname\fR passed to \fBne_addr_resolve\fR can be a DNS hostname (e\&.g\&. "www\&.example\&.com") or an IPv4 dotted quad (e\&.g\&. "192\&.0\&.34\&.72"); or, on systems which support IPv6, an IPv6 hex address, which may be enclosed in brackets, e\&.g\&. "[::1]"\&. .PP To determine whether the hostname was successfully resolved, the \fBne_addr_result\fR function is used, which returns non\-zero if an error occurred\&. If an error did occur, the \fBne_addr_error\fR function can be used, which will copy the error string into a given \fIbuffer\fR (of size \fIbufsiz\fR)\&. .PP The functions \fBne_addr_first\fR and \fBne_addr_next\fR are used to retrieve the Internet addresses associated with an address object which has been successfully resolved\&. \fBne_addr_first\fR returns the first address; \fBne_addr_next\fR returns the next address after the most recent call to \fBne_addr_next\fR or \fBne_addr_first\fR, or NULL if there are no more addresses\&. The \fBne_inet_addr\fR pointer returned by these functions can be passed to \fBne_sock_connect\fR to connect a socket\&. .PP After the address object has been used, it should be destroyed using \fBne_addr_destroy\fR\&. .SH "RETURN VALUE" .PP \fBne_addr_resolve\fR returns a pointer to an address object, and never NULL\&. \fBne_addr_error\fR returns the \fIbuffer\fR parameter \&. .SH "EXAMPLES" .PP The code below prints out the set of addresses associated with the hostname www\&.google\&.com\&. .sp .if n \{\ .RS 4 .\} .nf ne_sock_addr *addr; char buf[256]; addr = ne_addr_resolve("www\&.google\&.com", 0); if (ne_addr_result(addr)) { printf("Could not resolve www\&.google\&.com: %s\en", ne_addr_error(addr, buf, sizeof buf)); } else { const ne_inet_addr *ia; printf("www\&.google\&.com:"); for (ia = ne_addr_first(addr); ia != NULL; ia = ne_addr_next(addr)) { printf(" %s", ne_iaddr_print(ia, buf, sizeof buf)); } putchar(\*(Aq\en\*(Aq); } ne_addr_destroy(addr); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_iaddr_print .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_addr_result.3000066400000000000000000000000261257152637300222420ustar00rootroot00000000000000.so ne_addr_resolve.3 davix-R_0_5_0/deps/libneon/doc/man/ne_buffer.3000066400000000000000000000044731257152637300212150ustar00rootroot00000000000000'\" t .\" Title: ne_buffer .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_BUFFER" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_buffer \- string buffer handling .SH "SYNOPSIS" .sp .ft B .nf #include typedef struct { char *data; size_t used; size_t length; } ne_buffer; .fi .ft .SH "DESCRIPTION" .PP The \fBne_buffer\fR type represents an expandable memory buffer for holding NUL\-terminated strings\&. The \fIdata\fR field points to the beginnning of the string, the length of which is given by the \fIused\fR field\&. The current size of memory allocated is given by the \fIlength\fR field\&. It is not recommended that the fields of a buffer are manipulated directly\&. The \fIdata\fR pointer may change when the buffer is modified\&. .PP A buffer is created using ne_buffer_create or ne_buffer_ncreate, and destroyed using ne_buffer_destroy or ne_buffer_finish\&. The functions ne_buffer_append, ne_buffer_zappend and ne_buffer_concat are used to append data to a buffer\&. .PP If the string referenced by the \fIdata\fR pointer is modified directly (rather than using one of the functions listed above), \fBne_buffer_altered\fR must be called\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_altered.3000066400000000000000000000000261257152637300227030ustar00rootroot00000000000000.so ne_buffer_clear.3 davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_append.3000066400000000000000000000057301257152637300225410ustar00rootroot00000000000000'\" t .\" Title: ne_buffer_append .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_BUFFER_APPEND" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_buffer_append, ne_buffer_zappend, ne_buffer_concat \- append data to a string buffer .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_buffer_append('u .BI "void ne_buffer_append(ne_buffer\ *" "buf" ", const\ char\ *" "string" ", size_t\ " "len" ");" .HP \w'void\ ne_buffer_zappend('u .BI "void ne_buffer_zappend(ne_buffer\ *" "buf" ", const\ char\ *" "string" ");" .HP \w'void\ ne_buffer_concat('u .BI "void ne_buffer_concat(ne_buffer\ *" "buf" ", const\ char\ *" "str" ", \&.\&.\&.);" .SH "DESCRIPTION" .PP The \fBne_buffer_append\fR and \fBne_buffer_zappend\fR functions append a string to the end of a buffer; extending the buffer as necessary\&. The \fIlen\fR passed to \fBne_buffer_append\fR specifies the length of the string to append; there must be no NUL terminator in the first \fIlen\fR bytes of the string\&. \fBne_buffer_zappend\fR must be passed a NUL\-terminated string\&. .PP The \fBne_buffer_concat\fR function takes a variable\-length argument list following \fIstr\fR; each argument must be a \fBchar *\fR pointer to a NUL\-terminated string\&. A NULL pointer must be given as the last argument to mark the end of the list\&. The strings (including \fIstr\fR) are appended to the buffer in the order given\&. None of the strings passed to \fBne_buffer_concat\fR are modified\&. .SH "EXAMPLES" .PP The following code will output "Hello, world\&. And goodbye\&."\&. .sp .if n \{\ .RS 4 .\} .nf ne_buffer *buf = ne_buffer_create(); ne_buffer_zappend(buf, "Hello"); ne_buffer_concat(buf, ", world\&. ", "And ", "goodbye\&.", NULL); puts(buf\->data); ne_buffer_destroy(buf); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_buffer, ne_buffer_create, ne_buffer_destroy .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_clear.3000066400000000000000000000044251257152637300223600ustar00rootroot00000000000000'\" t .\" Title: ne_buffer_clear .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_BUFFER_CLEAR" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_buffer_clear, ne_buffer_grow, ne_buffer_altered \- clear, grow, or mark as altered a string buffer .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_buffer_clear('u .BI "void ne_buffer_clear(ne_buffer\ *" "buf" ");" .HP \w'void\ ne_buffer_altered('u .BI "void ne_buffer_altered(ne_buffer\ *" "buf" ");" .HP \w'void\ ne_buffer_grow('u .BI "void ne_buffer_grow(ne_buffer\ *" "buf" ", size_t\ " "size" ");" .SH "DESCRIPTION" .PP The \fBne_buffer_clear\fR function sets the string stored in \fIbuf\fR to be the empty string ("")\&. .PP The \fBne_buffer_altered\fR function must be used after the string stored in the buffer \fIbuf\fR is modified by directly rather than using ne_buffer_append, ne_buffer_zappend or ne_buffer_concat\&. .PP The \fBne_buffer_grow\fR function ensures that at least \fIsize\fR bytes are allocated for the string; this can be used if a large amount of data is going to be appended to the buffer and may result in more efficient memory allocation\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_concat.3000066400000000000000000000000271257152637300225330ustar00rootroot00000000000000.so ne_buffer_append.3 davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_create.3000066400000000000000000000040011257152637300225230ustar00rootroot00000000000000'\" t .\" Title: ne_buffer_create .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_BUFFER_CREATE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_buffer_create, ne_buffer_ncreate \- create a string buffer .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_buffer\ *ne_buffer_create('u .BI "ne_buffer *ne_buffer_create(void);" .HP \w'ne_buffer\ *ne_buffer_ncreate('u .BI "ne_buffer *ne_buffer_ncreate(size_t\ " "size" ");" .SH "DESCRIPTION" .PP \fBne_buffer_create\fR creates a new buffer object, with an implementation\-defined initial size\&. \fBne_buffer_ncreate\fR creates an \fBne_buffer\fR where the minimum initial size is given in the \fIsize\fR parameter\&. The buffer created will contain the empty string ("")\&. .SH "RETURN VALUE" .PP Both functions return a pointer to a new buffer object, and never NULL\&. .SH "SEE ALSO" .PP ne_buffer .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_destroy.3000066400000000000000000000047441257152637300227670ustar00rootroot00000000000000'\" t .\" Title: ne_buffer_destroy .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_BUFFER_DESTROY" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_buffer_destroy, ne_buffer_finish \- destroy a buffer object .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_buffer_destroy('u .BI "void ne_buffer_destroy(ne_buffer\ *" "buf" ");" .HP \w'char\ *ne_buffer_finish('u .BI "char *ne_buffer_finish(ne_buffer\ *" "buf" ");" .SH "DESCRIPTION" .PP \fBne_buffer_destroy\fR frees all memory associated with the buffer\&. \fBne_buffer_finish\fR frees the buffer structure, but not the actual string stored in the buffer, which is returned and must be \fBfree\fR()d by the caller\&. .PP Any use of the buffer object after calling either of these functions gives undefined behaviour\&. .SH "RETURN VALUE" .PP \fBne_buffer_finish\fR returns the \fBmalloc\fR\-allocated string stored in the buffer\&. .SH "EXAMPLES" .PP An example use of \fBne_buffer_finish\fR; the \fBduplicate\fR function returns a string made up of \fIn\fR copies of \fIstr\fR: .sp .if n \{\ .RS 4 .\} .nf static char *duplicate(int n, const char *str) { ne_buffer *buf = ne_buffer_create(); while (n\-\-) { ne_buffer_zappend(buf, str); } return ne_buffer_finish(buf); } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_buffer, ne_buffer_create, ne_buffer_zappend .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_finish.3000066400000000000000000000000301257152637300225360ustar00rootroot00000000000000.so ne_buffer_destroy.3 davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_grow.3000066400000000000000000000000261257152637300222410ustar00rootroot00000000000000.so ne_buffer_clear.3 davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_ncreate.3000066400000000000000000000000271257152637300227050ustar00rootroot00000000000000.so ne_buffer_create.3 davix-R_0_5_0/deps/libneon/doc/man/ne_buffer_zappend.3000066400000000000000000000000271257152637300227250ustar00rootroot00000000000000.so ne_buffer_append.3 davix-R_0_5_0/deps/libneon/doc/man/ne_calloc.3000066400000000000000000000000201257152637300211610ustar00rootroot00000000000000.so ne_malloc.3 davix-R_0_5_0/deps/libneon/doc/man/ne_close_connection.3000066400000000000000000000000301257152637300232510ustar00rootroot00000000000000.so ne_session_create.3 davix-R_0_5_0/deps/libneon/doc/man/ne_forget_auth.3000066400000000000000000000000311257152637300222350ustar00rootroot00000000000000.so ne_set_server_auth.3 davix-R_0_5_0/deps/libneon/doc/man/ne_get_error.3000066400000000000000000000056141257152637300217320ustar00rootroot00000000000000'\" t .\" Title: ne_get_error .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_GET_ERROR" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_get_error, ne_set_error \- error handling for HTTP sessions .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'const\ char\ *ne_get_error('u .BI "const char *ne_get_error(ne_sesssion\ *" "session" ");" .HP \w'void\ ne_set_error('u .BI "void ne_set_error(ne_sesssion\ *" "session" ", const\ char\ *" "format" ", \&.\&.\&.);" .SH "DESCRIPTION" .PP The session error string is used to store any human\-readable error information associated with any errors which occur whilst using the HTTP session\&. .PP The \fBne_get_error\fR function returns the current session error string\&. This string persists only until it is changed by a subsequent operation on the session\&. If localisation was enabled at build time, and if necessary enabled at run\-time if necessary using ne_i18n_init, the returned string may have been translated into the user\*(Aqs current locale\&. .PP The \fBne_set_error\fR function can be used to set a new session error string, using a \fBprintf\fR\-style format string interface\&. .SH "RETURN VALUE" .PP \fBne_set_error\fR returns a constant NUL\-terminated string\&. In the default English locale, the returned string will \fInot\fR have a terminating \(lq\&.\(rq period character\&. .SH "EXAMPLES" .PP Retrieve the current error string: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess = ne_session_create(\&.\&.\&.); \&.\&.\&. printf("Error was: %s\en", ne_get_error(sess)); .fi .if n \{\ .RE .\} .PP Set a new error string: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess = ne_session_create(\&.\&.\&.); \&.\&.\&. ne_set_error(sess, "Response missing header %s", "somestring"); .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_get_request_flag.3000066400000000000000000000000321257152637300232470ustar00rootroot00000000000000.so ne_set_request_flag.3 davix-R_0_5_0/deps/libneon/doc/man/ne_get_response_header.3000066400000000000000000000065501257152637300237470ustar00rootroot00000000000000'\" t .\" Title: ne_get_response_header .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_GET_RESPONSE_HEAD" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_get_response_header, ne_response_header_iterate \- functions to access response headers .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'const\ char\ *ne_get_response_header('u .BI "const char *ne_get_response_header(ne_request\ *" "request" ", const\ char\ *" "name" ");" .HP \w'void\ *ne_response_header_iterate('u .BI "void *ne_response_header_iterate(ne_request\ *" "request" ", void\ *" "cursor" ", const\ char\ **" "name" ", const\ char\ **" "value" ");" .SH "DESCRIPTION" .PP To retrieve the value of a response header field, the \fBne_get_response_header\fR function can be used, and is given the name of the header to return\&. .PP To iterate over all the response headers returned, the \fBne_response_header_iterate\fR function can be used\&. This function takes a \fIcursor\fR parameter which should be NULL to retrieve the first header\&. The function stores the name and value of the next header header in the \fIname\fR and \fIvalue\fR parameters, and returns a new cursor pointer which can be passed to \fBne_response_header_iterate\fR to retrieve the next header\&. .SH "RETURN VALUE" .PP \fBne_get_response_header\fR returns a string, or NULL if no header with that name was given\&. If used during request processing, the return value pointer is valid only until the next call to \fBne_begin_request\fR, or else, until the request object is destroyed\&. .PP Likewise, the cursor, names, and values returned by \fBne_response_header_iterate\fR are only valid until the next call to \fBne_begin_request\fR or until the request object is destroyed\&. .SH "EXAMPLES" .PP The following code will output the value of the Last\-Modified header for a resource: .sp .if n \{\ .RS 4 .\} .nf ne_request *req = ne_request_create(sess, "GET", "/foo\&.txt"); if (ne_request_dispatch(req) == NE_OK) { const char *mtime = ne_get_response_header(req, "Last\-Modified"); if (mtime) { printf("/foo\&.txt has last\-modified value %s\en", mtime); } } ne_request_destroy(req); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_request_create, ne_request_destroy\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_get_scheme.3000066400000000000000000000000271257152637300220360ustar00rootroot00000000000000.so ne_set_useragent.3 davix-R_0_5_0/deps/libneon/doc/man/ne_get_server_hostport.3000066400000000000000000000000271257152637300240420ustar00rootroot00000000000000.so ne_set_useragent.3 davix-R_0_5_0/deps/libneon/doc/man/ne_get_session_flag.3000066400000000000000000000000321257152637300232420ustar00rootroot00000000000000.so ne_set_session_flag.3 davix-R_0_5_0/deps/libneon/doc/man/ne_get_status.3000066400000000000000000000045021257152637300221170ustar00rootroot00000000000000'\" t .\" Title: ne_get_status .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_GET_STATUS" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_get_status \- retrieve HTTP response status for request .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'const\ ne_status\ *ne_get_status('u .BI "const ne_status *ne_get_status(const\ ne_request\ *" "request" ");" .SH "DESCRIPTION" .PP The \fBne_get_status\fR function returns a pointer to the HTTP status object giving the result of a request\&. The object returned only becomes valid once the request has been \fIsuccessfully\fR dispatched (the return value of \fBne_request_dispatch\fR or \fBne_begin_request\fR was zero)\&. The object remains valid until the associated request object is destroyed\&. .SH "SEE ALSO" .PP ne_status, ne_request_create .SH "EXAMPLE" .PP Display the response status code of applying the HEAD method to some resource\&. .sp .if n \{\ .RS 4 .\} .nf ne_request *req = ne_request_create(sess, "HEAD", "/foo/bar"); if (ne_request_dispatch(req)) /* handle errors\&.\&.\&. */ else printf("Response status code was %d\en", ne_get_status(req)\->code); ne_request_destroy(req); .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_has_support.3000066400000000000000000000044661257152637300223150ustar00rootroot00000000000000'\" t .\" Title: ne_has_support .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_HAS_SUPPORT" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_has_support \- determine feature support status .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'int\ ne_has_support('u .BI "int ne_has_support(int\ " "feature" ");" .SH "DESCRIPTION" .PP The \fBne_has_support\fR function can be used to determine whether a particular optional feature, given by the feature code \fIfeature\fR, is supported\&. The following feature codes are available: .PP \fBNE_FEATURE_SSL\fR .RS 4 Indicates support for SSL/TLS .RE .PP \fBNE_FEATURE_ZLIB\fR .RS 4 Indicates support for compressed responses .RE .PP \fBNE_FEATURE_IPV6\fR .RS 4 Indicates support for IPv6 .RE .PP \fBNE_FEATURE_LFS\fR .RS 4 Indicates support for large files .RE .PP \fBNE_FEATURE_SOCKS\fR .RS 4 Indicates support for SOCKSv5 .RE .PP \fBNE_FEATURE_TS_SSL\fR .RS 4 Indicates support for thread\-safe SSL initialization \(em see ne_sock_init .RE .SH "RETURN VALUE" .PP \fBne_has_support\fR returns non\-zero if the given feature is supported, or zero otherwise\&. .SH "SEE ALSO" .PP ne_version_match(3), ne_sock_init(3) .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_i18n_init.3000066400000000000000000000053601257152637300215420ustar00rootroot00000000000000'\" t .\" Title: ne_i18n_init .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_I18N_INIT" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_i18n_init \- functions to initialize internationalization support .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_i18n_init('u .BI "void ne_i18n_init(const\ char\ *" "encoding" ");" .SH "DESCRIPTION" .PP The \fBne_i18n_init\fR function can be used to enable support for translated messages in the neon library\&. The \fIencoding\fR parameter, if non\-NULL, specifies the character encoding required for generated translated string\&. If it is NULL, the appropriate character encoding for the process locale will be used\&. .PP This call is only strictly necessary if either: .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} neon has been installed into a different prefix than the gettext implementation on which it depends for i18n purposes, or .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} the caller requires that translated messages are in a particular character encoding\&. .RE .PP If \fBne_i18n_init\fR is never called, the message catalogs will not be found if case (a) applies (and so English error messages will be used), and will use the default character encoding specified by the process locale\&. The library will otherwise operate correctly\&. .PP Note that the encoding used is a process\-global setting and so results may be unexpected if other users of neon within the process call \fBne_i18n_init\fR with a different encoding parameter\&. .SH "SEE ALSO" .PP ne_sock_init .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_cmp.3000066400000000000000000000000241257152637300216520ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_free.3000066400000000000000000000000241257152637300220140ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_make.3000066400000000000000000000123631257152637300220210ustar00rootroot00000000000000'\" t .\" Title: ne_iaddr_make .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_IADDR_MAKE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_iaddr_make, ne_iaddr_cmp, ne_iaddr_print, ne_iaddr_typeof, ne_iaddr_parse, ne_iaddr_raw, ne_iaddr_reverse, ne_iaddr_free \- functions to manipulate network addresses .SH "SYNOPSIS" .sp .ft B .nf #include typedef enum { ne_iaddr_ipv4 = 0, ne_iaddr_ipv6 } ne_iaddr_type; .fi .ft .HP \w'ne_inet_addr\ *ne_iaddr_make('u .BI "ne_inet_addr *ne_iaddr_make(ne_iaddr_type\ " "type" ", const\ unsigned\ char\ *" "raw" ");" .HP \w'int\ ne_iaddr_cmp('u .BI "int ne_iaddr_cmp(const\ ne_inet_addr\ *" "ia1" ", const\ ne_inet_addr\ *" "ia2" ");" .HP \w'char\ *ne_iaddr_print('u .BI "char *ne_iaddr_print(const\ ne_inet_addr\ *" "ia" ", char\ *" "buffer" ", size_t\ " "bufsiz" ");" .HP \w'ne_iaddr_type\ ne_iaddr_typeof('u .BI "ne_iaddr_type ne_iaddr_typeof(const\ ne_inet_addr\ *" "ia" ");" .HP \w'ne_inet_addr\ *ne_iaddr_parse('u .BI "ne_inet_addr *ne_iaddr_parse(const\ char\ *" "address" ", ne_iaddr_type\ " "type" ");" .HP \w'unsigned\ char\ *ne_iaddr_raw('u .BI "unsigned char *ne_iaddr_raw(const\ ne_inet_addr\ *" "ia" ", unsigned\ char\ *" "buffer" ");" .HP \w'int\ ne_iaddr_reverse('u .BI "int ne_iaddr_reverse(const\ ne_inet_addr\ *" "ia" ", char\ *" "buffer" ", size_t\ " "buflen" ");" .HP \w'void\ ne_iaddr_free('u .BI "void ne_iaddr_free(const\ ne_inet_addr\ *" "ia" ");" .SH "DESCRIPTION" .PP \fBne_iaddr_make\fR creates an \fBne_inet_addr\fR object from a raw binary network address; for instance the four bytes 0x7f 0x00 0x00 0x01 represent the IPv4 address 127\&.0\&.0\&.1\&. The object returned is suitable for passing to \fBne_sock_connect\fR\&. A binary IPv4 address contains four bytes; a binary IPv6 address contains sixteen bytes; addresses passed must be in network byte order\&. .PP \fBne_iaddr_cmp\fR compares two network address objects; returning zero only if they are identical\&. The objects need not have the same address type; if the addresses are not of the same type, the return value is guaranteed to be non\-zero\&. .PP \fBne_iaddr_print\fR prints a human\-readable string representation of a network address into a buffer, for instance the string "127\&.0\&.0\&.1"\&. .PP \fBne_iaddr_typeof\fR returns the type of the given network address object\&. .PP \fBne_iaddr_parse\fR parses a string representation of a network address (such as "127\&.0\&.0\&.1" and creates a network address object to represent the parsed address\&. .PP \fBne_iaddr_raw\fR writes the raw byte representation of a network address to the provided buffer\&. The bytes are written in network byte order; the buffer must be of suitable length for the type of address (4 bytes for an IPv4 address, 16 bytes for an IPv6 address)\&. .PP \fBne_iaddr_reverse\fR performs a reverse name lookup on the address object, writing the (first) hostname associated with the IP address to the provided buffer\&. If the hostname is longer than the buffer it will be silently truncated; on success the string written to the buffer is always NUL\-terminated\&. .PP \fBne_iaddr_free\fR releases the memory associated with a network address object\&. .SH "RETURN VALUE" .PP \fBne_iaddr_make\fR returns NULL if the address type passed is not supported (for instance on a platform which does not support IPv6)\&. .PP \fBne_iaddr_print\fR returns the \fIbuffer\fR pointer, and never NULL\&. .PP \fBne_iaddr_parse\fR returns a network address object on success, or NULL on failure to parse the \fIaddress\fR parameter\&. .PP \fBne_iaddr_reverse\fR returns zero on success or non\-zero if no hostname is associated with the address\&. .PP \fBne_iaddr_raw\fR returns the \fIbuffer\fR parameter, and never NULL\&. .SH "EXAMPLES" .PP The following example connects a socket to port 80 at the address 127\&.0\&.0\&.1\&. .sp .if n \{\ .RS 4 .\} .nf unsigned char addr[] = "\e0x7f\e0x00\e0x00\e0x01"; ne_inet_addr *ia; ia = ne_iaddr_make(ne_iaddr_ipv4, addr); if (ia != NULL) { ne_socket *sock = ne_sock_connect(ia, 80); ne_iaddr_free(ia); /* \&.\&.\&. */ } else { /* \&.\&.\&. */ } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_addr_resolve .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_parse.3000066400000000000000000000000241257152637300222050ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_print.3000066400000000000000000000000241257152637300222270ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_raw.3000066400000000000000000000000241257152637300216640ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_reverse.3000066400000000000000000000000241257152637300225460ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_iaddr_typeof.3000066400000000000000000000000241257152637300224010ustar00rootroot00000000000000.so ne_iaddr_make.3 davix-R_0_5_0/deps/libneon/doc/man/ne_malloc.3000066400000000000000000000051741257152637300212120ustar00rootroot00000000000000'\" t .\" Title: ne_malloc .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_MALLOC" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_malloc, ne_calloc, ne_realloc, ne_strdup, ne_strndup, ne_oom_callback \- memory allocation wrappers .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ *ne_malloc('u .BI "void *ne_malloc(size_t\ " "size" ");" .HP \w'void\ *ne_calloc('u .BI "void *ne_calloc(size_t\ " "size" ");" .HP \w'void\ *ne_realloc('u .BI "void *ne_realloc(void\ *" "size" ", size_t\ " "len" ");" .HP \w'char\ *ne_strdup('u .BI "char *ne_strdup(const\ char\ *" "s" ");" .HP \w'char\ *ne_strndup('u .BI "char *ne_strndup(const\ char\ *" "s" ", size_t\ " "size" ");" .HP \w'void\ ne_oom_callback('u .BI "void ne_oom_callback(void\ (*" "callback" ")(void));" .SH "DESCRIPTION" .PP The functions \fBne_malloc\fR, \fBne_calloc\fR, \fBne_realloc\fR, \fBne_strdup\fR and \fBne_strdnup\fR provide wrappers for the equivalent functions in the standard C library\&. The wrappers provide the extra guarantee that if the C library equivalent returns NULL when no memory is available, an optional callback will be called, and the library will then call \fBabort\fR()\&. .PP \fBne_oom_callback\fR registers a callback which will be invoked if an out of memory error is detected\&. .SH "NOTES" .PP If the operating system uses optimistic memory allocation, the C library memory allocation routines will not return NULL, so it is not possible to gracefully handle memory allocation failures\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_oom_callback.3000066400000000000000000000000201257152637300223320ustar00rootroot00000000000000.so ne_malloc.3 davix-R_0_5_0/deps/libneon/doc/man/ne_print_request_header.3000066400000000000000000000000341257152637300241450ustar00rootroot00000000000000.so ne_add_request_header.3 davix-R_0_5_0/deps/libneon/doc/man/ne_qtoken.3000066400000000000000000000000171257152637300212330ustar00rootroot00000000000000.so ne_token.3 davix-R_0_5_0/deps/libneon/doc/man/ne_realloc.3000066400000000000000000000000201257152637300213450ustar00rootroot00000000000000.so ne_malloc.3 davix-R_0_5_0/deps/libneon/doc/man/ne_request_create.3000066400000000000000000000122641257152637300227540ustar00rootroot00000000000000'\" t .\" Title: ne_request_create .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_REQUEST_CREATE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_request_create, ne_request_dispatch, ne_request_destroy \- low\-level HTTP request handling .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_request\ *ne_request_create('u .BI "ne_request *ne_request_create(ne_session\ *" "session" ", const\ char\ *" "method" ", const\ char\ *" "path" ");" .HP \w'int\ ne_request_dispatch('u .BI "int ne_request_dispatch(ne_request\ *" "req" ");" .HP \w'void\ ne_request_destroy('u .BI "void ne_request_destroy(ne_request\ *" "req" ");" .SH "DESCRIPTION" .PP An HTTP request, represented by the \fBne_request\fR type, specifies that some operation is to be performed on some resource\&. The \fBne_request_create\fR function creates a request object, specifying the operation in the \fImethod\fR parameter\&. The location of the resource is determined by the server in use for the session given by the \fIsess\fR parameter, combined with the \fIpath\fR parameter\&. .PP The \fIpath\fR string used must conform to the abs_path definition given in RFC2396, with an optional "?query" part, and must be URI\-escaped by the caller (for instance, using \fBne_path_escape\fR)\&. If the string comes from an untrusted source, failure to perform URI\-escaping results in a security vulnerability\&. .PP To dispatch a request, and process the response, the \fBne_request_dispatch\fR function can be used\&. An alternative is to use the (more complex, but more flexible) combination of the \fBne_begin_request\fR, \fBne_end_request\fR, and \fBne_read_response_block\fR functions; see \fBne_begin_request\fR\&. .PP To add extra headers in the request, the functions ne_add_request_header and ne_print_request_header can be used\&. To include a message body with the request, one of the functions \fBne_set_request_body_buffer\fR, ne_set_request_body_fd, or \fBne_set_request_body_provider\fR can be used\&. .PP The return value of \fBne_request_dispatch\fR indicates merely whether the request was sent and the response read successfully\&. To discover the result of the operation, ne_get_status, along with any processing of the response headers and message body\&. .PP A request can only be dispatched once: calling \fBne_request_dispatch\fR more than once on a single \fBne_request\fR object produces undefined behaviour\&. Once all processing associated with the request object is complete, use the \fBne_request_destroy\fR function to destroy the resources associated with it\&. Any subsequent use of the request object produces undefined behaviour\&. .PP If a request is being using a non\-idempotent method such as POST, the NE_REQFLAG_IDEMPOTENT flag should be disabled; see ne_set_request_flag\&. .SH "RETURN VALUE" .PP The \fBne_request_create\fR function returns a pointer to a request object (and never NULL)\&. .PP The \fBne_request_dispatch\fR function returns zero if the request was dispatched successfully, and a non\-zero error code otherwise\&. .SH "ERRORS" .PP \fBNE_ERROR\fR .RS 4 Request failed (see session error string) .RE .PP \fBNE_LOOKUP\fR .RS 4 The DNS lookup for the server (or proxy server) failed\&. .RE .PP \fBNE_AUTH\fR .RS 4 Authentication failed on the server\&. .RE .PP \fBNE_PROXYAUTH\fR .RS 4 Authentication failed on the proxy server\&. .RE .PP \fBNE_CONNECT\fR .RS 4 A connection to the server could not be established\&. .RE .PP \fBNE_TIMEOUT\fR .RS 4 A timeout occurred while waiting for the server to respond\&. .RE .SH "EXAMPLE" .PP An example of applying a MKCOL operation to the resource at the location http://www\&.example\&.com/foo/bar/: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess = ne_session_create("http", "www\&.example\&.com", 80); ne_request *req = ne_request_create(sess, "MKCOL", "/foo/bar/"); if (ne_request_dispatch(req)) { printf("Request failed: %s\en", ne_get_error(sess)); } ne_request_destroy(req); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_get_error, ne_set_error, ne_get_status, ne_add_request_header, ne_set_request_body_buffer, ne_set_request_flag\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_request_destroy.3000066400000000000000000000000301257152637300231660ustar00rootroot00000000000000.so ne_request_create.3 davix-R_0_5_0/deps/libneon/doc/man/ne_request_dispatch.3000066400000000000000000000000301257152637300232740ustar00rootroot00000000000000.so ne_request_create.3 davix-R_0_5_0/deps/libneon/doc/man/ne_response_header_iterate.3000066400000000000000000000000351257152637300246150ustar00rootroot00000000000000.so ne_get_response_header.3 davix-R_0_5_0/deps/libneon/doc/man/ne_session_create.3000066400000000000000000000104501257152637300227420ustar00rootroot00000000000000'\" t .\" Title: ne_session_create .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SESSION_CREATE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_session_create, ne_close_connection, ne_session_proxy, ne_session_destroy \- set up HTTP sessions .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_session\ *ne_session_create('u .BI "ne_session *ne_session_create(const\ char\ *" "scheme" ", const\ char\ *" "hostname" ", unsigned\ int\ " "port" ");" .HP \w'void\ ne_session_proxy('u .BI "void ne_session_proxy(ne_session\ *" "session" ", const\ char\ *" "hostname" ", unsigned\ int\ " "port" ");" .HP \w'void\ ne_close_connection('u .BI "void ne_close_connection(ne_session\ *" "session" ");" .HP \w'void\ ne_session_destroy('u .BI "void ne_session_destroy(ne_session\ *" "session" ");" .SH "DESCRIPTION" .PP An \fBne_session\fR object represents an HTTP session \- a logical grouping of a sequence of HTTP requests made to a certain server\&. Any requests made using the session can use a persistent connection, share cached authentication credentials and any other common attributes\&. .PP A new HTTP session is created using \fBne_session_create\fR, giving the \fIhostname\fR and \fIport\fR of the server to use, along with the \fIscheme\fR used to contact the server (usually "http")\&. Before the first use of \fBne_session_create\fR in a process, ne_sock_init must have been called to perform any global initialization needed by any libraries used by neon\&. .PP To enable SSL/TLS for the session, pass the string "https" as the \fIscheme\fR parameter, and either register a certificate verification function (see ne_ssl_set_verify) or trust the appropriate certificate (see ne_ssl_trust_cert, ne_ssl_trust_default_ca)\&. .PP If an HTTP proxy server should be used for the session, \fBne_session_proxy\fR must be called giving the hostname and port on which to contact the proxy\&. .PP Further per\-session options may be changed using the ne_set_request_flag interface\&. .PP If it is known that the session will not be used for a significant period of time, \fBne_close_connection\fR can be called to close the connection, if one remains open\&. Use of this function is entirely optional, but it must not be called if there is a request active using the session\&. .PP Once a session has been completed, \fBne_session_destroy\fR must be called to destroy the resources associated with the session\&. Any subsequent use of the session pointer produces undefined behaviour\&. .SH "NOTES" .PP The hostname passed to \fBne_session_create\fR is resolved when the first request using the session is dispatched; a DNS resolution failure can only be detected at that time (using the NE_LOOKUP error code); see ne_request_dispatch for details\&. .SH "RETURN VALUES" .PP \fBne_session_create\fR will return a pointer to a new session object (and never NULL)\&. .SH "EXAMPLES" .PP Create and destroy a session: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess; sess = ne_session_create("http", "host\&.example\&.com", 80); /* \&.\&.\&. use sess \&.\&.\&. */ ne_session_destroy(sess); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_ssl_set_verify, ne_ssl_trust_cert, ne_sock_init, ne_set_session_flag .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_session_destroy.3000066400000000000000000000000301257152637300231610ustar00rootroot00000000000000.so ne_session_create.3 davix-R_0_5_0/deps/libneon/doc/man/ne_session_proxy.3000066400000000000000000000000301257152637300226510ustar00rootroot00000000000000.so ne_session_create.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_connect_timeout.3000066400000000000000000000000271257152637300240050ustar00rootroot00000000000000.so ne_set_useragent.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_error.3000066400000000000000000000000231257152637300217330ustar00rootroot00000000000000.so ne_get_error.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_proxy_auth.3000066400000000000000000000000311257152637300230030ustar00rootroot00000000000000.so ne_set_server_auth.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_read_timeout.3000066400000000000000000000000271257152637300232670ustar00rootroot00000000000000.so ne_set_useragent.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_request_body_buffer.3000066400000000000000000000052771257152637300246600ustar00rootroot00000000000000'\" t .\" Title: ne_set_request_body_buffer .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SET_REQUEST_BODY_" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_set_request_body_buffer, ne_set_request_body_fd, ne_set_request_body_fd64 \- include a message body with a request .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_set_request_body_buffer('u .BI "void ne_set_request_body_buffer(ne_request\ *" "req" ", const\ char\ *" "buf" ", size_t\ " "count" ");" .HP \w'int\ ne_set_request_body_fd('u .BI "int ne_set_request_body_fd(ne_request\ *" "req" ", int\ " "fd" ", off_t\ " "begin" ", off_t\ " "length" ");" .SH "DESCRIPTION" .PP The \fBne_set_request_body_buffer\fR function specifies that a message body should be included with the body, which is stored in the \fIcount\fR bytes buffer \fIbuf\fR\&. .PP The \fBne_set_request_body_fd\fR function can be used to include a message body with a request which is read from a file descriptor\&. The body is read from the file descriptor \fIfd\fR, which must be a associated with a seekable file (not a pipe, socket, or FIFO)\&. \fIcount\fR bytes are read, beginning at offset \fIbegin\fR (hence, passing \fIbegin\fR as zero means the body is read from the beginning of the file)\&. .PP For all the above functions, the source of the request body must survive until the request has been dispatched; neither the memory buffer passed to \fBne_set_request_body_buffer\fR nor the file descriptor passed to \fBne_set_request_body_fd\fR are copied internally\&. .SH "SEE ALSO" .PP ne_request_create .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_set_request_body_fd.3000066400000000000000000000000411257152637300237600ustar00rootroot00000000000000.so ne_set_request_body_buffer.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_request_body_fd64.3000066400000000000000000000000411257152637300241320ustar00rootroot00000000000000.so ne_set_request_body_buffer.3 davix-R_0_5_0/deps/libneon/doc/man/ne_set_request_flag.3000066400000000000000000000052011257152637300232660ustar00rootroot00000000000000'\" t .\" Title: ne_set_request_flag .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SET_REQUEST_FLAG" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_set_request_flag, ne_get_request_flag \- set and retrieve per\-request flags .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_set_request_flag('u .BI "void ne_set_request_flag(ne_request\ *" "req" ", ne_request_flag\ " "flag" ", int\ " "value" ");" .HP \w'int\ ne_get_request_flag('u .BI "int ne_get_request_flag(ne_request\ *" "req" ", ne_request_flag\ " "flag" ");" .SH "DESCRIPTION" .PP The \fBne_set_request_flag\fR function enables or disables a per\-request flag\&. Passing a non\-zero \fIvalue\fR argument enables the flag, and zero disables it\&. .PP The following flags are defined: .PP \fBNE_REQFLAG_EXPECT100\fR .RS 4 enable this flag to use the "Expect: 100\-continue" feature of HTTP/1\&.1, which allows the server to process request headers without reading the entire request body\&. This saves time and bandwidth if the server gives an authentication challenge (requiring the request to be resent), but has interoperability problems with some older servers\&. .RE .PP \fBNE_REQFLAG_IDEMPOTENT\fR .RS 4 disable this flag if the request uses a non\-idempotent method such as POST .RE .SH "RETURN VALUE" .PP The \fBne_get_request_flag\fR function returns zero if a flag is disabled, less than zero if the flag is not supported, or greater than zero if the flag is enabled\&. .SH "SEE ALSO" .PP ne_request_create\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_set_server_auth.3000066400000000000000000000074311257152637300231430ustar00rootroot00000000000000'\" t .\" Title: ne_set_server_auth .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SET_SERVER_AUTH" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_set_server_auth, ne_set_proxy_auth, ne_forget_auth \- register authentication callbacks .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'typedef\ int\ (*ne_auth_creds)('u .BI "typedef int (*ne_auth_creds)(void\ *" "userdata" ", const\ char\ *" "realm" ", int\ " "attempt" ", char\ *" "username" ", char\ *" "password" ");" .HP \w'void\ ne_set_server_auth('u .BI "void ne_set_server_auth(ne_session\ *" "session" ", ne_auth_creds\ " "callback" ", void\ *" "userdata" ");" .HP \w'void\ ne_set_proxy_auth('u .BI "void ne_set_proxy_auth(ne_session\ *" "session" ", ne_auth_creds\ " "callback" ", void\ *" "userdata" ");" .HP \w'void\ ne_forget_auth('u .BI "void ne_forget_auth(ne_session\ *" "session" ");" .SH "DESCRIPTION" .PP The \fBne_auth_creds\fR function type defines a callback which is invoked when a server or proxy server requires user authentication for a particular request\&. The \fIrealm\fR string is supplied by the server\&. The \fIattempt\fR is a counter giving the number of times the request has been retried with different authentication credentials\&. The first time the callback is invoked for a particular request, \fIattempt\fR will be zero\&. .PP To retry the request using new authentication credentials, the callback should return zero, and the \fIusername\fR and \fIpassword\fR buffers must contain NUL\-terminated strings\&. The NE_ABUFSIZ constant gives the size of these buffers\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBTip\fR .ps -1 .br .PP If you only wish to allow the user one attempt to enter credentials, use the value of the \fIattempt\fR parameter as the return value of the callback\&. .sp .5v .RE .PP To abort the request, the callback should return a non\-zero value; in which case the contents of the \fIusername\fR and \fIpassword\fR buffers are ignored\&. .PP The \fBne_forget_auth\fR function can be used to discard the cached authentication credentials\&. .SH "EXAMPLES" .sp .if n \{\ .RS 4 .\} .nf /* Function which prompts for a line of user input: */ extern char *prompt_for(const char *prompt); static int my_auth(void *userdata, const char *realm, int attempts, char *username, char *password) { strncpy(username, prompt_for("Username: "), NE_ABUFSIZ); strncpy(password, prompt_for("Password: "), NE_ABUFSIZ); return attempts; } int main(\&.\&.\&.) { ne_session *sess = ne_session_create(\&.\&.\&.); ne_set_server_auth(sess, my_auth, NULL); /* \&.\&.\&. */ } .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_set_session_flag.3000066400000000000000000000060051257152637300232640ustar00rootroot00000000000000'\" t .\" Title: ne_set_session_flag .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SET_SESSION_FLAG" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_set_session_flag, ne_get_session_flag \- set and retrieve session flags .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_set_session_flag('u .BI "void ne_set_session_flag(ne_session\ *" "sess" ", ne_session_flag\ " "flag" ", int\ " "value" ");" .HP \w'int\ ne_get_session_flag('u .BI "int ne_get_session_flag(ne_session\ *" "sess" ", ne_session_flag\ " "flag" ");" .SH "DESCRIPTION" .PP The \fBne_set_session_flag\fR function enables or disables a session flag\&. Passing a non\-zero \fIvalue\fR argument enables the flag, and zero disables it\&. .PP The following flags are defined: .PP \fBNE_SESSFLAG_PERSIST\fR .RS 4 disable this flag to prevent use of persistent connections .RE .PP \fBNE_SESSFLAG_ICYPROTO\fR .RS 4 enable this flag to enable support for non\-HTTP ShoutCast\-style "ICY" responses .RE .PP \fBNE_SESSFLAG_SSLv2\fR .RS 4 disable this flag to disable support for the SSLv2 protocol .RE .PP \fBNE_SESSFLAG_RFC4918\fR .RS 4 enable this flag to enable support for RFC4918\-only WebDAV features; losing backwards\-compatibility with RFC2518 servers .RE .PP \fBNE_SESSFLAG_CONNAUTH\fR .RS 4 enable this flag if an RFC\-violating connection\-based HTTP authentication scheme is in use .RE .PP \fBNE_SESSFLAG_TLS_SNI\fR .RS 4 disable this flag if a server is used which does not correctly support the TLS SNI extension .RE .PP \fBNE_SESSFLAG_EXPECT100\fR .RS 4 enable this flag to enable the request flag \fBNE_REQFLAG_EXPECT100\fR for new requests .RE .SH "RETURN VALUE" .PP The \fBne_get_session_flag\fR function returns zero if a flag is disabled, less than zero if the flag is not supported, or greater than zero if the flag is enabled\&. .SH "SEE ALSO" .PP ne_session_create, ne_set_request_flag\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_set_useragent.3000066400000000000000000000075171257152637300226160ustar00rootroot00000000000000'\" t .\" Title: ne_set_useragent .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SET_USERAGENT" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_set_useragent, ne_set_read_timeout, ne_set_connect_timeout, ne_get_scheme, ne_get_server_hostport \- common properties for HTTP sessions .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_set_useragent('u .BI "void ne_set_useragent(ne_session\ *" "session" ", const\ char\ *" "product" ");" .HP \w'void\ ne_set_read_timeout('u .BI "void ne_set_read_timeout(ne_session\ *" "session" ", int\ " "timeout" ");" .HP \w'void\ ne_set_connect_timeout('u .BI "void ne_set_connect_timeout(ne_session\ *" "session" ", int\ " "timeout" ");" .HP \w'const\ char\ *ne_get_scheme('u .BI "const char *ne_get_scheme(ne_sesssion\ *" "session" ");" .HP \w'const\ char\ *ne_get_server_hostport('u .BI "const char *ne_get_server_hostport(ne_sesssion\ *" "session" ");" .SH "DESCRIPTION" .PP The User\-Agent request header is used to identify the software which generated the request for statistical or debugging purposes\&. neon does not send a User\-Agent header unless a call is made to the \fBne_set_useragent\fR\&. \fBne_set_useragent\fR must be passed a product string conforming to RFC2616\*(Aqs product token grammar; of the form "Product/Version"\&. .PP When neon reads from a socket, by default the read operation will time out after 60 seconds, and the request will fail giving an \fBNE_TIMEOUT\fR error\&. To configure this timeout interval, call \fBne_set_read_timeout\fR giving the desired number of seconds as the \fItimeout\fR parameter\&. .PP When a connection is being established to a server, normally only the system\*(Aqs TCP timeout handling will apply\&. To configure a specific (and probably shorter) timeout, the \fBne_set_connect_timeout\fR can be used, giving the desired number of seconds as the \fItimeout\fR parameter\&. If 0 is passed, then the default behaviour of using the system TCP timeout will be used\&. .PP The scheme used to initially create the session will be returned by \fBne_get_scheme\fR\&. .PP The hostport pair with which the session is associated will be returned by the \fBne_get_server_hostport\fR; for example www\&.example\&.com:8080\&. Note that the :port will be omitted if the default port for the scheme is used\&. .SH "EXAMPLES" .PP Set a user\-agent string: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess = ne_session_create(\&.\&.\&.); ne_set_useragent(sess, "MyApplication/2\&.1"); .fi .if n \{\ .RE .\} .PP Set a 30 second read timeout: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess = ne_session_create(\&.\&.\&.); ne_set_read_timeout(sess, 30); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_session_create, ne_set_session_flag\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_shave.3000066400000000000000000000036011257152637300210420ustar00rootroot00000000000000'\" t .\" Title: ne_shave .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SHAVE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_shave \- trim whitespace from a string .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'char\ *ne_shave('u .BI "char *ne_shave(char\ *" "str" ", const\ char\ *" "whitespace" ");" .SH "DESCRIPTION" .PP \fBne_shave\fR returns a portion of \fIstr\fR with any leading or trailing characters in the \fIwhitespace\fR array removed\&. \fIstr\fR may be modified\&. Note that the return value may not be equal to \fIstr\fR\&. .SH "EXAMPLES" .PP The following code segment will output "fish": .sp .if n \{\ .RS 4 .\} .nf char s[] = "\&.!\&.fish!\&.!"; puts(ne_shave(s, "\&.!")); .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_sock_exit.3000066400000000000000000000000231257152637300217170ustar00rootroot00000000000000.so ne_sock_init.3 davix-R_0_5_0/deps/libneon/doc/man/ne_sock_init.3000066400000000000000000000110471257152637300217210ustar00rootroot00000000000000'\" t .\" Title: ne_sock_init .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SOCK_INIT" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_sock_init, ne_sock_exit \- perform library initialization .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'int\ ne_sock_init('u .BI "int ne_sock_init(void);" .HP \w'void\ ne_sock_exit('u .BI "void ne_sock_exit(void);" .SH "DESCRIPTION" .PP In some platforms and configurations, neon may be using some socket or SSL libraries which require global initialization before use\&. To perform this initialization, the \fBne_sock_init\fR function must be called before any other library functions are used\&. .PP Once all use of neon is complete, \fBne_sock_exit\fR can be called to perform de\-initialization of socket or SSL libraries, if necessary\&. Uses of \fBne_sock_init\fR and \fBne_sock_exit\fR are "reference counted"; if N calls to \fBne_sock_init\fR are made, only the Nth call to \fBne_sock_exit\fR will have effect\&. .PP \fBne_sock_init\fR will set the disposition of the SIGPIPE signal to \fIignored\fR\&. No change is made to the SIGPIPE disposition by \fBne_sock_exit\fR\&. .PP Both the SSL libraries supported by neon \(em OpenSSL and GnuTLS \(em require callbacks to be registered to allow thread\-safe use of SSL\&. These callbacks are stored as global variables and so their state persists for as long as the library in question is loaded into the process\&. If multiple users of the SSL library exist within the process, this can be problematic, particularly if one is dynamically loaded (and may subsequently be unloaded)\&. .PP If neon is configured using the \-\-enable\-threadsafe\-ssl flag, thread\-safe SSL support will be enabled automatically, as covered in the following section\&. Otherwise, it is not safe to use neon with SSL in a multi\-threaded process\&. The ne_has_support function can be used to determine whether neon is built to enable thread\-safety support in the SSL library\&. .SS "Thread\-safe SSL with OpenSSL" .PP neon follows two simple rules when dealing with the OpenSSL locking callbacks: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fBne_sock_init\fR will set thread\-safety locking callbacks if and only if no locking callbacks are already registered\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fBne_sock_exit\fR will unset the thread\-safety locking callbacks if and only if the locking callbacks registered are those registered by \fBne_sock_init\fR\&. .RE .sp Applications and libraries should be able to co\-operate to ensure that SSL use is always thread\-safe if similar rules are always followed\&. .SS "Thread\-safe SSL with GnuTLS" .PP The cryptography library used by GnuTLS, libgcrypt, only supports an initialization operation to register thread\-safety callbacks\&. \fBne_sock_init\fR will register the thread\-safe locking callbacks on first use; \fBne_sock_exit\fR cannot unregister them\&. If multiple users of GnuTLS are present within the process, it is unsafe to dynamically unload neon from the process if neon is configured with thread\-safe SSL support enabled (since the callbacks would be left pointing at unmapped memory once neon is unloaded)\&. .SH "RETURN VALUE" .PP \fBne_sock_init\fR returns zero on success, or non\-zero on error\&. If an error occurs, no further use of the neon library should be attempted\&. .SH "SEE ALSO" .PP neon(3), ne_has_support(3) .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_cmp.3000066400000000000000000000037131257152637300224150ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_cert_cmp .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_CERT_CMP" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_cert_cmp, ne_ssl_cert_free \- functions to operate on certificate objects .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'int\ ne_ssl_cert_cmp('u .BI "int ne_ssl_cert_cmp(const\ ne_ssl_certificate\ *" "c1" ", const\ ne_ssl_certificate\ *" "c2" ");" .HP \w'void\ ne_ssl_cert_free('u .BI "void ne_ssl_cert_free(ne_ssl_certificate\ *" "cert" ");" .SH "DESCRIPTION" .PP The \fBne_ssl_cert_cmp\fR function can be used to compare two certificate objects; it returns zero if they refer to the same certificate, and non\-zero otherwise\&. .PP The \fBne_ssl_cert_free\fR function can be used to destroy a certificate object when it is no longer needed\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_export.3000066400000000000000000000000271257152637300231520ustar00rootroot00000000000000.so ne_ssl_cert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_free.3000066400000000000000000000000261257152637300225510ustar00rootroot00000000000000.so ne_ssl_cert_cmp.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_identity.3000066400000000000000000000073141257152637300234700ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_cert_identity .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_CERT_IDENTITY" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_cert_identity, ne_ssl_cert_signedby, ne_ssl_cert_issuer, ne_ssl_cert_subject \- functions to access certificate properties .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'const\ char\ *ne_ssl_cert_identity('u .BI "const char *ne_ssl_cert_identity(const\ ne_ssl_certificate\ *" "cert" ");" .HP \w'const\ ne_ssl_certificate\ *ne_ssl_cert_signedby('u .BI "const ne_ssl_certificate *ne_ssl_cert_signedby(const\ ne_ssl_certificate\ *" "cert" ");" .HP \w'const\ ne_ssl_dname\ *ne_ssl_cert_subject('u .BI "const ne_ssl_dname *ne_ssl_cert_subject(const\ ne_ssl_certificate\ *" "cert" ");" .HP \w'const\ ne_ssl_dname\ *ne_ssl_cert_issuer('u .BI "const ne_ssl_dname *ne_ssl_cert_issuer(const\ ne_ssl_certificate\ *" "cert" ");" .SH "DESCRIPTION" .PP The function \fBne_ssl_cert_identity\fR retrieves the \(lqidentity\(rq of a certificate; for an SSL server certificate, this will be the hostname for which the certificate was issued\&. In PKI parlance, the identity is the \fIcommon name\fR attribute of the distinguished name of the certificate subject\&. .PP The functions \fBne_ssl_cert_subject\fR and \fBne_ssl_cert_issuer\fR can be used to access the objects representing the distinguished name of the subject and of the issuer of a certificate, respectively\&. .PP If a certificate object is part of a certificate chain, then \fBne_ssl_cert_signedby\fR can be used to find the certificate which signed a particular certificate\&. For a self\-signed certificate or a certificate for which the full chain is not available, this function will return NULL\&. .SH "RETURN VALUE" .PP \fBne_ssl_cert_issuer\fR and \fBne_ssl_cert_subject\fR are guaranteed to never return NULL\&. \fBne_ssl_cert_identity\fR may return NULL if the certificate has no specific \(lqidentity\(rq\&. \fBne_ssl_cert_signedby\fR may return NULL as covered above\&. .SH "EXAMPLES" .PP The following function could be used to display information about a given certificate: .sp .if n \{\ .RS 4 .\} .nf void dump_cert(const ne_ssl_certificate *cert) { const char *id = ne_ssl_cert_identity(cert); char *dn; if (id) printf("Certificate was issued for \*(Aq%s\*(Aq\&.\en", id); dn = ne_ssl_readable_dname(ne_ssl_cert_subject(cert)); printf("Subject: %s\en", dn); free(dn); dn = ne_ssl_readable_dname(ne_ssl_cert_issuer(cert)); printf("Issuer: %s\en", dn); free(dn); } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_ssl_cert_cmp, ne_ssl_readable_dname .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_import.3000066400000000000000000000000271257152637300231430ustar00rootroot00000000000000.so ne_ssl_cert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_issuer.3000066400000000000000000000000331257152637300231400ustar00rootroot00000000000000.so ne_ssl_cert_identity.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_read.3000066400000000000000000000065671257152637300225630ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_cert_read .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_CERT_READ" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_cert_read, ne_ssl_cert_write, ne_ssl_cert_import, ne_ssl_cert_export \- functions to read or write certificates to and from files or strings .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_ssl_certificate\ *ne_ssl_cert_read('u .BI "ne_ssl_certificate *ne_ssl_cert_read(const\ char\ *" "filename" ");" .HP \w'int\ ne_ssl_cert_write('u .BI "int ne_ssl_cert_write(const\ ne_ssl_certificate\ *" "cert" ", const\ char\ *" "filename" ");" .HP \w'ne_ssl_certificate\ *ne_ssl_cert_import('u .BI "ne_ssl_certificate *ne_ssl_cert_import(const\ char\ *" "data" ");" .HP \w'char\ *ne_ssl_cert_export('u .BI "char *ne_ssl_cert_export(const\ ne_ssl_certificate\ *" "cert" ");" .SH "DESCRIPTION" .PP The \fBne_ssl_cert_write\fR function writes a certificate to a file using the PEM encoding\&. The \fBne_ssl_cert_export\fR function returns a base64\-encoded NUL\-terminated string representing the certificate\&. This string is malloc\-allocated and should be destroyed using \fBfree\fR by the caller\&. .PP The \fBne_ssl_cert_read\fR function reads a certificate from a PEM\-encoded file, and returns a certificate object\&. The \fBne_ssl_cert_import\fR function returns a certificate object from a base64\-encoded string, \fIdata\fR, as returned by \fBne_ssl_cert_export\fR\&. The certificate object returned by these functions should be destroyed using ne_ssl_cert_free after use\&. .SH "RETURN VALUE" .PP \fBne_ssl_cert_read\fR returns NULL if a certificate could not be read from the file\&. \fBne_ssl_cert_write\fR returns non\-zero if the certificate could not be written to the file\&. \fBne_ssl_cert_export\fR always returns a NUL\-terminated string, and never NULL\&. \fBne_ssl_cert_import\fR returns NULL if the string was not a valid base64\-encoded certificate\&. .SH "ENCODING FORMATS" .PP The string produced by \fBne_ssl_cert_export\fR is the base64 encoding of the DER representation of the certificate\&. The file written by \fBne_ssl_cert_write\fR uses the PEM format: this is the base64 encoding of the DER representation with newlines every 64 characters, and start and end marker lines\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_signedby.3000066400000000000000000000000331257152637300234320ustar00rootroot00000000000000.so ne_ssl_cert_identity.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_subject.3000066400000000000000000000000331257152637300232650ustar00rootroot00000000000000.so ne_ssl_cert_identity.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_cert_write.3000066400000000000000000000000271257152637300227630ustar00rootroot00000000000000.so ne_ssl_cert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_clicert_decrypt.3000066400000000000000000000000321257152637300237670ustar00rootroot00000000000000.so ne_ssl_clicert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_clicert_encrypted.3000066400000000000000000000000321257152637300243120ustar00rootroot00000000000000.so ne_ssl_clicert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_clicert_free.3000066400000000000000000000000321257152637300232360ustar00rootroot00000000000000.so ne_ssl_clicert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_clicert_name.3000066400000000000000000000000321257152637300232350ustar00rootroot00000000000000.so ne_ssl_clicert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_clicert_owner.3000066400000000000000000000000321257152637300234470ustar00rootroot00000000000000.so ne_ssl_clicert_read.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_clicert_read.3000066400000000000000000000117651257152637300232470ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_client_cert .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_CLIENT_CERT" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_clicert_read, ne_ssl_clicert_name, ne_ssl_clicert_encrypted, ne_ssl_clicert_decrypt, ne_ssl_clicert_owner, ne_ssl_clicert_free \- SSL client certificate handling .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_ssl_client_cert\ *ne_ssl_clicert_read('u .BI "ne_ssl_client_cert *ne_ssl_clicert_read(const\ char\ *" "filename" ");" .HP \w'const\ char\ *ne_ssl_clicert_name('u .BI "const char *ne_ssl_clicert_name(const\ ne_ssl_client_cert\ *" "ccert" ");" .HP \w'int\ ne_ssl_clicert_encrypted('u .BI "int ne_ssl_clicert_encrypted(const\ ne_ssl_client_cert\ *" "ccert" ");" .HP \w'int\ ne_ssl_clicert_decrypt('u .BI "int ne_ssl_clicert_decrypt(ne_ssl_client_cert\ *" "ccert" ", const\ char\ *" "password" ");" .HP \w'const\ ne_ssl_certificate\ *ne_ssl_clicert_owner('u .BI "const ne_ssl_certificate *ne_ssl_clicert_owner(const\ ne_ssl_client_cert\ *" "ccert" ");" .HP \w'void\ ne_ssl_clicert_free('u .BI "void ne_ssl_clicert_free(ne_ssl_client_cert\ *" "ccert" ");" .SH "DESCRIPTION" .PP The \fBne_ssl_clicert_read\fR function reads a client certificate from a PKCS#12\-formatted file, and returns an \fBne_ssl_client_cert\fR object\&. If the client certificate is encrypted, it must be decrypted before it is used\&. An \fBne_ssl_client_cert\fR object holds a client certificate and the associated private key, not just a certificate; the term "client certificate" will used to refer to this pair\&. .PP A client certificate can be in one of two states: \fIencrypted\fR or \fIdecrypted\fR\&. The \fBne_ssl_clicert_encrypted\fR function will return non\-zero if the client certificate is in the \fIencrypted\fR state\&. A client certificate object returned by \fBne_ssl_clicert_read\fR may be initially in either state, depending on whether the file was encrypted or not\&. .PP \fBne_ssl_clicert_decrypt\fR can be used to decrypt a client certificate using the appropriate password\&. This function must only be called if the object is in the \fIencrypted\fR state; if decryption fails, the certificate state does not change, so decryption can be attempted more than once using different passwords\&. .PP A client certificate can be given a "friendly name" when it is created; \fBne_ssl_clicert_name\fR will return this name (or NULL if no friendly name was specified)\&. \fBne_ssl_clicert_name\fR can be used when the client certificate is in either the encrypted or decrypted state, and will return the same string for the lifetime of the object\&. .PP The function \fBne_ssl_clicert_owner\fR returns the certificate part of the client certificate; it must only be called if the client certificate is in the \fIdecrypted\fR state\&. .PP When the client certificate is no longer needed, the \fBne_ssl_clicert_free\fR function should be used to destroy the object\&. .SH "RETURN VALUE" .PP \fBne_ssl_clicert_read\fR returns a client certificate object, or NULL if the file could not be read\&. \fBne_ssl_clicert_encrypted\fR returns zero if the object is in the decrypted state, or non\-zero if it is in the encrypted state\&. \fBne_ssl_clicert_name\fR returns a NUL\-terminated friendly name string, or NULL\&. \fBne_ssl_clicert_owner\fR returns a certificate object\&. .SH "EXAMPLES" .PP The following code reads a client certificate and decrypts it if necessary, then loads it into an HTTP session\&. .sp .if n \{\ .RS 4 .\} .nf ne_ssl_client_cert *ccert; ccert = ne_ssl_clicert_read("/path/to/client\&.p12"); if (ccert == NULL) { /* handle error\&.\&.\&. */ } else if (ne_ssl_clicert_encrypted(ccert)) { char *password = prompt_for_password(); if (ne_ssl_clicert_decrypt(ccert, password)) { /* could not decrypt! handle error\&.\&.\&. */ } } ne_ssl_set_clicert(sess, ccert); .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_ssl_cert_read .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_dname_cmp.3000066400000000000000000000000341257152637300225350ustar00rootroot00000000000000.so ne_ssl_readable_dname.3 davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_readable_dname.3000066400000000000000000000044211257152637300235210ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_dname .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_DNAME" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_readable_dname, ne_ssl_dname_cmp \- SSL distinguished name handling .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'const\ char\ *ne_ssl_readable_dname('u .BI "const char *ne_ssl_readable_dname(const\ ne_ssl_dname\ *" "dname" ");" .HP \w'int\ ne_ssl_dname_cmp('u .BI "int ne_ssl_dname_cmp(const\ ne_ssl_dname\ *" "dn1" ", const\ ne_ssl_dname\ *" "dn2" ");" .SH "DESCRIPTION" .PP The \fBne_ssl_readable_dname\fR function creates a single\-line, human\-readable string out of an \fBne_ssl_dname\fR object\&. The returned string is \fBmalloc\fR()\-allocated, and must be \fBfree\fR()d by the caller\&. .PP The \fBne_ssl_dname_cmp\fR function compares two distinguished names, and returns zero if they are equal, or non\-zero otherwise\&. .SH "RETURN VALUE" .PP \fBne_ssl_readable_dname\fR returns a \fBmalloc\fR\-allocated string, and never NULL\&. .SH "EXAMPLES" .PP See ne_ssl_cert_subject for an example use of \fBne_ssl_readable_dname\fR\&. .SH "SEE ALSO" .PP ne_ssl_cert_subject .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_set_verify.3000066400000000000000000000115461257152637300230030ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_set_verify .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_SET_VERIFY" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_set_verify \- register an SSL certificate verification callback .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'typedef\ int\ ne_ssl_verify_fn('u .BI "typedef int ne_ssl_verify_fn(void\ *" "userdata" ", int\ " "failures" ", const\ ne_ssl_certificate\ *" "cert" ");" .HP \w'void\ ne_ssl_set_verify('u .BI "void ne_ssl_set_verify(ne_session\ *" "session" ", ne_ssl_verify_fn\ " "verify_fn" ", void\ *" "userdata" ");" .SH "DESCRIPTION" .PP To enable manual SSL certificate verification, a callback can be registered using \fBne_ssl_set_verify\fR\&. If such a callback is not registered, when a connection is established to an SSL server which does not present a certificate signed by a trusted CA (see ne_ssl_trust_cert), or if the certificate presented is invalid in some way, the connection will fail\&. .PP When the callback is invoked, the \fIfailures\fR parameter gives a bitmask indicating in what way the automatic certificate verification failed\&. The value is equal to the bit\-wise OR of one or more of the following constants (and is guaranteed to be non\-zero): .PP \fBNE_SSL_NOTYETVALID\fR .RS 4 The certificate is not yet valid\&. .RE .PP \fBNE_SSL_EXPIRED\fR .RS 4 The certificate has expired\&. .RE .PP \fBNE_SSL_IDMISMATCH\fR .RS 4 The hostname used for the session does not match the hostname to which the certificate was issued\&. .RE .PP \fBNE_SSL_UNTRUSTED\fR .RS 4 The Certificate Authority which signed the certificate is not trusted\&. .RE .PP Note that if either of the \fBNE_SSL_IDMISMATCH\fR or \fBNE_SSL_UNTRUSTED\fR failures is given, the connection may have been intercepted by a third party, and must not be presumed to be \(lqsecure\(rq\&. .PP The \fIcert\fR parameter passed to the callback represents the certificate which was presented by the server\&. If the server presented a chain of certificates, the chain can be accessed using ne_ssl_cert_signedby\&. The \fIcert\fR object given is not valid after the callback returns\&. .SH "RETURN VALUE" .PP The verification callback must return zero to indicate that the certificate should be trusted; and non\-zero otherwise (in which case, the connection will fail)\&. .SH "EXAMPLES" .PP The following code implements an example verification callback, using the \fBdump_cert\fR function from ne_ssl_cert_subject to display certification information\&. Notice that the hostname of the server used for the session is passed as the \fIuserdata\fR parameter to the callback\&. .sp .if n \{\ .RS 4 .\} .nf static int my_verify(void *userdata, int failures, const ne_ssl_certificate *cert) { const char *hostname = userdata; dump_cert(cert); puts("Certificate verification failed \- the connection may have been " "intercepted by a third party!"); if (failures & NE_SSL_IDMISMATCH) { const char *id = ne_ssl_cert_identity(cert); if (id) printf("Server certificate was issued to \*(Aq%s\*(Aq not \*(Aq%s\*(Aq\&.\en", id, hostname); else printf("The certificate was not issued for \*(Aq%s\*(Aq\en", hostname); } if (failures & NE_SSL_UNTRUSTED) puts("The certificate is not signed by a trusted Certificate Authority\&."); /* \&.\&.\&. check for validity failures \&.\&.\&. */ if (prompt_user()) return 1; /* fail verification */ else return 0; /* trust the certificate anyway */ } int main(\&.\&.\&.) { ne_session *sess = ne_session_create("https", "some\&.host\&.name", 443); ne_ssl_set_verify(sess, my_verify, "some\&.host\&.name"); \&.\&.\&. } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_ssl_trust_cert, ne_ssl_readable_dname, ne_ssl_cert_subject .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_trust_cert.3000066400000000000000000000050651257152637300230210ustar00rootroot00000000000000'\" t .\" Title: ne_ssl_trust_cert .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_SSL_TRUST_CERT" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_ssl_trust_cert, ne_ssl_trust_default_ca \- functions to indicate that certificates are trusted .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'void\ ne_ssl_trust_cert('u .BI "void ne_ssl_trust_cert(ne_session\ *" "session" ", const\ ne_ssl_certificate\ *" "cert" ");" .HP \w'void\ ne_ssl_trust_default_ca('u .BI "void ne_ssl_trust_default_ca(ne_session\ *" "session" ");" .SH "DESCRIPTION" .PP To indicate that a given certificate is trusted by the user, the certificate object can be passed to \fBne_ssl_trust_cert\fR\&. The certificate object is duplicated internally and can subsequently be destroyed\&. .PP The SSL library in use by neon may include a default set of CA certificates; calling the \fBne_ssl_trust_default_ca\fR function will indicate that these CAs are trusted by the user\&. .SH "EXAMPLES" .PP Load the CA certificate stored in /path/to/cacert\&.pem: .sp .if n \{\ .RS 4 .\} .nf ne_session *sess = ne_session_create(\&.\&.\&.); ne_ssl_certificate *cert = ne_ssl_cert_read("/path/to/cacert\&.pem"); if (cert) { ne_ssl_trust_cert(sess, cert); ne_ssl_cert_free(cert); } else { printf("Could not load CA cert: %s\en", ne_get_error(sess)); } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP ne_ssl_cert_read, ne_ssl_cert_import, ne_ssl_cert_free .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_ssl_trust_default_ca.3000066400000000000000000000000301257152637300241360ustar00rootroot00000000000000.so ne_ssl_trust_cert.3 davix-R_0_5_0/deps/libneon/doc/man/ne_status.3000066400000000000000000000047321257152637300212650ustar00rootroot00000000000000'\" t .\" Title: ne_status .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_STATUS" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_status \- HTTP status structure .SH "SYNOPSIS" .sp .ft B .nf #include typedef struct { int major_version, minor_version; int code, klass; const char *reason_phrase; } ne_status; .fi .ft .SH "DESCRIPTION" .PP An \fBne_status\fR type represents an HTTP response status; used in response messages giving a result of request\&. The \fImajor_version\fR and \fIminor_version\fR fields give the HTTP version supported by the server issuing the response\&. The \fIcode\fR field gives the status code of the result (lying between 100 and 999 inclusive), and the \fIklass\fR field gives the class\&\s-2\u[1]\d\s+2, which is equal to the most significant digit of the status\&. .PP There are five classes of HTTP status code defined by RFC2616: .PP 1xx .RS 4 Informational response\&. .RE .PP 2xx .RS 4 Success: the operation was successful .RE .PP 3xx .RS 4 Redirection .RE .PP 4xx .RS 4 Client error: the request made was incorrect in some manner\&. .RE .PP 5xx .RS 4 Server error .RE .SH "SEE ALSO" .PP ne_get_status\&. .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br .SH "NOTES" .IP " 1." 4 the field is named \(lqklass\(rq not \(lqclass\(rq so that the header can be used from a C++ program, in which \(lqclass\(rq is a reserved word) davix-R_0_5_0/deps/libneon/doc/man/ne_strdup.3000066400000000000000000000000201257152637300212450ustar00rootroot00000000000000.so ne_malloc.3 davix-R_0_5_0/deps/libneon/doc/man/ne_strndup.3000066400000000000000000000000201257152637300214230ustar00rootroot00000000000000.so ne_malloc.3 davix-R_0_5_0/deps/libneon/doc/man/ne_token.3000066400000000000000000000051251257152637300210570ustar00rootroot00000000000000'\" t .\" Title: ne_token .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_TOKEN" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_token, ne_qtoken \- string tokenizers .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'char\ *ne_token('u .BI "char *ne_token(char\ **" "str" ", char\ " "sep" ");" .HP \w'char\ *ne_qtoken('u .BI "char *ne_qtoken(char\ **" "str" ", char\ " "sep" ", const\ char\ *" "quotes" ");" .SH "DESCRIPTION" .PP \fBne_token\fR and \fBne_qtoken\fR tokenize the string at the location stored in the pointer \fIstr\fR\&. Each time the function is called, it returns the next token, and modifies the \fIstr\fR pointer to point to the remainer of the string, or NULL if there are no more tokens in the string\&. A token is delimited by the separator character \fIsep\fR; if \fBne_qtoken\fR is used any quoted segments of the string are skipped when searching for a separator\&. A quoted segment is enclosed in a pair of one of the characters given in the \fIquotes\fR string\&. .PP The string being tokenized is modified each time the tokenizing function is called; replacing the next separator character with a NUL terminator\&. .SH "EXAMPLES" .PP The following function prints out each token in a comma\-separated string \fIlist\fR, which is modified in\-place: .sp .if n \{\ .RS 4 .\} .nf static void splitter(char *list) { do { printf("Token: %s\en", ne_token(&list, \*(Aq,\*(Aq)); while (list); } .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_version_match.3000066400000000000000000000043361257152637300226030ustar00rootroot00000000000000'\" t .\" Title: ne_version_match .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_VERSION_MATCH" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_version_match, ne_version_string \- library versioning .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'int\ ne_version_match('u .BI "int ne_version_match(int\ " "major" ", int\ " "minor" ");" .HP \w'const\ char\ *ne_version_string('u .BI "const char *ne_version_string(void);" .SH "DESCRIPTION" .PP The \fBne_version_match\fR function returns non\-zero if the library version is not of major version \fImajor\fR, or the minor version is less than \fIminor\fR\&. For neon versions 0\&.x, every minor version is assumed to be incompatible with every other minor version\&. .PP The \fBne_version_string\fR function returns a string giving the library version\&. .SH "EXAMPLES" .PP To require neon 1\&.x, version 1\&.2 or later: .sp .if n \{\ .RS 4 .\} .nf if (ne_version_match(1, 2)) { printf("Library version out of date: 1\&.2 required, found %s\&.", ne_version_string()); exit(1); } .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_version_string.3000066400000000000000000000000271257152637300230060ustar00rootroot00000000000000.so ne_version_match.3 davix-R_0_5_0/deps/libneon/doc/man/ne_xml_create.3000066400000000000000000000035471257152637300220700ustar00rootroot00000000000000'\" t .\" Title: ne_xml_create .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NE_XML_CREATE" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ne_xml_create, ne_xml_destroy \- create and destroy an XML parser .SH "SYNOPSIS" .sp .ft B .nf #include .fi .ft .HP \w'ne_xml_parser\ *ne_xml_create('u .BI "ne_xml_parser *ne_xml_create(void);" .HP \w'void\ ne_xml_destroy('u .BI "void ne_xml_destroy(ne_xml_parser\ *" "parser" ");" .SH "DESCRIPTION" .PP The \fBne_xml_create\fR function creates an XML parser object, which can be used for parsing XML documents using stacked SAX handlers\&. .SH "RETURN VALUE" .PP \fBne_xml_create\fR returns a pointer to an XML parser object, and never NULL .SH "SEE ALSO" .PP XXX .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/ne_xml_destroy.3000066400000000000000000000000241257152637300223010ustar00rootroot00000000000000.so ne_xml_create.3 davix-R_0_5_0/deps/libneon/doc/man/neon-config.1000066400000000000000000000066521257152637300214630ustar00rootroot00000000000000'\" t .\" Title: neon-config .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NEON\-CONFIG" "1" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" neon-config \- script providing information about installed copy of neon library .SH "SYNOPSIS" .HP \w'\fBneon\-config\fR\ 'u \fBneon\-config\fR [\fB\-\-prefix\fR] [[\fB\-\-cflags\fR] | [\fB\-\-libs\fR] | [\fB\-\-la\-file\fR] | [\fB\-\-support\fR\ \fIfeature\fR] | [\fB\-\-help\fR] | [\fB\-\-version\fR]] .SH "DESCRIPTION" .PP The \fBneon\-config\fR script provides information about an installed copy of the neon library\&. The \fB\-\-cflags\fR and \fB\-\-libs\fR options instruct how to compile and link an application against the library; the \fB\-\-version\fR and \fB\-\-support\fR options can help determine whether the library meets the applications requirements\&. .SH "OPTIONS" .PP \fB\-\-cflags\fR .RS 4 Print the flags which should be passed to the C compiler when compiling object files, when the object files use neon header files\&. .RE .PP \fB\-\-libs\fR .RS 4 Print the flags which should be passed to the linker when linking an application which uses the neon library .RE .PP \fB\-\-la\-file\fR .RS 4 Print the location of the libtool library script, libneon\&.la, which can be used to link against neon by applications using libtool\&. .RE .PP \fB\-\-version\fR .RS 4 Print the version of the library .RE .PP \fB\-\-prefix\fR \fIdir\fR .RS 4 If \fIdir\fR is given; relocate output of \fB\-\-cflags\fR and \fB\-\-libs\fR as if neon was installed in given prefix directory\&. Otherwise, print the installation prefix of the library\&. .RE .PP \fB\-\-support\fR \fIfeature\fR .RS 4 The script exits with success if \fIfeature\fR is supported by the library\&. .RE .PP \fB\-\-help\fR .RS 4 Print help message; includes list of known features and whether they are supported or not\&. .RE .SH "EXAMPLE" .PP Below is a Makefile fragment which could be used to build an application against an installed neon library, when the \fBneon\-config\fR script can be found in \fB$PATH\fR\&. .sp .if n \{\ .RS 4 .\} .nf CFLAGS = `neon\-config \-\-cflags` LIBS = `neon\-config \-\-libs` OBJECTS = myapp\&.o TARGET = myapp $(TARGET): $(OBJECTS) $(CC) $(LDFLAGS) \-o $(TARGET) $(OBJECTS) $(LIBS) myapp\&.o: myapp\&.c $(CC) $(CFLAGS) \-c myapp\&.c \-o myapp\&.o .fi .if n \{\ .RE .\} .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/man/neon.3000066400000000000000000000212421257152637300202120ustar00rootroot00000000000000'\" t .\" Title: neon .\" Author: .\" Generator: DocBook XSL Stylesheets v1.76.1 .\" Date: 3 May 2011 .\" Manual: neon API reference .\" Source: neon 0.29.6 .\" Language: English .\" .TH "NEON" "3" "3 May 2011" "neon 0.29.6" "neon API reference" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" neon \- HTTP and WebDAV client library .SH "DESCRIPTION" .PP neon is an HTTP and WebDAV client library\&. The major abstractions exposed are the HTTP \fIsession\fR, created by ne_session_create; and the HTTP \fIrequest\fR, created by ne_request_create\&. HTTP authentication is handled transparently for server and proxy servers, see ne_set_server_auth; complete SSL/TLS support is also included, see ne_ssl_set_verify\&. .SH "CONVENTIONS" .PP Some conventions are used throughout the neon API, to provide a consistent and simple interface; these are documented below\&. .SS "Thread\-safeness and global initialization" .PP neon itself is implemented to be thread\-safe (avoiding any use of global state), but relies on the operating system providing a thread\-safe resolver interface\&. Modern operating systems offer the thread\-safe \fBgetaddrinfo\fR interface, which neon supports; some others implement \fBgethostbyname\fR using thread\-local storage\&. .PP To allow thread\-safe use of SSL in the OpenSSL and GnuTLS libraries neon must be configured using the \-\-enable\-threadsafe\-ssl; if this is done, locking callbacks will be registered by ne_sock_init; note that care must be exercised if neon is used in conjunction with another library which uses OpenSSL or GnuTLS\&. .PP Some platforms and libraries used by neon require global initialization before use; notably: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} The SIGPIPE signal disposition must be set to \fIignored\fR or otherwise handled to avoid process termination when writing to a socket which has been shutdown by the peer\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} OpenSSL and GnuTLS require global initialization to load shared lookup tables\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} The Win32 socket library requires initialization before use\&. .RE .sp The ne_sock_init function should be called before any other use of neon to perform any necessary initialization needed for the particular platform\&. Applications wishing to perform all the necessary process\-global initialization steps themselves may omit to call ne_sock_init (and ne_sock_exit); neon neither checks whether these functions are called nor calls them itself\&. .PP For some applications and configurations it may be necessary to call ne_i18n_init to initialize the support for internationalization in neon\&. .SS "Asynchronous signal safety" .PP No function in neon is defined to be \(lqasync\-signal safe\(rq \- that is, no function is safe to call from a signal handler\&. Any call into the neon library from a signal handler will have undefined behaviour \- in other words, it may crash the process\&. .SS "Functions using global state" .PP Any function in neon may modify the errno global variable as a side\-effect\&. Except where explicitly documented, the value of errno is unspecified after any neon function call\&. .PP Other than in the use of errno, the only functions which use or modify process\-global state in neon are as follows: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} ne_sock_init, ne_i18n_init, and ne_sock_exit, as described above .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fBne_debug_init\fR and \fBne_debug\fR, if enabled at compile time; for debugging output .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} ne_oom_callback for installing a process\-global callback to be invoked on \fBmalloc\fR failure .RE .SS "Namespaces" .PP To avoid possible collisions between names used for symbols and preprocessor macros by an application and the libraries it uses, it is good practice for each library to reserve a particular \fInamespace prefix\fR\&. An application which ensures it uses no names with these prefixes is then guaranteed to avoid such collisions\&. .PP The neon library reserves the use of the namespace prefixes ne_ and NE_\&. The libraries used by neon may also reserve certain namespaces; collisions between these libraries and a neon\-based application will not be detected at compile time, since the underlying library interfaces are not exposed through the neon header files\&. Such collisions can only be detected at link time, when the linker attempts to resolve symbols\&. The following list documents some of the namespaces claimed by libraries used by neon; this list may be incomplete\&. .PP SSL, ssl, TLS, tls, ERR_, BIO_, d2i_, i2d_, ASN1_ .RS 4 Some of the many prefixes used by the OpenSSL library; little attempt has been made to keep exported symbols within any particular prefixes for this library\&. .RE .PP gnutls_, gcry_, gpg_ .RS 4 Namespaces used by the GnuTLS library (and dependencies thereof) .RE .PP XML_, Xml[A\-Z] .RS 4 Namespaces used by the expat library\&. .RE .PP xml[A\-Z], html[A\-Z], docb[A\-Z] .RS 4 Namespaces used by the libxml2 library; a relatively small number of symbols are used without these prefixes\&. .RE .PP inflate, deflate, crc32, compress, uncompres, adler32, zlib .RS 4 Namespaces used by the zlib library; a relatively small number of symbols are used without these prefixes\&. .RE .PP krb5, gss, GSS, asn1, decode_krb5, encode_krb5, profile, mit .RS 4 Some of the prefixes used by the MIT GSSAPI library and dependencies thereof; a number of symbols lie outside these prefixes\&. .RE .PP pakchois_ .RS 4 Namespace used by the pakchois library\&. .RE .PP px_ .RS 4 Namespace used by the libproxy library\&. .RE .SS "Argument validation" .PP neon does not attempt to validate that the parameters passed to functions conform to the API (for instance, checking that pointer arguments are not NULL)\&. Any use of the neon API which is not documented to produce a certain behaviour results is said to produce \fIundefined behaviour\fR; it is likely that neon will segfault under these conditions\&. .SS "URI paths, WebDAV metadata" .PP The path strings passed to any function must be \fIURI\-encoded\fR by the application; neon never performs any URI encoding or decoding internally\&. WebDAV property names and values must be valid UTF\-8 encoded Unicode strings\&. .SS "User interaction" .PP As a pure library interface, neon will never produce output on \fBstdout\fR or \fBstderr\fR; all user interaction is the responsibilty of the application\&. .SS "Memory handling" .PP neon does not attempt to cope gracefully with an out\-of\-memory situation; instead, by default, the \fBabort\fR function is called to immediately terminate the process\&. An application may register a custom function which will be called before \fBabort\fR in such a situation; see ne_oom_callback\&. .SS "Callbacks and userdata" .PP Whenever a callback is registered, a userdata pointer is also used to allow the application to associate a context with the callback\&. The userdata is of type \fBvoid *\fR, allowing any pointer to be used\&. .SS "Large File Support" .PP Since version 0\&.27\&.0, neon transparently uses the "LFS transitional" interfaces in places where file\-backed file descriptors are manipulated\&. This means files larger than 2GiB can be handled on platforms with a native 32\-bit off_t type, where LFS support is available\&. .PP Some interfaces use the ne_off_t type, which is defined to be either off_t or off64_t according to whether LFS support is detected at build time\&. neon does not use or require the \-D_FILE_OFFSET_BITS=64 macro definition\&. .SH "SEE ALSO" .PP ne_session_create(3), ne_oom_callback .SH "AUTHOR" .PP \fBJoe Orton\fR <\&neon@lists.manyfish.co.uk\&> .RS 4 Author. .RE .SH "COPYRIGHT" .br davix-R_0_5_0/deps/libneon/doc/manual.css000066400000000000000000000020631257152637300204030ustar00rootroot00000000000000 p, pre.funcsynopsisinfo { margin-left: 0.4em; margin-right: 0.4em; } span.term { margin-left: 0.6em; margin-bottom: 0.0em } div.legalnotice { font-size: 80%; margin-left: 2em; } a:visited { color: darkgreen; } div.navheader { border-top: 1px solid #bbf2bb; } div.navfooter { border-bottom: 1px solid #bbf2bb; } div.funcprototype { margin-top: 0.2em; margin-left: 0.4em; margin-bottom: 0.2em; } pre.programlisting, pre.screen { background-color: #dddddd; margin-left: 0.6em; margin-right: 1em; padding: 0.3em; width: 50em; } div.funcsynopsis, div.cmdsynopsis { background-color: #dddddd; margin-left: 0.4em; margin-right: 0.4em; padding: 0.1em; } div.warning { border: 1px solid #777777; } h1.title { border-bottom: thick solid #bbf2bb; padding-bottom: 0.1em; } div.toc { border-left: thick solid #bbf2bb; padding-left: 0.5em; } h2, h3 { padding-left: 0.2em; padding-top: -0.1em; } h2 { background-color: #bbf2bb; font-size: 110%; padding-bottom: 0.3em; padding-top: 0.2em; spacing-top: 0.1em; } h3 { border-bottom: 1px solid #bbf2bb; } davix-R_0_5_0/deps/libneon/doc/manual.xml000066400000000000000000000155131257152637300204170ustar00rootroot00000000000000 %isoent; %isopub; NULL"> NUL"> start-element"> character-data"> end-element"> ]> neon HTTP/WebDAV client library JoeOrton neon@lists.manyfish.co.uk 2001-2008Joe Orton This document is free documentation; 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 document 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. Introduction This chapter provides an introduction to neon, giving an overview of the range of features offered, and some general guidelines for using the neon API. neon aims to provide a modern, flexible, and simple API in the C programming language for implementing HTTP and WebDAV support. The WebDAV functionality is entirely separate from the basic HTTP functionality; neon can be used simply as an HTTP client library, ignoring the WebDAV support if desired. §ion.features; §ion.using; §ion.security; The &neon; C language interface The documentation for the &neon; interface is split between this chapter, which gives a broad introduction to the abstractions exposed by the library, and , which gives a function-by-function breakdown of the interface. §ion.xml; neon API reference &date; neon &version; neon API reference &refneon; &refconfig; &refresolve; &refbuf; &refbufapp; &refbufutil; &refbufcr; &refbufdest; &referr; &refgetst; &reffeat; &refi18n; &refiaddr; &refalloc; &refsess; &refsessflags; &refreq; &refreqhdr; &refresphdr; &refopts; &refreqflags; &refreqbody; &refauth; &refshave; &refinit; &refsslcert; &refsslcert2; &refsslcertio; &refssldname; &refssltrust; &refsslvfy; &refclicert; &refstatus; &reftok; &refvers; &refxml; &biblio; davix-R_0_5_0/deps/libneon/doc/parsing-xml.txt000066400000000000000000000127371257152637300214270ustar00rootroot00000000000000 Requirements for XML parsing in neon ------------------------------------ Before describing the interface given in neon for parsing XML, here are the requirements which it must satisfy: 1. to support using either libxml or expat as the underlying parser 2. to allow "independent" sections to handle parsing one XML document 3. to map element namespaces/names to an integer for easier comparison. A description of requirement (2) is useful since it is the "hard" requirement, and adds most of the complexity of interface: WebDAV PROPFIND responses are made up of a large boilerplate XML ... etc. neon should handle the parsing of these standard elements, and expose the meaning of the response using a convenient interface. But, within the elements, there may also be fragments of XML: neon can never know how to parse these, since they are property- and hence application-specific. The simplest example of this is the DAV:resourcetype property. So there is requirement (2) that two "independent" sections of code can handle the parsing of one XML document. Callback-based XML parsing -------------------------- There are two ways of parsing XML documents commonly used: 1. Build an in-memory tree of the document 2. Use callbacks Where practical, using callbacks is more efficient than building a tree, so this is what neon uses. The standard interface for callback-based XML parsing is called SAX, so understanding the SAX interface is useful to understanding the XML parsing interface provided by neon. The SAX interface works by registering callbacks which are called *as the XML is parsed*. The most important callbacks are for 'start element' and 'end element'. For instance, if the XML document below is parsed by a SAX-like interface: Say we have registered callbacks "startelm" for 'start element' and "endelm" for 'end element'. Simplified somewhat, the callbacks will be called in this order, with these arguments: 1. startelm("hello") 2. startelm("foobar") 3. endelm("foobar") 4. endelm("hello") See the expat 'xmlparse.h' header for a more complete definition of a SAX-like interface. The hip_xml interface --------------------- The hip_xml interface satisfies requirement (2) by introducing the "handler" concept. A handler is made up of these things: - a set of XML elements - a callback to validate an element - a callback which is called when an element is opened - a callback which is called when an element is closed - (optionally, a callback which is called for CDATA) Registering a handler essentially says: "If you encounter any of this set of elements, I want these callbacks to be called." Handlers are kept in a STACK inside hip_xml. The first handler registered becomes the BASE of the stack, subsequent handlers are PUSHed on top. During XML parsing, the handler which is used for an XML element is recorded. When a new element is started, the search for a handler for this element begins at the handler used for the parent element, and carries on up the stack. For the root element, the search always starts at the BASE of the stack. A user's guide to hip_xml ------------------------- The first thing to do when using hip_xml is to know what set of XML elements you are going to be parsing. This can usually be done by looking at the DTD provided for the documents you are going to be parsing. The DTD is also very useful in writing the 'validate' callback function, since it can tell you what parent/child pairs are valid, and which aren't. In this example, we'll parse XML documents which look like: foo bar So, given the set of elements, declare the element id's and the element array: #define ELM_listofthings (HIP_ELM_UNUSED) #define ELM_a_thing (HIP_ELM_UNUSED + 1) const static struct my_elms[] = { { "http://things.org/", "list-of-things", ELM_listofthings, 0 }, { "http://things.org/", "a-thing", ELM_a_thing, HIP_XML_CDATA }, { NULL } }; This declares we know about two elements: list-of-things, and a-thing, and that the 'a-thing' element contains character data. The definition of the validation callback is very simple: static int validate(hip_xml_elmid parent, hip_xml_elmid child) { /* Only allow 'list-of-things' as the root element. */ if (parent == HIP_ELM_root && child == ELM_listofthings || parent = ELM_listofthings && child == ELM_a_thing) { return HIP_XML_VALID; } else { return HIP_XML_INVALID; } } For this example, we can ignore the start-element callback, and just use the end-element callback: static int endelm(void *userdata, const struct hip_xml_elm *s, const char *cdata) { printf("Got a thing: %s\n", cdata); return 0; } This endelm callback just prints the cdata which was contained in the "a-thing" element. Now, on to parsing. A new parser object is created for parsing each XML document. Creating a new parser object is as simple as: hip_xml_parser *parser; parser = hip_xml_create(); Next register the handler, passing NULL as the start-element callback, and also as userdata, which we don't use here. hip_xml_push_handler(parser, my_elms, validate, NULL, endelm, NULL); Finally, call hip_xml_parse, passing the chunks of XML document to the hip_xml as you get them. The output should be: Got a thing: foo Got a thing: bar for the XML document. davix-R_0_5_0/deps/libneon/doc/ref/000077500000000000000000000000001257152637300171675ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/doc/ref/alloc.xml000066400000000000000000000053101257152637300210020ustar00rootroot00000000000000 ne_malloc 3 ne_malloc ne_calloc ne_realloc ne_strdup ne_strndup ne_oom_callback memory allocation wrappers #include <ne_alloc.h> void *ne_malloc size_t size void *ne_calloc size_t size void *ne_realloc void *size size_t len char *ne_strdup const char *s char *ne_strndup const char *s size_t size void ne_oom_callback void (*callback)(void) Description The functions ne_malloc, ne_calloc, ne_realloc, ne_strdup and ne_strdnup provide wrappers for the equivalent functions in the standard C library. The wrappers provide the extra guarantee that if the C library equivalent returns &null; when no memory is available, an optional callback will be called, and the library will then call abort(). ne_oom_callback registers a callback which will be invoked if an out of memory error is detected. Notes If the operating system uses optimistic memory allocation, the C library memory allocation routines will not return &null;, so it is not possible to gracefully handle memory allocation failures. davix-R_0_5_0/deps/libneon/doc/ref/auth.xml000066400000000000000000000073231257152637300206570ustar00rootroot00000000000000 ne_set_server_auth 3 ne_set_server_auth ne_set_proxy_auth ne_forget_auth register authentication callbacks #include <ne_auth.h> typedef int (*ne_auth_creds) void *userdata const char *realm int attempt char *username char *password void ne_set_server_auth ne_session *session ne_auth_creds callback void *userdata void ne_set_proxy_auth ne_session *session ne_auth_creds callback void *userdata void ne_forget_auth ne_session *session Description The ne_auth_creds function type defines a callback which is invoked when a server or proxy server requires user authentication for a particular request. The realm string is supplied by the server. The attempt is a counter giving the number of times the request has been retried with different authentication credentials. The first time the callback is invoked for a particular request, attempt will be zero. To retry the request using new authentication credentials, the callback should return zero, and the username and password buffers must contain &nul;-terminated strings. The NE_ABUFSIZ constant gives the size of these buffers. If you only wish to allow the user one attempt to enter credentials, use the value of the attempt parameter as the return value of the callback. To abort the request, the callback should return a non-zero value; in which case the contents of the username and password buffers are ignored. The ne_forget_auth function can be used to discard the cached authentication credentials. Examples /* Function which prompts for a line of user input: */ extern char *prompt_for(const char *prompt); static int my_auth(void *userdata, const char *realm, int attempts, char *username, char *password) { strncpy(username, prompt_for("Username: "), NE_ABUFSIZ); strncpy(password, prompt_for("Password: "), NE_ABUFSIZ); return attempts; } int main(...) { &egsess; ne_set_server_auth(sess, my_auth, NULL); /* ... */ } davix-R_0_5_0/deps/libneon/doc/ref/buf.xml000066400000000000000000000033001257152637300204610ustar00rootroot00000000000000 ne_buffer 3 ne_buffer string buffer handling #include <ne_string.h> typedef struct { char *data; size_t used; size_t length; } ne_buffer; Description The ne_buffer type represents an expandable memory buffer for holding &nul;-terminated strings. The data field points to the beginnning of the string, the length of which is given by the used field. The current size of memory allocated is given by the length field. It is not recommended that the fields of a buffer are manipulated directly. The data pointer may change when the buffer is modified. A buffer is created using or , and destroyed using or . The functions , and are used to append data to a buffer. If the string referenced by the data pointer is modified directly (rather than using one of the functions listed above), ne_buffer_altered must be called. davix-R_0_5_0/deps/libneon/doc/ref/bufapp.xml000066400000000000000000000056441257152637300211770ustar00rootroot00000000000000 ne_buffer_append 3 ne_buffer_append ne_buffer_zappend ne_buffer_concat append data to a string buffer #include <ne_string.h> void ne_buffer_append ne_buffer *buf const char *string size_t len void ne_buffer_zappend ne_buffer *buf const char *string void ne_buffer_concat ne_buffer *buf const char *str ... Description The ne_buffer_append and ne_buffer_zappend functions append a string to the end of a buffer; extending the buffer as necessary. The len passed to ne_buffer_append specifies the length of the string to append; there must be no &nul; terminator in the first len bytes of the string. ne_buffer_zappend must be passed a &nul;-terminated string. The ne_buffer_concat function takes a variable-length argument list following str; each argument must be a char * pointer to a &nul;-terminated string. A &null; pointer must be given as the last argument to mark the end of the list. The strings (including str) are appended to the buffer in the order given. None of the strings passed to ne_buffer_concat are modified. Examples The following code will output "Hello, world. And goodbye.". ne_buffer *buf = ne_buffer_create(); ne_buffer_zappend(buf, "Hello"); ne_buffer_concat(buf, ", world. ", "And ", "goodbye.", NULL); puts(buf->data); ne_buffer_destroy(buf); See also , , davix-R_0_5_0/deps/libneon/doc/ref/bufcr.xml000066400000000000000000000027551257152637300210230ustar00rootroot00000000000000 ne_buffer_create 3 ne_buffer_create ne_buffer_ncreate create a string buffer #include <ne_alloc.h> ne_buffer *ne_buffer_create ne_buffer *ne_buffer_ncreate size_t size Description ne_buffer_create creates a new buffer object, with an implementation-defined initial size. ne_buffer_ncreate creates an ne_buffer where the minimum initial size is given in the size parameter. The buffer created will contain the empty string (""). Return value Both functions return a pointer to a new buffer object, and never &null;. See also davix-R_0_5_0/deps/libneon/doc/ref/bufdest.xml000066400000000000000000000042211257152637300213440ustar00rootroot00000000000000 ne_buffer_destroy 3 ne_buffer_destroy ne_buffer_finish destroy a buffer object #include <ne_string.h> void ne_buffer_destroy ne_buffer *buf char *ne_buffer_finish ne_buffer *buf Description ne_buffer_destroy frees all memory associated with the buffer. ne_buffer_finish frees the buffer structure, but not the actual string stored in the buffer, which is returned and must be free()d by the caller. Any use of the buffer object after calling either of these functions gives undefined behaviour. Return value ne_buffer_finish returns the malloc-allocated string stored in the buffer. Examples An example use of ne_buffer_finish; the duplicate function returns a string made up of n copies of str: static char *duplicate(int n, const char *str) { ne_buffer *buf = ne_buffer_create(); while (n--) { ne_buffer_zappend(buf, str); } return ne_buffer_finish(buf); } See also , , davix-R_0_5_0/deps/libneon/doc/ref/bufutil.xml000066400000000000000000000037061257152637300213710ustar00rootroot00000000000000 ne_buffer_clear 3 ne_buffer_clear ne_buffer_grow ne_buffer_altered clear, grow, or mark as altered a string buffer #include <ne_string.h> void ne_buffer_clear ne_buffer *buf void ne_buffer_altered ne_buffer *buf void ne_buffer_grow ne_buffer *buf size_t size Description The ne_buffer_clear function sets the string stored in buf to be the empty string (""). The ne_buffer_altered function must be used after the string stored in the buffer buf is modified by directly rather than using , or . The ne_buffer_grow function ensures that at least size bytes are allocated for the string; this can be used if a large amount of data is going to be appended to the buffer and may result in more efficient memory allocation. davix-R_0_5_0/deps/libneon/doc/ref/clicert.xml000066400000000000000000000130401257152637300213340ustar00rootroot00000000000000 ne_ssl_client_cert 3 ne_ssl_clicert_read ne_ssl_clicert_name ne_ssl_clicert_encrypted ne_ssl_clicert_decrypt ne_ssl_clicert_owner ne_ssl_clicert_free SSL client certificate handling #include <ne_ssl.h> ne_ssl_client_cert *ne_ssl_clicert_read const char *filename const char *ne_ssl_clicert_name const ne_ssl_client_cert *ccert int ne_ssl_clicert_encrypted const ne_ssl_client_cert *ccert int ne_ssl_clicert_decrypt ne_ssl_client_cert *ccert const char *password const ne_ssl_certificate *ne_ssl_clicert_owner const ne_ssl_client_cert *ccert void ne_ssl_clicert_free ne_ssl_client_cert *ccert Description The ne_ssl_clicert_read function reads a client certificate from a PKCS#12-formatted file, and returns an ne_ssl_client_cert object. If the client certificate is encrypted, it must be decrypted before it is used. An ne_ssl_client_cert object holds a client certificate and the associated private key, not just a certificate; the term "client certificate" will used to refer to this pair. A client certificate can be in one of two states: encrypted or decrypted. The ne_ssl_clicert_encrypted function will return non-zero if the client certificate is in the encrypted state. A client certificate object returned by ne_ssl_clicert_read may be initially in either state, depending on whether the file was encrypted or not. ne_ssl_clicert_decrypt can be used to decrypt a client certificate using the appropriate password. This function must only be called if the object is in the encrypted state; if decryption fails, the certificate state does not change, so decryption can be attempted more than once using different passwords. A client certificate can be given a "friendly name" when it is created; ne_ssl_clicert_name will return this name (or &null; if no friendly name was specified). ne_ssl_clicert_name can be used when the client certificate is in either the encrypted or decrypted state, and will return the same string for the lifetime of the object. The function ne_ssl_clicert_owner returns the certificate part of the client certificate; it must only be called if the client certificate is in the decrypted state. When the client certificate is no longer needed, the ne_ssl_clicert_free function should be used to destroy the object. Return value ne_ssl_clicert_read returns a client certificate object, or &null; if the file could not be read. ne_ssl_clicert_encrypted returns zero if the object is in the decrypted state, or non-zero if it is in the encrypted state. ne_ssl_clicert_name returns a &nul;-terminated friendly name string, or &null;. ne_ssl_clicert_owner returns a certificate object. Examples The following code reads a client certificate and decrypts it if necessary, then loads it into an HTTP session. ne_ssl_client_cert *ccert; ccert = ne_ssl_clicert_read("/path/to/client.p12"); if (ccert == NULL) { /* handle error... */ } else if (ne_ssl_clicert_encrypted(ccert)) { char *password = prompt_for_password(); if (ne_ssl_clicert_decrypt(ccert, password)) { /* could not decrypt! handle error... */ } } ne_ssl_set_clicert(sess, ccert); See also davix-R_0_5_0/deps/libneon/doc/ref/config.xml000066400000000000000000000073071257152637300211650ustar00rootroot00000000000000 neon neon-config 1 neon-config script providing information about installed copy of neon library neon-config feature Description The neon-config script provides information about an installed copy of the neon library. The and options instruct how to compile and link an application against the library; the and options can help determine whether the library meets the applications requirements. Options Print the flags which should be passed to the C compiler when compiling object files, when the object files use neon header files. Print the flags which should be passed to the linker when linking an application which uses the neon library Print the location of the libtool library script, libneon.la, which can be used to link against &neon; by applications using libtool. Print the version of the library dir If dir is given; relocate output of and as if neon was installed in given prefix directory. Otherwise, print the installation prefix of the library. feature The script exits with success if feature is supported by the library. Print help message; includes list of known features and whether they are supported or not. Example Below is a Makefile fragment which could be used to build an application against an installed neon library, when the neon-config script can be found in $PATH. CFLAGS = `neon-config --cflags` LIBS = `neon-config --libs` OBJECTS = myapp.o TARGET = myapp $(TARGET): $(OBJECTS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) myapp.o: myapp.c $(CC) $(CFLAGS) -c myapp.c -o myapp.o davix-R_0_5_0/deps/libneon/doc/ref/err.xml000066400000000000000000000047111257152637300205040ustar00rootroot00000000000000 ne_get_error 3 ne_get_error ne_set_error error handling for HTTP sessions #include <ne_session.h> const char *ne_get_error ne_sesssion *session void ne_set_error ne_sesssion *session const char *format ... Description The session error string is used to store any human-readable error information associated with any errors which occur whilst using the HTTP session. The ne_get_error function returns the current session error string. This string persists only until it is changed by a subsequent operation on the session. If localisation was enabled at build time, and if necessary enabled at run-time if necessary using , the returned string may have been translated into the user's current locale. The ne_set_error function can be used to set a new session error string, using a printf-style format string interface. Return value ne_set_error returns a constant &nul;-terminated string. In the default English locale, the returned string will not have a terminating . period character. Examples Retrieve the current error string: &egsess; ... printf("Error was: %s\n", ne_get_error(sess)); Set a new error string: &egsess; ... ne_set_error(sess, "Response missing header %s", "somestring"); davix-R_0_5_0/deps/libneon/doc/ref/feat.xml000066400000000000000000000050501257152637300206300ustar00rootroot00000000000000 ne_has_support 3 ne_has_support determine feature support status #include <ne_utils.h> int ne_has_support int feature Description The ne_has_support function can be used to determine whether a particular optional feature, given by the feature code feature, is supported. The following feature codes are available: NE_FEATURE_SSL Indicates support for SSL/TLS NE_FEATURE_ZLIB Indicates support for compressed responses NE_FEATURE_IPV6 Indicates support for IPv6 NE_FEATURE_LFS Indicates support for large files NE_FEATURE_SOCKS Indicates support for SOCKSv5 NE_FEATURE_TS_SSL Indicates support for thread-safe SSL initialization — see Return value ne_has_support returns non-zero if the given feature is supported, or zero otherwise. See also , davix-R_0_5_0/deps/libneon/doc/ref/getst.xml000066400000000000000000000033161257152637300210420ustar00rootroot00000000000000 ne_get_status 3 ne_get_status retrieve HTTP response status for request #include <ne_request.h> const ne_status *ne_get_status const ne_request *request Description The ne_get_status function returns a pointer to the HTTP status object giving the result of a request. The object returned only becomes valid once the request has been successfully dispatched (the return value of ne_request_dispatch or ne_begin_request was zero). The object remains valid until the associated request object is destroyed. See also , Example Display the response status code of applying the HEAD method to some resource. ne_request *req = ne_request_create(sess, "HEAD", "/foo/bar"); if (ne_request_dispatch(req)) /* handle errors... */ else printf("Response status code was %d\n", ne_get_status(req)->code); ne_request_destroy(req); davix-R_0_5_0/deps/libneon/doc/ref/i18n.xml000066400000000000000000000042741257152637300204770ustar00rootroot00000000000000 ne_i18n_init 3 ne_i18n_init functions to initialize internationalization support #include <ne_i18n.h> void ne_i18n_init const char *encoding Description The ne_i18n_init function can be used to enable support for translated messages in the &neon; library. The encoding parameter, if non-&null;, specifies the character encoding required for generated translated string. If it is &null;, the appropriate character encoding for the process locale will be used. This call is only strictly necessary if either: &neon; has been installed into a different prefix than the gettext implementation on which it depends for i18n purposes, or the caller requires that translated messages are in a particular character encoding. If ne_i18n_init is never called, the message catalogs will not be found if case (a) applies (and so English error messages will be used), and will use the default character encoding specified by the process locale. The library will otherwise operate correctly. Note that the encoding used is a process-global setting and so results may be unexpected if other users of &neon; within the process call ne_i18n_init with a different encoding parameter. See also davix-R_0_5_0/deps/libneon/doc/ref/iaddr.xml000066400000000000000000000147401257152637300210020ustar00rootroot00000000000000 ne_iaddr_make 3 ne_iaddr_make ne_iaddr_cmp ne_iaddr_print ne_iaddr_typeof ne_iaddr_parse ne_iaddr_raw ne_iaddr_reverse ne_iaddr_free functions to manipulate network addresses #include <ne_socket.h> typedef enum { ne_iaddr_ipv4 = 0, ne_iaddr_ipv6 } ne_iaddr_type; ne_inet_addr *ne_iaddr_make ne_iaddr_type type const unsigned char *raw int ne_iaddr_cmp const ne_inet_addr *ia1 const ne_inet_addr *ia2 char *ne_iaddr_print const ne_inet_addr *ia char *buffer size_t bufsiz ne_iaddr_type ne_iaddr_typeof const ne_inet_addr *ia ne_inet_addr *ne_iaddr_parse const char *address ne_iaddr_type type unsigned char *ne_iaddr_raw const ne_inet_addr *ia unsigned char *buffer int ne_iaddr_reverse const ne_inet_addr *ia char *buffer size_t buflen void ne_iaddr_free const ne_inet_addr *ia Description ne_iaddr_make creates an ne_inet_addr object from a raw binary network address; for instance the four bytes 0x7f 0x00 0x00 0x01 represent the IPv4 address 127.0.0.1. The object returned is suitable for passing to ne_sock_connect. A binary IPv4 address contains four bytes; a binary IPv6 address contains sixteen bytes; addresses passed must be in network byte order. ne_iaddr_cmp compares two network address objects; returning zero only if they are identical. The objects need not have the same address type; if the addresses are not of the same type, the return value is guaranteed to be non-zero. ne_iaddr_print prints a human-readable string representation of a network address into a buffer, for instance the string "127.0.0.1". ne_iaddr_typeof returns the type of the given network address object. ne_iaddr_parse parses a string representation of a network address (such as "127.0.0.1" and creates a network address object to represent the parsed address. ne_iaddr_raw writes the raw byte representation of a network address to the provided buffer. The bytes are written in network byte order; the buffer must be of suitable length for the type of address (4 bytes for an IPv4 address, 16 bytes for an IPv6 address). ne_iaddr_reverse performs a reverse name lookup on the address object, writing the (first) hostname associated with the IP address to the provided buffer. If the hostname is longer than the buffer it will be silently truncated; on success the string written to the buffer is always &nul;-terminated. ne_iaddr_free releases the memory associated with a network address object. Return value ne_iaddr_make returns &null; if the address type passed is not supported (for instance on a platform which does not support IPv6). ne_iaddr_print returns the buffer pointer, and never &null;. ne_iaddr_parse returns a network address object on success, or &null; on failure to parse the address parameter. ne_iaddr_reverse returns zero on success or non-zero if no hostname is associated with the address. ne_iaddr_raw returns the buffer parameter, and never &null;. Examples The following example connects a socket to port 80 at the address 127.0.0.1. unsigned char addr[] = "\0x7f\0x00\0x00\0x01"; ne_inet_addr *ia; ia = ne_iaddr_make(ne_iaddr_ipv4, addr); if (ia != NULL) { ne_socket *sock = ne_sock_connect(ia, 80); ne_iaddr_free(ia); /* ... */ } else { /* ... */ } See also davix-R_0_5_0/deps/libneon/doc/ref/init.xml000066400000000000000000000111611257152637300206540ustar00rootroot00000000000000 ne_sock_init 3 ne_sock_init ne_sock_exit perform library initialization #include <ne_socket.h> int ne_sock_init void ne_sock_exit Description In some platforms and configurations, &neon; may be using some socket or SSL libraries which require global initialization before use. To perform this initialization, the ne_sock_init function must be called before any other library functions are used. Once all use of &neon; is complete, ne_sock_exit can be called to perform de-initialization of socket or SSL libraries, if necessary. Uses of ne_sock_init and ne_sock_exit are "reference counted"; if N calls to ne_sock_init are made, only the Nth call to ne_sock_exit will have effect. ne_sock_init will set the disposition of the SIGPIPE signal to ignored. No change is made to the SIGPIPE disposition by ne_sock_exit. Both the SSL libraries supported by &neon; — OpenSSL and GnuTLS — require callbacks to be registered to allow thread-safe use of SSL. These callbacks are stored as global variables and so their state persists for as long as the library in question is loaded into the process. If multiple users of the SSL library exist within the process, this can be problematic, particularly if one is dynamically loaded (and may subsequently be unloaded). If &neon; is configured using the --enable-threadsafe-ssl flag, thread-safe SSL support will be enabled automatically, as covered in the following section. Otherwise, it is not safe to use &neon; with SSL in a multi-threaded process. The function can be used to determine whether &neon; is built to enable thread-safety support in the SSL library. Thread-safe SSL with OpenSSL &neon; follows two simple rules when dealing with the OpenSSL locking callbacks: ne_sock_init will set thread-safety locking callbacks if and only if no locking callbacks are already registered. ne_sock_exit will unset the thread-safety locking callbacks if and only if the locking callbacks registered are those registered by ne_sock_init. Applications and libraries should be able to co-operate to ensure that SSL use is always thread-safe if similar rules are always followed. Thread-safe SSL with GnuTLS The cryptography library used by GnuTLS, libgcrypt, only supports an initialization operation to register thread-safety callbacks. ne_sock_init will register the thread-safe locking callbacks on first use; ne_sock_exit cannot unregister them. If multiple users of GnuTLS are present within the process, it is unsafe to dynamically unload &neon; from the process if &neon; is configured with thread-safe SSL support enabled (since the callbacks would be left pointing at unmapped memory once &neon; is unloaded). Return value ne_sock_init returns zero on success, or non-zero on error. If an error occurs, no further use of the &neon; library should be attempted. See also , davix-R_0_5_0/deps/libneon/doc/ref/neon.xml000066400000000000000000000243151257152637300206550ustar00rootroot00000000000000 neon 3 neon HTTP and WebDAV client library Description neon is an HTTP and WebDAV client library. The major abstractions exposed are the HTTP session, created by ; and the HTTP request, created by . HTTP authentication is handled transparently for server and proxy servers, see ; complete SSL/TLS support is also included, see . Conventions Some conventions are used throughout the neon API, to provide a consistent and simple interface; these are documented below. Thread-safeness and global initialization &neon; itself is implemented to be thread-safe (avoiding any use of global state), but relies on the operating system providing a thread-safe resolver interface. Modern operating systems offer the thread-safe getaddrinfo interface, which &neon; supports; some others implement gethostbyname using thread-local storage. To allow thread-safe use of SSL in the OpenSSL and GnuTLS libraries &neon; must be configured using the --enable-threadsafe-ssl; if this is done, locking callbacks will be registered by ; note that care must be exercised if &neon; is used in conjunction with another library which uses OpenSSL or GnuTLS. Some platforms and libraries used by &neon; require global initialization before use; notably: The SIGPIPE signal disposition must be set to ignored or otherwise handled to avoid process termination when writing to a socket which has been shutdown by the peer. OpenSSL and GnuTLS require global initialization to load shared lookup tables. The Win32 socket library requires initialization before use. The function should be called before any other use of &neon; to perform any necessary initialization needed for the particular platform. Applications wishing to perform all the necessary process-global initialization steps themselves may omit to call (and ); &neon; neither checks whether these functions are called nor calls them itself. For some applications and configurations it may be necessary to call to initialize the support for internationalization in &neon;. Asynchronous signal safety No function in &neon; is defined to be async-signal safe - that is, no function is safe to call from a signal handler. Any call into the &neon; library from a signal handler will have undefined behaviour - in other words, it may crash the process. Functions using global state Any function in &neon; may modify the errno global variable as a side-effect. Except where explicitly documented, the value of errno is unspecified after any &neon; function call. Other than in the use of errno, the only functions which use or modify process-global state in &neon; are as follows: , , and , as described above ne_debug_init and ne_debug, if enabled at compile time; for debugging output for installing a process-global callback to be invoked on malloc failure Namespaces To avoid possible collisions between names used for symbols and preprocessor macros by an application and the libraries it uses, it is good practice for each library to reserve a particular namespace prefix. An application which ensures it uses no names with these prefixes is then guaranteed to avoid such collisions. The &neon; library reserves the use of the namespace prefixes ne_ and NE_. The libraries used by &neon; may also reserve certain namespaces; collisions between these libraries and a &neon;-based application will not be detected at compile time, since the underlying library interfaces are not exposed through the &neon; header files. Such collisions can only be detected at link time, when the linker attempts to resolve symbols. The following list documents some of the namespaces claimed by libraries used by &neon;; this list may be incomplete. SSL, ssl, TLS, tls, ERR_, BIO_, d2i_, i2d_, ASN1_ Some of the many prefixes used by the OpenSSL library; little attempt has been made to keep exported symbols within any particular prefixes for this library. gnutls_, gcry_, gpg_ Namespaces used by the GnuTLS library (and dependencies thereof) XML_, Xml[A-Z] Namespaces used by the expat library. xml[A-Z], html[A-Z], docb[A-Z] Namespaces used by the libxml2 library; a relatively small number of symbols are used without these prefixes. inflate, deflate, crc32, compress, uncompres, adler32, zlib Namespaces used by the zlib library; a relatively small number of symbols are used without these prefixes. krb5, gss, GSS, asn1, decode_krb5, encode_krb5, profile, mit Some of the prefixes used by the MIT GSSAPI library and dependencies thereof; a number of symbols lie outside these prefixes. pakchois_ Namespace used by the pakchois library. px_ Namespace used by the libproxy library. Argument validation &neon; does not attempt to validate that the parameters passed to functions conform to the API (for instance, checking that pointer arguments are not &null;). Any use of the &neon; API which is not documented to produce a certain behaviour results is said to produce undefined behaviour; it is likely that &neon; will segfault under these conditions. URI paths, WebDAV metadata The path strings passed to any function must be URI-encoded by the application; &neon; never performs any URI encoding or decoding internally. WebDAV property names and values must be valid UTF-8 encoded Unicode strings. User interaction As a pure library interface, &neon; will never produce output on stdout or stderr; all user interaction is the responsibilty of the application. Memory handling neon does not attempt to cope gracefully with an out-of-memory situation; instead, by default, the abort function is called to immediately terminate the process. An application may register a custom function which will be called before abort in such a situation; see . Callbacks and userdata Whenever a callback is registered, a userdata pointer is also used to allow the application to associate a context with the callback. The userdata is of type void *, allowing any pointer to be used. Large File Support Since version 0.27.0, &neon; transparently uses the "LFS transitional" interfaces in places where file-backed file descriptors are manipulated. This means files larger than 2GiB can be handled on platforms with a native 32-bit off_t type, where LFS support is available. Some interfaces use the ne_off_t type, which is defined to be either off_t or off64_t according to whether LFS support is detected at build time. &neon; does not use or require the -D_FILE_OFFSET_BITS=64 macro definition. See also , davix-R_0_5_0/deps/libneon/doc/ref/opts.xml000066400000000000000000000100161257152637300206740ustar00rootroot00000000000000 ne_set_useragent 3 ne_set_useragent ne_set_read_timeout ne_set_connect_timeout ne_get_scheme ne_get_server_hostport common properties for HTTP sessions #include <ne_session.h> void ne_set_useragent ne_session *session const char *product void ne_set_read_timeout ne_session *session int timeout void ne_set_connect_timeout ne_session *session int timeout const char *ne_get_scheme ne_sesssion *session const char *ne_get_server_hostport ne_sesssion *session Description The User-Agent request header is used to identify the software which generated the request for statistical or debugging purposes. neon does not send a User-Agent header unless a call is made to the ne_set_useragent. ne_set_useragent must be passed a product string conforming to RFC2616's product token grammar; of the form "Product/Version". When neon reads from a socket, by default the read operation will time out after 60 seconds, and the request will fail giving an NE_TIMEOUT error. To configure this timeout interval, call ne_set_read_timeout giving the desired number of seconds as the timeout parameter. When a connection is being established to a server, normally only the system's TCP timeout handling will apply. To configure a specific (and probably shorter) timeout, the ne_set_connect_timeout can be used, giving the desired number of seconds as the timeout parameter. If 0 is passed, then the default behaviour of using the system TCP timeout will be used. The scheme used to initially create the session will be returned by ne_get_scheme. The hostport pair with which the session is associated will be returned by the ne_get_server_hostport; for example www.example.com:8080. Note that the :port will be omitted if the default port for the scheme is used. Examples Set a user-agent string: &egsess; ne_set_useragent(sess, "MyApplication/2.1"); Set a 30 second read timeout: &egsess; ne_set_read_timeout(sess, 30); See also , . davix-R_0_5_0/deps/libneon/doc/ref/req.xml000066400000000000000000000144321257152637300205040ustar00rootroot00000000000000 ne_request_create 3 ne_request_create ne_request_dispatch ne_request_destroy low-level HTTP request handling #include <ne_request.h> ne_request *ne_request_create ne_session *session const char *method const char *path int ne_request_dispatch ne_request *req void ne_request_destroy ne_request *req Description An HTTP request, represented by the ne_request type, specifies that some operation is to be performed on some resource. The ne_request_create function creates a request object, specifying the operation in the method parameter. The location of the resource is determined by the server in use for the session given by the sess parameter, combined with the path parameter. The path string used must conform to the abs_path definition given in RFC2396, with an optional "?query" part, and must be URI-escaped by the caller (for instance, using ne_path_escape). If the string comes from an untrusted source, failure to perform URI-escaping results in a security vulnerability. To dispatch a request, and process the response, the ne_request_dispatch function can be used. An alternative is to use the (more complex, but more flexible) combination of the ne_begin_request, ne_end_request, and ne_read_response_block functions; see ne_begin_request. To add extra headers in the request, the functions and can be used. To include a message body with the request, one of the functions ne_set_request_body_buffer, , or ne_set_request_body_provider can be used. The return value of ne_request_dispatch indicates merely whether the request was sent and the response read successfully. To discover the result of the operation, , along with any processing of the response headers and message body. A request can only be dispatched once: calling ne_request_dispatch more than once on a single ne_request object produces undefined behaviour. Once all processing associated with the request object is complete, use the ne_request_destroy function to destroy the resources associated with it. Any subsequent use of the request object produces undefined behaviour. If a request is being using a non-idempotent method such as POST, the NE_REQFLAG_IDEMPOTENT flag should be disabled; see . Return value The ne_request_create function returns a pointer to a request object (and never &null;). The ne_request_dispatch function returns zero if the request was dispatched successfully, and a non-zero error code otherwise. Errors NE_ERROR Request failed (see session error string) NE_LOOKUP The DNS lookup for the server (or proxy server) failed. NE_AUTH Authentication failed on the server. NE_PROXYAUTH Authentication failed on the proxy server. NE_CONNECT A connection to the server could not be established. NE_TIMEOUT A timeout occurred while waiting for the server to respond. Example An example of applying a MKCOL operation to the resource at the location http://www.example.com/foo/bar/: ne_session *sess = ne_session_create("http", "www.example.com", 80); ne_request *req = ne_request_create(sess, "MKCOL", "/foo/bar/"); if (ne_request_dispatch(req)) { printf("Request failed: %s\n", ne_get_error(sess)); } ne_request_destroy(req); See also , , , , , . davix-R_0_5_0/deps/libneon/doc/ref/reqbody.xml000066400000000000000000000050711257152637300213610ustar00rootroot00000000000000 ne_set_request_body_buffer 3 ne_set_request_body_buffer ne_set_request_body_fd ne_set_request_body_fd64 include a message body with a request #include <ne_request.h> void ne_set_request_body_buffer ne_request *req const char *buf size_t count int ne_set_request_body_fd ne_request *req int fd off_t begin off_t length Description The ne_set_request_body_buffer function specifies that a message body should be included with the body, which is stored in the count bytes buffer buf. The ne_set_request_body_fd function can be used to include a message body with a request which is read from a file descriptor. The body is read from the file descriptor fd, which must be a associated with a seekable file (not a pipe, socket, or FIFO). count bytes are read, beginning at offset begin (hence, passing begin as zero means the body is read from the beginning of the file). For all the above functions, the source of the request body must survive until the request has been dispatched; neither the memory buffer passed to ne_set_request_body_buffer nor the file descriptor passed to ne_set_request_body_fd are copied internally. See also davix-R_0_5_0/deps/libneon/doc/ref/reqflags.xml000066400000000000000000000052021257152637300215140ustar00rootroot00000000000000 ne_set_request_flag 3 ne_set_request_flag ne_get_request_flag set and retrieve per-request flags #include <ne_request.h> void ne_set_request_flag ne_request *req ne_request_flag flag int value int ne_get_request_flag ne_request *req ne_request_flag flag Description The ne_set_request_flag function enables or disables a per-request flag. Passing a non-zero value argument enables the flag, and zero disables it. The following flags are defined: NE_REQFLAG_EXPECT100 enable this flag to use the "Expect: 100-continue" feature of HTTP/1.1, which allows the server to process request headers without reading the entire request body. This saves time and bandwidth if the server gives an authentication challenge (requiring the request to be resent), but has interoperability problems with some older servers. NE_REQFLAG_IDEMPOTENT disable this flag if the request uses a non-idempotent method such as POST Return value The ne_get_request_flag function returns zero if a flag is disabled, less than zero if the flag is not supported, or greater than zero if the flag is enabled. See also . davix-R_0_5_0/deps/libneon/doc/ref/reqhdr.xml000066400000000000000000000037161257152637300212050ustar00rootroot00000000000000 ne_add_request_header 3 ne_add_request_header ne_print_request_header add headers to a request #include <ne_request.h> void ne_add_request_header ne_request *request const char *name const char *value void ne_print_request_header ne_request *request const char *name const char *format ... Description The functions ne_add_request_header and ne_print_request_header can be used to add headers to a request, before it is sent. ne_add_request_header simply adds a header of given name, with given value. ne_print_request_header adds a header of given name, taking the value from the printf-like format string parameter and subsequent variable-length argument list. See also davix-R_0_5_0/deps/libneon/doc/ref/resolve.xml000066400000000000000000000120611257152637300213700ustar00rootroot00000000000000 ne_addr_resolve 3 ne_addr_resolve ne_addr_result ne_addr_first ne_addr_next ne_addr_error ne_addr_destroy functions to resolve hostnames to addresses #include <ne_socket.h> ne_sock_addr *ne_addr_resolve const char *hostname int flags int ne_addr_result const ne_sock_addr *addr const ne_inet_addr *ne_addr_first ne_sock_addr *addr const ne_inet_addr *ne_addr_next ne_sock_addr *addr char *ne_addr_error const ne_sock_addr *addr char *buffer size_t bufsiz void ne_addr_destroy ne_sock_addr *addr Description The ne_addr_resolve function resolves the given hostname, returning an ne_sock_addr object representing the address (or addresses) associated with the hostname. The flags parameter is currently unused, and must be passed as 0. The hostname passed to ne_addr_resolve can be a DNS hostname (e.g. "www.example.com") or an IPv4 dotted quad (e.g. "192.0.34.72"); or, on systems which support IPv6, an IPv6 hex address, which may be enclosed in brackets, e.g. "[::1]". To determine whether the hostname was successfully resolved, the ne_addr_result function is used, which returns non-zero if an error occurred. If an error did occur, the ne_addr_error function can be used, which will copy the error string into a given buffer (of size bufsiz). The functions ne_addr_first and ne_addr_next are used to retrieve the Internet addresses associated with an address object which has been successfully resolved. ne_addr_first returns the first address; ne_addr_next returns the next address after the most recent call to ne_addr_next or ne_addr_first, or &null; if there are no more addresses. The ne_inet_addr pointer returned by these functions can be passed to ne_sock_connect to connect a socket. After the address object has been used, it should be destroyed using ne_addr_destroy. Return value ne_addr_resolve returns a pointer to an address object, and never &null;. ne_addr_error returns the buffer parameter . Examples The code below prints out the set of addresses associated with the hostname www.google.com. ne_sock_addr *addr; char buf[256]; addr = ne_addr_resolve("www.google.com", 0); if (ne_addr_result(addr)) { printf("Could not resolve www.google.com: %s\n", ne_addr_error(addr, buf, sizeof buf)); } else { const ne_inet_addr *ia; printf("www.google.com:"); for (ia = ne_addr_first(addr); ia != NULL; ia = ne_addr_next(addr)) { printf(" %s", ne_iaddr_print(ia, buf, sizeof buf)); } putchar('\n'); } ne_addr_destroy(addr); See also davix-R_0_5_0/deps/libneon/doc/ref/resphdr.xml000066400000000000000000000064431257152637300213670ustar00rootroot00000000000000 ne_get_response_header 3 ne_get_response_header ne_response_header_iterate functions to access response headers #include <ne_request.h> const char *ne_get_response_header ne_request *request const char *name void *ne_response_header_iterate ne_request *request void *cursor const char **name const char **value Description To retrieve the value of a response header field, the ne_get_response_header function can be used, and is given the name of the header to return. To iterate over all the response headers returned, the ne_response_header_iterate function can be used. This function takes a cursor parameter which should be &null; to retrieve the first header. The function stores the name and value of the next header header in the name and value parameters, and returns a new cursor pointer which can be passed to ne_response_header_iterate to retrieve the next header. Return value ne_get_response_header returns a string, or &null; if no header with that name was given. If used during request processing, the return value pointer is valid only until the next call to ne_begin_request, or else, until the request object is destroyed. Likewise, the cursor, names, and values returned by ne_response_header_iterate are only valid until the next call to ne_begin_request or until the request object is destroyed. Examples The following code will output the value of the Last-Modified header for a resource: ne_request *req = ne_request_create(sess, "GET", "/foo.txt"); if (ne_request_dispatch(req) == NE_OK) { const char *mtime = ne_get_response_header(req, "Last-Modified"); if (mtime) { printf("/foo.txt has last-modified value %s\n", mtime); } } ne_request_destroy(req); See also , . davix-R_0_5_0/deps/libneon/doc/ref/sess.xml000066400000000000000000000112671257152637300206750ustar00rootroot00000000000000 ne_session_create 3 ne_session_create ne_close_connection ne_session_proxy ne_session_destroy set up HTTP sessions #include <ne_session.h> ne_session *ne_session_create const char *scheme const char *hostname unsigned int port void ne_session_proxy ne_session *session const char *hostname unsigned int port void ne_close_connection ne_session *session void ne_session_destroy ne_session *session Description An ne_session object represents an HTTP session - a logical grouping of a sequence of HTTP requests made to a certain server. Any requests made using the session can use a persistent connection, share cached authentication credentials and any other common attributes. A new HTTP session is created using ne_session_create, giving the hostname and port of the server to use, along with the scheme used to contact the server (usually "http"). Before the first use of ne_session_create in a process, must have been called to perform any global initialization needed by any libraries used by &neon;. To enable SSL/TLS for the session, pass the string "https" as the scheme parameter, and either register a certificate verification function (see ) or trust the appropriate certificate (see , ). If an HTTP proxy server should be used for the session, ne_session_proxy must be called giving the hostname and port on which to contact the proxy. Further per-session options may be changed using the interface. If it is known that the session will not be used for a significant period of time, ne_close_connection can be called to close the connection, if one remains open. Use of this function is entirely optional, but it must not be called if there is a request active using the session. Once a session has been completed, ne_session_destroy must be called to destroy the resources associated with the session. Any subsequent use of the session pointer produces undefined behaviour. Notes The hostname passed to ne_session_create is resolved when the first request using the session is dispatched; a DNS resolution failure can only be detected at that time (using the NE_LOOKUP error code); see for details. Return Values ne_session_create will return a pointer to a new session object (and never &null;). Examples Create and destroy a session: ne_session *sess; sess = ne_session_create("http", "host.example.com", 80); /* ... use sess ... */ ne_session_destroy(sess); See Also , , , davix-R_0_5_0/deps/libneon/doc/ref/sessflags.xml000066400000000000000000000072431257152637300217110ustar00rootroot00000000000000 ne_set_session_flag 3 ne_set_session_flag ne_get_session_flag set and retrieve session flags #include <ne_request.h> void ne_set_session_flag ne_session *sess ne_session_flag flag int value int ne_get_session_flag ne_session *sess ne_session_flag flag Description The ne_set_session_flag function enables or disables a session flag. Passing a non-zero value argument enables the flag, and zero disables it. The following flags are defined: NE_SESSFLAG_PERSIST disable this flag to prevent use of persistent connections NE_SESSFLAG_ICYPROTO enable this flag to enable support for non-HTTP ShoutCast-style "ICY" responses NE_SESSFLAG_SSLv2 disable this flag to disable support for the SSLv2 protocol NE_SESSFLAG_RFC4918 enable this flag to enable support for RFC4918-only WebDAV features; losing backwards-compatibility with RFC2518 servers NE_SESSFLAG_CONNAUTH enable this flag if an RFC-violating connection-based HTTP authentication scheme is in use NE_SESSFLAG_TLS_SNI disable this flag if a server is used which does not correctly support the TLS SNI extension NE_SESSFLAG_EXPECT100 enable this flag to enable the request flag NE_REQFLAG_EXPECT100 for new requests Return value The ne_get_session_flag function returns zero if a flag is disabled, less than zero if the flag is not supported, or greater than zero if the flag is enabled. See also , . davix-R_0_5_0/deps/libneon/doc/ref/shave.xml000066400000000000000000000023661257152637300210260ustar00rootroot00000000000000 ne_shave 3 ne_shave trim whitespace from a string #include <ne_string.h> char *ne_shave char *str const char *whitespace Description ne_shave returns a portion of str with any leading or trailing characters in the whitespace array removed. str may be modified. Note that the return value may not be equal to str. Examples The following code segment will output "fish": char s[] = ".!.fish!.!"; puts(ne_shave(s, ".!")); davix-R_0_5_0/deps/libneon/doc/ref/sslca.xml000066400000000000000000000046271257152637300210270ustar00rootroot00000000000000 ne_ssl_load_ca 3 ne_ssl_load_ca ne_ssl_load_default_ca load SSL Certificate Authorities #include <ne_session.h> int ne_ssl_load_ca ne_session *session const char *filename int ne_ssl_load_default_ca ne_session *session Description To indicate that a given CA certificate is trusted by the user, the certificate can be loaded using the ne_ssl_load_ca function. The filename parameter given must specify the location of a PEM-encoded CA certificate. The SSL library in use by neon may include a default set of CA certificates; calling the ne_ssl_load_default_ca function will indicate that these CAs are trusted by the user. If no CA certificates are loaded, or the server presents a certificate which is invalid in some way, then the certificate must be manually verified (see ), otherwise the connection will fail. Return value Both ne_ssl_load_ca and ne_ssl_load_default_ca functions return 0 on success, or non-zero on failure. Examples Load the CA certificate stored in /path/to/cacert.pem: &egsess; if (ne_ssl_load_ca(sess, "/path/to/cacert.pem")) { printf("Could not load CA cert: %s\n", ne_get_error(sess)); } See also , davix-R_0_5_0/deps/libneon/doc/ref/sslcert.xml000066400000000000000000000072301257152637300213720ustar00rootroot00000000000000 ne_ssl_cert_identity 3 ne_ssl_cert_identity ne_ssl_cert_signedby ne_ssl_cert_issuer ne_ssl_cert_subject functions to access certificate properties #include <ne_ssl.h> const char *ne_ssl_cert_identity const ne_ssl_certificate *cert const ne_ssl_certificate *ne_ssl_cert_signedby const ne_ssl_certificate *cert const ne_ssl_dname *ne_ssl_cert_subject const ne_ssl_certificate *cert const ne_ssl_dname *ne_ssl_cert_issuer const ne_ssl_certificate *cert Description The function ne_ssl_cert_identity retrieves the identity of a certificate; for an SSL server certificate, this will be the hostname for which the certificate was issued. In PKI parlance, the identity is the common name attribute of the distinguished name of the certificate subject. The functions ne_ssl_cert_subject and ne_ssl_cert_issuer can be used to access the objects representing the distinguished name of the subject and of the issuer of a certificate, respectively. If a certificate object is part of a certificate chain, then ne_ssl_cert_signedby can be used to find the certificate which signed a particular certificate. For a self-signed certificate or a certificate for which the full chain is not available, this function will return &null;. Return value ne_ssl_cert_issuer and ne_ssl_cert_subject are guaranteed to never return &null;. ne_ssl_cert_identity may return &null; if the certificate has no specific identity. ne_ssl_cert_signedby may return &null; as covered above. Examples The following function could be used to display information about a given certificate: void dump_cert(const ne_ssl_certificate *cert) { const char *id = ne_ssl_cert_identity(cert); char *dn; if (id) printf("Certificate was issued for '%s'.\n", id); dn = ne_ssl_readable_dname(ne_ssl_cert_subject(cert)); printf("Subject: %s\n", dn); free(dn); dn = ne_ssl_readable_dname(ne_ssl_cert_issuer(cert)); printf("Issuer: %s\n", dn); free(dn); } See also , davix-R_0_5_0/deps/libneon/doc/ref/sslcert2.xml000066400000000000000000000026061257152637300214560ustar00rootroot00000000000000 ne_ssl_cert_cmp 3 ne_ssl_cert_cmp ne_ssl_cert_free functions to operate on certificate objects #include <ne_header.h> int ne_ssl_cert_cmp const ne_ssl_certificate *c1 const ne_ssl_certificate *c2 void ne_ssl_cert_free ne_ssl_certificate *cert Description The ne_ssl_cert_cmp function can be used to compare two certificate objects; it returns zero if they refer to the same certificate, and non-zero otherwise. The ne_ssl_cert_free function can be used to destroy a certificate object when it is no longer needed. davix-R_0_5_0/deps/libneon/doc/ref/sslcertio.xml000066400000000000000000000066311257152637300217260ustar00rootroot00000000000000 ne_ssl_cert_read 3 ne_ssl_cert_read ne_ssl_cert_write ne_ssl_cert_import ne_ssl_cert_export functions to read or write certificates to and from files or strings #include <ne_ssl.h> ne_ssl_certificate *ne_ssl_cert_read const char *filename int ne_ssl_cert_write const ne_ssl_certificate *cert const char *filename ne_ssl_certificate *ne_ssl_cert_import const char *data char *ne_ssl_cert_export const ne_ssl_certificate *cert Description The ne_ssl_cert_write function writes a certificate to a file using the PEM encoding. The ne_ssl_cert_export function returns a base64-encoded &nul;-terminated string representing the certificate. This string is malloc-allocated and should be destroyed using free by the caller. The ne_ssl_cert_read function reads a certificate from a PEM-encoded file, and returns a certificate object. The ne_ssl_cert_import function returns a certificate object from a base64-encoded string, data, as returned by ne_ssl_cert_export. The certificate object returned by these functions should be destroyed using after use. Return value ne_ssl_cert_read returns &null; if a certificate could not be read from the file. ne_ssl_cert_write returns non-zero if the certificate could not be written to the file. ne_ssl_cert_export always returns a &nul;-terminated string, and never &null;. ne_ssl_cert_import returns &null; if the string was not a valid base64-encoded certificate. Encoding Formats The string produced by ne_ssl_cert_export is the base64 encoding of the DER representation of the certificate. The file written by ne_ssl_cert_write uses the PEM format: this is the base64 encoding of the DER representation with newlines every 64 characters, and start and end marker lines. davix-R_0_5_0/deps/libneon/doc/ref/ssldname.xml000066400000000000000000000037441257152637300215270ustar00rootroot00000000000000 ne_ssl_dname 3 ne_ssl_readable_dname ne_ssl_dname_cmp SSL distinguished name handling #include <ne_ssl.h> const char *ne_ssl_readable_dname const ne_ssl_dname *dname int ne_ssl_dname_cmp const ne_ssl_dname *dn1 const ne_ssl_dname *dn2 Description The ne_ssl_readable_dname function creates a single-line, human-readable string out of an ne_ssl_dname object. The returned string is malloc()-allocated, and must be free()d by the caller. The ne_ssl_dname_cmp function compares two distinguished names, and returns zero if they are equal, or non-zero otherwise. Return value ne_ssl_readable_dname returns a malloc-allocated string, and never &null;. Examples See for an example use of ne_ssl_readable_dname. See also davix-R_0_5_0/deps/libneon/doc/ref/ssltrust.xml000066400000000000000000000041121257152637300216120ustar00rootroot00000000000000 ne_ssl_trust_cert 3 ne_ssl_trust_cert ne_ssl_trust_default_ca functions to indicate that certificates are trusted #include <ne_session.h> void ne_ssl_trust_cert ne_session *session const ne_ssl_certificate *cert void ne_ssl_trust_default_ca ne_session *session Description To indicate that a given certificate is trusted by the user, the certificate object can be passed to ne_ssl_trust_cert. The certificate object is duplicated internally and can subsequently be destroyed. The SSL library in use by &neon; may include a default set of CA certificates; calling the ne_ssl_trust_default_ca function will indicate that these CAs are trusted by the user. Examples Load the CA certificate stored in /path/to/cacert.pem: &egsess; ne_ssl_certificate *cert = ne_ssl_cert_read("/path/to/cacert.pem"); if (cert) { ne_ssl_trust_cert(sess, cert); ne_ssl_cert_free(cert); } else { printf("Could not load CA cert: %s\n", ne_get_error(sess)); } See also , , davix-R_0_5_0/deps/libneon/doc/ref/sslvfy.xml000066400000000000000000000122631257152637300212430ustar00rootroot00000000000000 ne_ssl_set_verify 3 ne_ssl_set_verify register an SSL certificate verification callback #include <ne_session.h> typedef int ne_ssl_verify_fn void *userdata int failures const ne_ssl_certificate *cert void ne_ssl_set_verify ne_session *session ne_ssl_verify_fn verify_fn void *userdata Description To enable manual SSL certificate verification, a callback can be registered using ne_ssl_set_verify. If such a callback is not registered, when a connection is established to an SSL server which does not present a certificate signed by a trusted CA (see ), or if the certificate presented is invalid in some way, the connection will fail. When the callback is invoked, the failures parameter gives a bitmask indicating in what way the automatic certificate verification failed. The value is equal to the bit-wise OR of one or more of the following constants (and is guaranteed to be non-zero): NE_SSL_NOTYETVALID The certificate is not yet valid. NE_SSL_EXPIRED The certificate has expired. NE_SSL_IDMISMATCH The hostname used for the session does not match the hostname to which the certificate was issued. NE_SSL_UNTRUSTED The Certificate Authority which signed the certificate is not trusted. Note that if either of the NE_SSL_IDMISMATCH or NE_SSL_UNTRUSTED failures is given, the connection may have been intercepted by a third party, and must not be presumed to be secure. The cert parameter passed to the callback represents the certificate which was presented by the server. If the server presented a chain of certificates, the chain can be accessed using . The cert object given is not valid after the callback returns. Return value The verification callback must return zero to indicate that the certificate should be trusted; and non-zero otherwise (in which case, the connection will fail). Examples The following code implements an example verification callback, using the dump_cert function from to display certification information. Notice that the hostname of the server used for the session is passed as the userdata parameter to the callback. static int my_verify(void *userdata, int failures, const ne_ssl_certificate *cert) { const char *hostname = userdata; dump_cert(cert); puts("Certificate verification failed - the connection may have been " "intercepted by a third party!"); if (failures & NE_SSL_IDMISMATCH) { const char *id = ne_ssl_cert_identity(cert); if (id) printf("Server certificate was issued to '%s' not '%s'.\n", id, hostname); else printf("The certificate was not issued for '%s'\n", hostname); } if (failures & NE_SSL_UNTRUSTED) puts("The certificate is not signed by a trusted Certificate Authority."); /* ... check for validity failures ... */ if (prompt_user()) return 1; /* fail verification */ else return 0; /* trust the certificate anyway */ } int main(...) { ne_session *sess = ne_session_create("https", "some.host.name", 443); ne_ssl_set_verify(sess, my_verify, "some.host.name"); ... } See also , , davix-R_0_5_0/deps/libneon/doc/ref/status.xml000066400000000000000000000044721257152637300212430ustar00rootroot00000000000000 ne_status 3 ne_status HTTP status structure #include <ne_utils.h> typedef struct { int major_version, minor_version; int code, klass; const char *reason_phrase; } ne_status; Description An ne_status type represents an HTTP response status; used in response messages giving a result of request. The major_version and minor_version fields give the HTTP version supported by the server issuing the response. The code field gives the status code of the result (lying between 100 and 999 inclusive), and the klass field gives the classthe field is named klass not class so that the header can be used from a C++ program, in which class is a reserved word), which is equal to the most significant digit of the status. There are five classes of HTTP status code defined by RFC2616: 1xx Informational response. 2xx Success: the operation was successful 3xx Redirection 4xx Client error: the request made was incorrect in some manner. 5xx Server error See also . davix-R_0_5_0/deps/libneon/doc/ref/tok.xml000066400000000000000000000043211257152637300205060ustar00rootroot00000000000000 ne_token 3 ne_token ne_qtoken string tokenizers #include <ne_string.h> char *ne_token char **str char sep char *ne_qtoken char **str char sep const char *quotes Description ne_token and ne_qtoken tokenize the string at the location stored in the pointer str. Each time the function is called, it returns the next token, and modifies the str pointer to point to the remainer of the string, or &null; if there are no more tokens in the string. A token is delimited by the separator character sep; if ne_qtoken is used any quoted segments of the string are skipped when searching for a separator. A quoted segment is enclosed in a pair of one of the characters given in the quotes string. The string being tokenized is modified each time the tokenizing function is called; replacing the next separator character with a &nul; terminator. Examples The following function prints out each token in a comma-separated string list, which is modified in-place: static void splitter(char *list) { do { printf("Token: %s\n", ne_token(&list, ',')); while (list); } davix-R_0_5_0/deps/libneon/doc/ref/vers.xml000066400000000000000000000032521257152637300206720ustar00rootroot00000000000000 ne_version_match 3 ne_version_match ne_version_string library versioning #include <ne_utils.h> int ne_version_match int major int minor const char *ne_version_string Description The ne_version_match function returns non-zero if the library version is not of major version major, or the minor version is less than minor. For &neon; versions 0.x, every minor version is assumed to be incompatible with every other minor version. The ne_version_string function returns a string giving the library version. Examples To require &neon; 1.x, version 1.2 or later: if (ne_version_match(1, 2)) { printf("Library version out of date: 1.2 required, found %s.", ne_version_string()); exit(1); } davix-R_0_5_0/deps/libneon/doc/ref/xml.xml000066400000000000000000000024471257152637300205200ustar00rootroot00000000000000 ne_xml_create 3 ne_xml_create ne_xml_destroy create and destroy an XML parser #include <ne_xml.h> ne_xml_parser *ne_xml_create void ne_xml_destroy ne_xml_parser *parser Description The ne_xml_create function creates an XML parser object, which can be used for parsing XML documents using stacked SAX handlers. Return value ne_xml_create returns a pointer to an XML parser object, and never &null; See also XXX davix-R_0_5_0/deps/libneon/doc/refentry.xml000066400000000000000000000020301257152637300207660ustar00rootroot00000000000000 ne_foo 3 ne_foo ne_bar functions which do foo and bar #include <ne_header.h> void ne_set_useragent ne_session *session const char *product Description XXX Return value XXX Examples XXX See also XXX davix-R_0_5_0/deps/libneon/doc/security.xml000066400000000000000000000117261257152637300210130ustar00rootroot00000000000000 HTTP Client Security &neon; is intended to be secure against a specific threat model: use of a malicious HTTP server. Under this threat model, a range of attacks are possible against a client when the user (or application) can be tricked into accessing an HTTP server which is controlled by an attacker. This section documents various types of possible attack and describes what mitigation is used in &neon;. CPU or memory consumption attacks &neon; uses fixed resource limits to prevent the following attacks: memory/CPU consumption attack using an unbounded number of response header fields memory consumption attack using an unbounded length of individual response header lines (or continuation headers) memory consumption attack against the PROPFIND code using an unbounded number of properties (propstat elements) per resource memory consumption attack against the PROPFIND code using an unbounded CDATA element in a "flat property" value Memory consumption attacks against applications based on &neon; by use of unbounded response length are also possible, but must be mitigated at application level. Memory consumption in &neon; itself is fixed and is not proportional to the response size. Test cases for all the above attacks are present in the &neon; test suite. SSL/TLS connection security When using a connection secured by SSL/TLS, it is necessary for clients to verify that the X.509 certificate presented by the server matches the server's expected identity. The algorithm required for this purpose is described in RFC 2818 and RFC 3280, and is implemented by &neon; in the following manner: the hostname argument passed to is the expected identity of the server the subjectAltName extension of the certificate is used for comparision against the expected identity, in preference to the Subject name's commonName attribute. the dNSName, iPAddress, and uniformResourceIdentifier classes of GeneralName are supported in subjectAltName comparison. if no subjectAltName is present in the certificate, the most specific commonName attribute in the Subject name is used for comparison instead. In the case where a server certificate is presented that does not match the expected identity (or is otherwise not trusted), &neon; will fail the request by default. This behaviour can be overridden by the use of a callback installed using , which allows the application to present the certificate details to a user for manual/off-line verification, if possible. Test cases for the correctness of the implementation of the identity verification algorithm are present in the &neon; test suite. Control character insertion in error messages Where error messages (as returned by () contain data supplied by the server, the untrusted data is sanitised to remove both control characters and non-ASCII characters. This prevents any attacks where such error messages are exposed to the user and can potentially distort the presentation of the interface (for example, through the use of a carriage return character in a text user interface). Attacks against authentication credentials Authentication credentials can be compromised by a "downgrade attack" by an active attacker; for example, where a MITM presents a Basic authentication challenge in place of the server's Digest challenge. &neon; mitigates these attacks by allowing the application (and hence, user) to specify that only a specific set of authentication protocols is permitted. &neon; supports the Digest and Negotiate authentication schemes, which both allow authentication of users without passing credentials in cleartext over the wire. The "domain" parameter is supported in Digest, allowing the server to restrict an authentication session to a particular set of URIs. davix-R_0_5_0/deps/libneon/doc/ssl.xml000066400000000000000000000017771257152637300177520ustar00rootroot00000000000000 Secure connections: HTTP over SSL This section gives an introduction to SSL. The text is inspired by . &neon; supports the use of HTTP over SSLThe term SSL is used throughout this section to refer in general to both the SSL protocol developed by Netscape and its successor TLS, as adopted by the IETF. to implement secure connections. A secure connection in this context means a connection which has integrity, secrecy and is authenticated. Applications must go to some effort to correctly support secure connections—an application based on &neon; does not magically become secure simply by flicking a switch and enabling the use of SSL. davix-R_0_5_0/deps/libneon/doc/using.xml000066400000000000000000000144301257152637300202640ustar00rootroot00000000000000 How to use neon from your application This section describes how to add &neon; support to an application. If you just want to quickly try out &neon;, use the script. The &neon; source code is designed to be easily embedded into an application source tree. &neon; has no dependencies on libraries other than an SSL toolkit and XML parser, though the source tree can be configured to have no support for SSL or XML if desired. To configure the &neon; source code some GNU autoconf macros are supplied, which can be used in a number of ways, as follows: autoconf macros are distributed in the 'macros' subdirectory of the neon distribution. Use the NEON_LIBRARY macro from your configure.in to check for the presence of the neon library installed on the system. The macro adds an '--with-neon=...' argument to configure, which allows the user to specify a location for the library (the standard /usr and /usr/local directories are checked automatically without having to be specified). The 'src' directory of the neon package can be imported directly into your application, if you do not wish to add an external dependency. If you wish to bundle, use the NEON_BUNDLED macro to configure neon in your application: here, the neon sources are bundled in a directory called 'libneon': NEON_BUNDLED(libneon, ...) If your application supports builds where srcdir != builddir, you should use the NEON_VPATH_BUNDLED macro like this: NEON_VPATH_BUNDLED(${srcdir}/libneon, libneon, ...) If you use this macro, a '--with-included-neon' option will be added to the generated configure script. This allows the user to force the bundled neon to be used in the application, rather than any neon library found on the system. If you allow neon to be configured this way, you must also configure an XML parser. Use the NEON_XML_PARSER macro to do this. The final argument to the _BUNDLED macros is a set of actions which are executed if the bundled build *is* chosen (rather than an external neon which might have been found on the user's system). In here, use either the NEON_LIBTOOL_BUILD or NEON_NORMAL_BUILD macro to set up the neon Makefile appropriately: including adding the neon source directory to the recursive make. A full fragment might be: NEON_BUNDLED(libneon, [ NEON_NORMAL_BUILD NEON_XML_PARSER SUBDIRS="libneon $SUBDIRS" ]) This means the bundled neon source directory (called 'libneon') is used if no neon is found on the system, and the standard XML parser search is used. Standards compliance &neon; is intended to be compliant with the IETF and W3C standards which it implements, with a few exceptions due to practical necessity or interoperability issues. These exceptions are documented in this section. RFC 2518, HTTP Extensions for Distributed Authoring—WebDAV &neon; is deliberately not compliant with section 23.4.2, and treats property names as a (namespace-URI, name) pair. This is generally considered to be correct behaviour by the WebDAV working group, and is likely to formally adopted in a future revision of the specification. RFC 2616, Hypertext Transfer Protocol—HTTP/1.1 There is some confusion in this specification about the use of the identity transfer-coding. &neon; ignores the Transfer-Encoding response header if it contains only the (now deprecated) identity token, and will determine the response message length as if the header was not present. &neon; will give an error if a response includes a Transfer-Encoding header with a value other than identity or chunked. RFC 2617, HTTP Authentication: Basic and Digest Access Authentication &neon; is not strictly compliant with the quoting rules given in the grammar for the Authorization header. The grammar requires that the qop and algorithm parameters are not quoted, however one widely deployed server implementation (Microsoft® IIS 5) rejects the request if these parameters are not quoted. &neon; sends these parameters with quotes—this is not known to cause any problems with other server implementations. Namespaces in XML The &neon; XML parser interface will accept and parse without error some XML documents which are well-formed according to the XML specification but do not conform to the "Namespaces in XML" specification . Specifically: the restrictions on the first character of the NCName rule are not all implemented; &neon; will allow any CombiningChar, Extender and some characters from the Digit class in this position. davix-R_0_5_0/deps/libneon/doc/version.xml000066400000000000000000000000061257152637300206160ustar00rootroot000000000000000.29.6davix-R_0_5_0/deps/libneon/doc/xml.xml000066400000000000000000000161531257152637300177430ustar00rootroot00000000000000 Parsing XML The &neon; XML interface is exposed by the ne_xml.h header file. This interface gives a wrapper around the standard SAX API used by XML parsers, with an additional abstraction, stacked SAX handlers, and also giving consistent XML Namespace support. Introduction to SAX A SAX-based parser works by emitting a sequence of events to reflect the tokens being parsed from the XML document. For example, parsing the following document fragment: world ]]> results in the following events: &startelm; "hello" &cdata; "world" &endelm; "hello" This example demonstrates the three event types used used in the subset of SAX exposed by the &neon; XML interface: &startelm;, &cdata; and &endelm;. In a C API, an event is implemented as a function callback; three callback types are used in &neon;, one for each type of event. Stacked SAX handlers WebDAV property values are represented as fragments of XML, transmitted as parts of larger XML documents over HTTP (notably in the body of the response to a PROPFIND request). When &neon; parses such documents, the SAX events generated for these property value fragments may need to be handled by the application, since &neon; has no knowledge of the structure of properties used by the application. To solve this problemThis problem only needs solving because the SAX interface is so inflexible when implemented as C function callbacks; a better approach would be to use an XML parser interface which is not based on callbacks. the &neon; XML interface introduces the concept of a SAX handler. A SAX handler comprises a &startelm;, &cdata; and &endelm; callback; the &startelm; callback being defined such that each handler may accept or decline the &startelm; event. Handlers are composed into a handler stack before parsing a document. When a new &startelm; event is generated by the XML parser, &neon; invokes each &startelm; callback in the handler stack in turn until one accepts the event. The handler which accepts the event will then be subsequently be passed &cdata; events if the element contains character data, followed by an &endelm; event when the element is closed. If no handler in the stack accepts a &startelm; event, the branch of the tree is ignored. To illustrate, given a handler A, which accepts the cat and age elements, and a handler B, which accepts the name element, the following document: An example XML document 3 Bob ]]> would be parsed as follows: A &startelm; "cat" → accept A &startelm; "age" → accept A &cdata; "3" A &endelm; "age" A &startelm; "name" → decline B &startelm; "name" → accept B &cdata; "Bob" B &endelm; "name" A &endelm; "cat" The search for a handler which will accept a &startelm; event begins at the handler of the parent element and continues toward the top of the stack. For the root element, it begins at the base of the stack. In the above example, handler A is at the base, and handler B at the top; if the name element had any children, only B's &startelm; would be invoked to accept them. Maintaining state To facilitate communication between independent handlers, a state integer is associated with each element being parsed. This integer is returned by &startelm; callback and is passed to the subsequent &cdata; and &endelm; callbacks associated with the element. The state integer of the parent element is also passed to each &startelm; callback, the value zero used for the root element (which by definition has no parent). To further extend : if handler A defines that the state of the root element cat will be 42, the event trace would be as follows: A &startelm; (parent = 0, "cat") → accept, state = 42 A &startelm; (parent = 42, "age") → accept, state = 50 A &cdata; (state = 50, "3") A &endelm; (state = 50, "age") A &startelm; (parent = 42, "name") → decline B &startelm; (parent = 42, "name") → accept, state = 99 B &cdata; (state = 99, "Bob") B &endelm; (state = 99, "name") A &endelm; (state = 42, "cat") To avoid collisions between state integers used by different handlers, the interface definition of any handler includes the range of integers it will use. XML namespaces To support XML namespaces, every element name is represented as a (namespace, name) pair. The &startelm; and &endelm; callbacks are passed namespace and name strings accordingly. If an element in the XML document has no declared namespace, the namespace given will be the empty string, "". davix-R_0_5_0/deps/libneon/install-sh000077500000000000000000000325371257152637300176640ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # 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. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false 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: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -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. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; 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 if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi 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 "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # 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: $dst_arg: 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 '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or 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 /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi 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. (umask $cp_umask && $doit_exec $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"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # 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. { test ! -f "$dst" || $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 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || 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-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: davix-R_0_5_0/deps/libneon/ltmain.sh000066400000000000000000010520401257152637300174700ustar00rootroot00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 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. # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [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 # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # 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. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # 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" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; 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 that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # 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 "$opt_dry_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" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # 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= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_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 $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE 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. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # 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 () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` 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 "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # 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. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # 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 func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # 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= pie_flag= 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) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append 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,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append 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. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # 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 # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) 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 "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" 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 $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "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." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_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 func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_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 func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [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: $progname [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 -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler 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: $progname [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: $progname [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: $progname [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 following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [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 -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -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 -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -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] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) 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: $progname [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." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" 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 -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; 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 LANGUAGE 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 } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # 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. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; 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. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append 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 -e "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. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_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 test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append 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 func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_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 func_basename "$file" destfile="$func_basename_result" 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 func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "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) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # 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/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) 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*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; 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 "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # 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. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug 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 # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $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_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" 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 func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result 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" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_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've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # 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. sed_quote_subst='$sed_quote_subst' # Be 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # 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 variables: generated_by_libtool_version='$macro_version' 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 file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED '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 \"\$file\" | $SED '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 \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ 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 "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # 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 \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #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 # define FOPEN_WB "wb" # 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 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ 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; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); 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 (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); 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 (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); 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 * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } 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; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" 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 func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append 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 func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" 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 func_append 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. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append 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 func_append 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" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir 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 func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework 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*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append 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* | *-cegcc* | *-*-haiku*) # 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 func_append deplibs " System.ltframework" 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 func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" 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*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext 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 ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" 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 func_append 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. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append 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 func_append 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" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" 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. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'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\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append 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 $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append 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 notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; 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 # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi 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%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" 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 \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; 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 func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" 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 func_dirname "$lib" "" "." ladir="$func_dirname_result" 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 *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; 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 func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` 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 use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac 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. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # 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 func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append 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 func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" 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. func_append dlprefiles " $lib $dependency_libs" else func_append 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 func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$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 func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac 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 func_append 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*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; 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 $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append 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 *"$absdir:"*) ;; *) func_append 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 "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append 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 case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && 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 "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" 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* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' 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 "$opt_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 (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; 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 elif test -n "$old_library"; then 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 && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append 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 func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append 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:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; 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:"*) ;; *) func_append 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 [\\/]*) func_append 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*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append 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" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= 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 "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi 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 "*) ;; *) func_append 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 "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append 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 func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" 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 test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # 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="$1" number_minor="$2" number_revision="$3" # # 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 # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; 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]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; 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]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; 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]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" 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 func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result 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 func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result 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 func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; 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 func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_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 | *.gcno) ;; $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 func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "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 func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append 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 "*) ;; *) func_append 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 "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-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 func_append 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. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi 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 "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append 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 ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append 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 func_append 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 ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; 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 " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) 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 ;; esac ;; 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 with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; 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 # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; 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 " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append 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 # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_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 func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result 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"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append 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 "$opt_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 shift realname="$1" 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 func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "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" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_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:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # 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 func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append 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. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result 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~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "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" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi 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\" test "X$libobjs" = "X " && libobjs= 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 fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( 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 "$opt_mode" = relink; then $opt_dry_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 func_show_eval '${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 func_show_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 "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_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 "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${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" # $opt_dry_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" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; 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 "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append 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 "*) ;; *) func_append 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"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append 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"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append 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 "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status 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 func_append 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 func_append 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 "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi 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" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "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}\" || $lt_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 func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result 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 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } 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 $symfileobj" 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" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append 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 # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # 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 func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$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 eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$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= len=$len0 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 func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "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}\" || $lt_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 func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; 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 "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { 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) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # 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' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_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 } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug 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) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; 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 func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append 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 func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # 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 build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 davix-R_0_5_0/deps/libneon/macros/000077500000000000000000000000001257152637300171325ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/macros/ChangeLog000066400000000000000000001023421257152637300207060ustar00rootroot00000000000000Sun Sep 12 18:38:13 2004 Joe Orton * neon.m4 (NEON_USE_EXTERNAL): Check for IDNA, LFS, SOCKS support. (NEON_SOCKS): Use common feature code for SOCKSv5 support. Fri Sep 10 20:52:54 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Safer autoheader template for declaring stpcpy as necessary for bundled neon builds. (NEON_WARNINGS): Drop -Winline. Wed Aug 25 19:44:26 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for poll. Sat Jul 3 11:39:01 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Pick up gethostbyname in -lsocket for QNX. Fri Apr 16 11:43:10 2004 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): If built using libtool, and --with-expat specifies a libexpat.la file, add the libexpat.la to NEON_LTLIBS. * neon.m4 (NEON_COMMON_CHECKS): Substitute NEON_LTLIBS. Tue Apr 13 20:51:59 2004 Joe Orton * neon.m4 (NEON_GSSAPI): Check for presence of gssapi/gssapi_generic.h. Wed Apr 7 13:16:33 2004 Joe Orton * neon.m4 (NE_LARGEFILE): Check for strtoq. Mon Mar 15 19:59:36 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Be safer around getaddrinfo blacklist for HP-UX and reference why it's needed. Sun Mar 7 11:15:44 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Use NE_LARGEFILE in-place rather than AC_REQUIRE'ing it. (NE_LARGEFILE): Add NE_LFS to CPPFLAGS for use in bundled builds. Mon Feb 23 23:02:54 2004 Joe Orton * neon.m4 (NE_SNPRINTF): Define HAVE_TRIO if trio is used. Mon Feb 23 00:22:39 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Give INCLUDES argument to AC_CHECK_HEADERS; prevent warning from cpp test for netinet/in.h on some platforms. Sun Feb 22 17:52:42 2004 Joe Orton * neon.m4 (NE_SEARCH_LIBS): Fix to run actions-if-found if function is found without needing additional libraries. (LIBNEON_SOURCE_CHECKS): Only check for gethostbyname if getaddrinfo is not found. Disable getaddrinfo on HP-UX 11.[01]* here rather than ne_socket.c. Sat Jan 24 17:49:50 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Also check for __tm_gmtoff in struct tm. Sat Jan 24 17:16:48 2004 Joe Orton * neon.m4: Remove -ansi-pedantic and -Wimplicit-prototypes for gcc 3.4 compatibility (thanks to Olaf Hering). Sat Jan 3 14:11:14 2004 Joe Orton * neon-test.m4: Check for stdint.h. Sat Jan 3 13:17:21 2004 Joe Orton * neon.m4 (NE_LARGEFILE): Add NE_LFS to neon-config --cflags output. Thu Jan 1 18:42:56 2004 Joe Orton * neon.m4 (NEON_FORMAT): Use C99 'll' rather than non-standard 'q' length modifier. Thu Jan 1 17:36:39 2004 Joe Orton * neon.m4 (NE_LARGEFILE): New macro. (LIBNEON_SOURCE_CHECKS): Call it. Sat Nov 15 09:25:43 2003 Joe Orton * neon.m4, neon-xml-parser.m4: Update for latest autoconf best-practice: s/AC_HELP_STRING/AS_HELP_STRING, replace AC_TRY_RUN with AC_RUN_IFELSE, AC_TRY_LINK_FUNC with AC_LINK_IFELSE, AC_TRY_COMPILE with AC_COMPILE_IFELSE, remove AC_LANG_C and AC_PROG_CC_STDC, Fri Nov 14 13:12:10 2003 Joe Orton * neon.m4 (NEON_LIBIDN): New macro. (LIBNEON_SOURCE_CHECKS): Use NEON_LIBIDN. Fri Nov 14 11:28:58 2003 Joe Orton * neon.m4 (NE_ENABLE_SUPPORT, NE_DISABLE_SUPPORT): New macros. Use throughout to flag support or lack of support for optional features. Thu Nov 13 20:25:28 2003 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for gethostbyname in -lbind too. Tue Oct 7 21:20:16 2003 Joe Orton * neon-test.m4 (NEON_TEST): Check for shutdown. Mon Sep 22 21:20:37 2003 Joe Orton * neon.m4 (NE_CHECK_FUNCS, NE_SEARCH_LIBS): Avoid clobbering ne_save_{LIBS,CPPFLAGS}. Sun Sep 14 10:51:34 2003 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for working AI_ADDRCONFIG flag for getaddrinfo(). Wed Sep 10 21:45:10 2003 Joe Orton * neon.m4 (NEON_GSSAPI): Restore CPPFLAGS and NEON_LIBS if GSSAPI detection fails. Thu Sep 4 21:29:06 2003 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for netinet/tcp.h. Wed Jul 23 21:17:40 2003 Joe Orton * neon.m4 (NEON_GSSAPI): New macro. Mon Apr 21 18:24:12 2003 Joe Orton * neon-xml-parser.m4 (HAVE_EXPAT): Fail if --with-expat is given but expat.h is not found. Wed Mar 26 20:29:11 2003 Joe Orton * neon.m4 (NEON_SSL): And add ne_stubssl to NEON_EXTRAOBJS for non-SSL build. Tue Mar 25 20:43:01 2003 Joe Orton * neon.m4 (NEON_SSL): Add ne_openssl to NEON_EXTRAOBJS. Mon Mar 17 20:34:55 2003 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for netdb.h. Sun Mar 16 14:22:02 2003 Joe Orton * neon-xml-parser.m4 (NE_XML_BUNDLED_EXPAT): Define HAVE_XMLPARSE_H. Sun Mar 16 11:47:35 2003 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Also fix non-included-expat build for when included expat is not an option. Sun Mar 16 11:20:23 2003 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Fix non-included-expat build broken in previous commit. Sun Mar 16 09:06:41 2003 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Fix --with-included-expat support. Sun Mar 9 10:08:57 2003 Joe Orton * neon.m4 (NEON_SSL): Fail if --with-ssl is given an argument. Sun Mar 9 08:55:04 2003 Joe Orton * neon.m4 (NE_SEARCH_LIBS): Bug fix to always compare against `extras' if given. Add support for optional `actions-if-found' argument. * neon-xml-parser.m4: Largely rewritten. Drop support for libxml 1.x; require expat 1.95.x. Sun Mar 9 08:50:22 2003 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for stpcpy. Mon Mar 3 22:15:56 2003 Joe Orton * neon.m4 (NE_CHECK_FUNCS): Check whether h_errno is declared. Wed Feb 19 21:35:20 2003 Joe Orton * neon.m4 (NEON_FORMAT): Revert use of 'z' modifier; breaks on CygWin. Tue Jan 14 17:06:07 2003 Joe Orton * neon.m4 (NEON_FORMAT): Prefer the C99 'z' modifier to printf size_t/ssize_t values where available. Fri Jan 3 23:12:20 2003 Joe Orton * neon.m4 (NE_PKG_CONFIG): New macro. (NEON_SSL): Use NE_PKG_CONFIG rather than PKG_CHECK_MODULES. Mon Dec 16 20:02:45 2002 Joe Orton * neon.m4 (NEON_SSL): Only check for OpenSSL <=0.9.6 if version is known to be <=0.9.7. Mon Dec 16 19:01:57 2002 Joe Orton * neon.m4: Use pkg-config data to determine location OpenSSL libraries/headers, if available. Tue Nov 19 11:21:31 2002 Joe Orton * neon-test.m4 (NEON_TEST): Suggest this macro is run before NEON_XML_PARSER. Mon Oct 7 22:22:12 2002 Joe Orton * neon.m4 (NE_CHECK_SSLVER): New macro. (NEON_SSL): Use NE_CHECK_SSLVER. Add --with-egd argument; conditionally enable EGD, optionally using only a specific EGD socket path, and only if using OpenSSL before 0.9.7. Tue Sep 24 21:36:01 2002 Joe Orton * neon.m4 (NE_ZLIB_VERSION): Removed macro. (NEON_ZLIB): Removed --with-force-zlib flag; don't check zlib version. (NEON_SSL): Removed --with-force-ssl flag, only require OpenSSL 0.9.6 or later. Sat Aug 31 17:28:15 2002 Joe Orton * neon.m4 (NEON_FORMAT_PREP): Add check for gcc -Wformat -Werror sanity. (NEON_FORMAT): Only use gcc -Wformat -Werror if sanity is assured. Fri Aug 30 22:07:59 2002 Joe Orton * neon.m4: Set NEON_INTERFACE_VERSION according to NEON_VERSION_MINOR, NEON_VERSION_RELEASE, for the duration of neon 0.x releases. Sun Aug 25 23:52:38 2002 Joe Orton * neon.m4 (NE_CHECK_FUNCS): New macro. (LIBNEON_SOURCE_CHECKS): Use NE_CHECK_FUNCS rather than AC_CHECK_FUNCS, so $NEON_LIBS are searched. Sun Aug 25 11:53:20 2002 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Require inet_ntop as well for USE_GETADDRINFO test. Sun Aug 18 22:50:09 2002 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Remove redundant check for SIGPIPE definition. Sun Aug 18 22:41:15 2002 Joe Orton * neon.m4 (NE_SEARCH_LIBS): Take optional fourth argument. (LIBNEON_SOURCE_CHECKS): Define USE_GETADDRINFO if getaddrinfo and gai_strerror are present. Otherwise, check for hstrerror, possibly in -lresolv. * neon-test.m4: Don't check for hstrerror(). Sun Aug 18 22:31:13 2002 Joe Orton * neon-xml-parser.m4 (NEON_FIND_PARSER_H, NEON_XML_LIBXML2): Re-order checks to skip redundant tests, speeding up common case. Fri Aug 9 19:47:14 2002 Joe Orton * neon.m4 (NEON_SSL): Require OpenSSL 0.9.6f or later. Wed Jul 31 23:01:17 2002 Joe Orton * strftime.m4, readline.m4: Removed from neon/macros CVS module. Tue Jul 30 19:09:20 2002 Joe Orton * neon.m4 (NEON_COMMON_CHECKS): Require AC_TYPE_SIZE_T, AC_TYPE_OFF_T. * neon-test.m4 (NEON_TEST): Require AC_TYPE_PID_T. Tue Jul 30 19:06:48 2002 Joe Orton * neon.m4 (NEON_SSL): Require OpenSSL 0.9.6e or later for security fixes; add --with-force-ssl to override version check. Fri Jul 26 00:01:07 2002 Joe Orton * neon.m4 (NE_MACOSX): Just check for any Darwin system. Sat Jul 20 10:40:29 2002 Joe Orton * neon.m4 (NEON_WITH_LIBS): Allow a colon-separated list of directories for --with-libs argument. Thu Jul 18 20:07:43 2002 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Require AC_FUNC_STRERROR_R. Wed Jul 17 23:26:51 2002 Joe Orton * neon.m4 (NEON_CHECK_VERSION): Rewrite to cache results, simplify, and use new ne_version_match. (NE_ZLIB_VERSION): Cache result. Fri Jul 5 12:57:56 2002 Joe Orton * neon.m4 (NEON_SSL): Fail if openssl/opensslv.h header is not found, or if OpenSSL version is earlier than 0.9.6. Sun Jun 16 14:04:18 2002 Joe Orton * neon.m4 (NEON_FORMAT): Take optional third argument giving format string specifier to use. (NEON_COMMON_CHECKS): Get format string for ssize_t; fix to use 'u' specifier for size_t format string. Thu Jun 13 20:34:35 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Undocument use of =DIR parameter to --with-expat, as it gives false expectations. Wed Jun 12 23:26:40 2002 Joe Orton * neon.m4 (NEON_WITH_LIBS): New macro. Mon Jun 10 22:31:50 2002 Joe Orton * neon.m4 (NEON_WARNINGS): Replace -ansi-pedantic with -pedantic. Sun May 26 19:08:12 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_LIBXML2): Check for libxml/xmlversion.h header too. Wed May 22 09:54:42 2002 Joe Orton * neon.m4 (NE_MACOSX): Cache result. (NE_COMMON_CHECKS): Simplify tm_gmtoff check further: use AC_CHECK_MEMBERS. Mon May 20 21:18:06 2002 Joe Orton * neon.m4 (NE_SEARCH_LIBS): Cache results. Mon May 20 20:55:04 2002 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Use AC_CACHE_CHECK to check for SIGPIPE in signal.h; don't invade the ac_ namespace with cache variables. Cache results of tm_gmtoff test too. Mon May 20 20:35:22 2002 Joe Orton * neon.m4 (NE_SNPRINTF): Simplify logic. Sun May 19 20:23:55 2002 Joe Orton * neon.m4 (NEON_WARNINGS): Remove with_warnings variable; simplify. Wed May 19 08:36:44 2004 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Declare stpcpy on modern "Linux-like" AIXes. Sun May 19 09:35:08 2002 Joe Orton * neon.m4 (NE_FIND_AR): Fix $PATH handling on some Linux platforms. Sun May 19 09:05:22 2002 Joe Orton * neon.m4 (NE_FIND_AR): New macro. (NEON_NORMAL_BUILD): Require NE_FIND_AR. * neon-test.m4: Require NE_FIND_AR. Check for hstrerror(). Fri May 17 23:37:19 2002 Joe Orton * neon.m4 (NEON_SSL): Allow --without-ssl again. Wed May 15 21:00:15 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_LIBXML2): sed '-L/usr/lib ' out of xml2-config --libs output. Sat May 11 15:30:38 2002 Joe Orton * neon.m4 (NEON_SOCKS): Moved and simplified from neon-socks.m4. Drop support for specifying directory argument; fail if --with-socks is given and socks.h is not found. * neon-socks.m4: Removed file. Sat May 11 15:22:36 2002 Joe Orton * neon.m4 (NEON_DEBUG): Moved and simplified from neon-debug.m4. * neon-debug.m4: Removed file. Sat May 11 13:40:29 2002 Joe Orton * neon.m4 (NEON_WARNINGS): Moved and simplified from neon-warnings.m4. * neon-warnings.m4: Removed file. Sat May 11 13:26:00 2002 Joe Orton * neon.m4 (NEON_SSL): Simplified version of NEON_SSL from neon-ssl.m4. Check for ssl.h; detect OpenSSL ENGINE correctly when -lcrypto requries -ldl. * neon-ssl.m4: Removed file. Sat May 11 13:16:27 2002 Joe Orton * neon.m4 (NE_SEARCH_LIBS): Allow passing 'extralibs' to include in library list when link against a specified library fails. Prepend found library/libraries to $NEON_LIBS. Sat May 11 12:40:24 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER), * neon.m4 (NEON_REPLACE_SNPRINTF): Use AC_LIBOBJ rather than modify LIBOBJS directly, to appease autoconf 2.53. Wed May 1 22:32:10 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_LIBXML1): Fix syntax error in libxml 1.x detection causing spurious or missing warning message. Thu Apr 25 07:38:33 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_EXTERNAL_EXPAT): Check for expat.h too, to support expat 1.95.x (Branko ibej). Tue Apr 23 21:09:55 2002 Joe Orton * neon-xml-parser.m4 (NEON_FIND_PARSER_H): New macro, factored out from NEON_XML_LIBXML2. (NEON_XML_LIBXML2, NEON_XML_LIBXML1): Use it. Tue Apr 23 20:54:30 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_LIBXML2): Check for parser.h or libxml/parser.h, or fail. Sat Apr 13 22:35:01 2002 Joe Orton * neon.m4 (NE_SNPRINTF): Define NEON_TRIO in NEON_CFLAGS, export it from 'neon-config --cflags' output. Fri Apr 5 23:40:00 2002 Joe Orton * neon.m4 (NEON_ZLIB, NE_ZLIB_VERSION): Add --with-force-zlib, to skip zlib version check. Simplify neon_zlib_message handling a little. Tue Mar 12 00:18:00 2002 Joe Orton * neon.m4 (NE_ZLIB_VERSION): New macro. (NEON_ZLIB): Use it to require zlib 1.1.4. Sun Mar 10 22:05:26 2002 Joe Orton * neon.m4 (NEON_ZLIB): Don't add ne_compress to NEON_EXTRAOBJS. Mon Mar 4 21:04:28 2002 Joe Orton * neon-ssl.m4 (NEON_SSL): Avoid adding -I/usr/include to CFLAGS during build as well as not exporting it via neon-config. Tue Feb 19 21:30:50 2002 Joe Orton * neon-socks.m4 (NEON_SOCKS): Fix configure argument name, export -L argument in NEON_LIBS, check for socks.h not sock.h, define NEON_SOCKS. Sun Jan 13 20:07:51 2002 Joe Orton * neon.m4 (NE_MACOSX): New macro. (NEON_COMMON_CHECKS): Call it. Sun Jan 6 21:35:08 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Add XML_BYTE_ORDER to CPPFLAGS; mini-expat doesn't pick up config.h. Tue Jan 1 23:30:03 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Set XML_BYTE_ORDER appropriately. Tue Jan 1 22:50:15 2002 Joe Orton * neon.m4 (NEON_CHECK_VERSION): Don't add libs for external neon to NEON_LIBS here. Tue Jan 1 22:44:05 2002 Joe Orton * neon-xml-parser.m4 (NEON_XML_LIBXML2, NEON_XML_LIBXML1): Alter CPPFLAGS only, not CFLAGS. Tue Jan 1 21:49:16 2002 Joe Orton * neon.m4 (NEON_USE_EXTERNAL): Factored out from NEON_COMMON. (NEON_COMMON): Use NEON_USE_EXTERNAL; simplify, improve reporting. * neon.m4 (NEON_COMMON_CHECKS): Move check for common headers here... (LIBNEON_SOURCE_CHECKS): from here. Tue Jan 1 21:44:33 2002 Joe Orton * neon-test.m4 (NEON_TEST): Check for AR and RANLIB. Fri Dec 14 22:39:57 2001 Joe Orton * neon-test.m4 (NEON_TEST): Pick up time_t definition from sys/time.h if present (fix for Solaris 2.6 and probably elsewhere). Fri Dec 14 22:39:32 2001 Joe Orton * neon.m4 (NEON_FORMAT): Allow passing in headers where type may be defined. Mon Dec 10 07:36:26 2001 Joe Orton * neon.m4 (NEON_COMMON): Fix --with-neon=PATH again. Sun Dec 9 21:40:47 2001 Joe Orton * neon-test.m4 (NEON_TEST): Determine how to print time_t. Sun Dec 9 11:50:03 2001 Joe Orton * neon.m4 (NEON_WITHOUT_ACL): New macro. (LIBNEON_SOURCE_CHECKS): Conditionally build ACL support. Sun Dec 9 01:06:32 2001 Joe Orton * neon.m4 (NEON_CHECK_VERSION): Use NEON_CONFIG as config script, drop first argument. Better error message if the link failed. (NEON_COMMON): Cleanup. Check for neon-config in PATH. Stop if --with-neon was given, and the external neon wasn't good enough. Sun Dec 9 00:17:19 2001 Joe Orton * neon-test.m4 (NEON_TEST): Requires NEON_COMMON_CHECKS. * neon-warnings.m4 (NEON_WARNINGS): Requires AC_PROG_CC. Sun Dec 9 00:13:47 2001 Joe Orton * neon.m4 (NEON_COMMON_CHECKS): New macro; runs common C language/compiler checks, which may be useful to neon applications regardless of whether a bundled or external neon is being used. Use AC_REQUIRE to prevent macros being expanded more than once. (LIBNEON_SOURCE_CHECKS, NEON_COMMON): Require NEON_COMMON_CHECKS to have been expanded. Sat Dec 8 00:56:34 2001 Joe Orton * neon.m4 (NEON_FORMAT): Rewrite to use cache results (should fix for cross-compiling), and for GCC, actually test for warnings - fix for Linux. Sat Dec 8 00:15:44 2001 Joe Orton * neon.m4 (NEON_CHECK_SUPPORT): Send --support output to /dev/null, in case it is from pre-0.18 and prints the usage message. Sat Dec 8 00:13:55 2001 Joe Orton * neon.m4 (NEON_COMMON): Prepend -lneon to NEON_LIBS rather than overwriting it when using bundled build. Mon Dec 3 19:49:28 2001 Joe Orton * neon.m4 (NEON_FORMAT_PREP, NEON_FORMAT): New macros. (LIBNEON_SOURCE_CHECKS): Call them. Mon Dec 3 19:43:11 2001 Joe Orton Fix gethostbyname() detection on Unixware 7: * neon.m4 (NEON_COMMON): Add -lneon to NEON_LIBS after performing source checks. (NE_SEARCH_LIBS): Test using libraries from NEON_LIBS too. Sat Nov 24 20:33:11 2001 Joe Orton * neon.m4 (NEON_CHECK_SUPPORT): New macro. (NEON_COMMON): Define NEON_SUPPORTS_{SSL,ZLIB} when using an external neon. Sat Nov 24 20:25:15 2001 Joe Orton * neon.m4 (NEON_WITHOUT_ZLIB): New function. (LIBNEON_SOURCE_CHECKS): Conditionally enable zlib support. Sun Nov 18 12:29:08 2001 Joe Orton * neon-ssl.m4 (NEON_SSL): Don't add -I/usr/include to NEON_CFLAGS. Sat Oct 27 12:20:08 2001 Joe Orton * neon.m4, neon-ssl.m4: Substitute NEON_SUPPORTS_ZLIB, NEON_SUPPORTS_DAV, NEON_SUPPORTS_SSL as "yes" or "no" appropriately. Thu Oct 25 14:29:53 2001 Mo DeJong * neon.m4 (NEON_NORMAL_BUILD): Use AC_CHECK_TOOL instead of AC_PATH_PROG so that cross compilation works properly. Sat Oct 6 13:36:58 2001 Joe Orton * neon.m4 (NEON_ZLIB): New macro. (LIBNEON_SOURCE_CHECKS): print warning if struct tm lacks tm_gmtoff. Sat Oct 6 12:39:09 2001 Joe Orton * neon.m4: Require autoconf 2.50. Use AC_HELP_STRING where possible, and AC_MSG_NOTICE instead of 'echo'. * neon-ssl.m4, neon-xml-parser.m4, neon-socks.m4: Quoting fixes for help strings. Tue Oct 2 21:13:24 2001 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for tm_gmtoff in struct tm. Sun Sep 30 23:35:03 2001 Joe Orton * neon.m4 (NE_SEARCH_LIBS): AC_SEARCH_LIBS replacement, adds found libraries to NEON_LIBS instead. Sun Sep 30 11:11:19 2001 Joe Orton * neon-test.m4: New file. Sun Sep 30 11:09:58 2001 Joe Orton * neon.m4, neon-xml-parser.m4: Always add libs to $LIBS rather than $NEONLIBS. * neon.m4: Export NEON_CFLAGS. Sat Sep 29 14:12:53 2001 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for zlib (zlib.h, inflate in -lz). Add ne_compress to NEON_EXTRAOBJS. Tue Sep 25 07:31:53 2001 Mo DeJong * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for instead of . Define HAVE_SIGPIPE if SIGPIPE is defined in . Mon Sep 24 20:16:47 2001 Joe Orton * neon-xml-parser.m4 (NEON_XML_EXTERNAL_EXPAT): Fix broken AC_DEFINE (Mo DeJong). Mon Sep 24 17:24:42 2001 Joe Orton * ac_c_bigendian_cross.m4: New file. * neon.m4: Use AC_C_BIGENDIAN_CROSS rather than AC_C_BIGENDIAN. Mon Sep 17 23:29:11 2001 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Check for setvbuf(). Sun Sep 16 20:39:05 2001 Joe Orton * neon-ssl.m4 (NEON_SSL): Put SSL libs in LIBS rather than NEONLIBS (and lib paths). Sun Sep 16 20:36:53 2001 Joe Orton * neon.m4 (NEON_COMMON): Add library paths to NEONLIBS rather than LDFLAGS. Sat Jun 9 22:06:25 2001 Joe Orton * neon-debug.m4: New file. Thu May 31 00:04:51 2001 Joe Orton * neon.m4 (NEON_COMMON_BUILD): Update filenames. (NEON_CHECK_VERSION): Do simple AC_TRY_LINK and warn appropriately before checking version. Thu May 31 00:03:40 2001 Joe Orton * neon-warnings.m4: Add -Wbad-function-cast. Wed May 30 23:37:48 2001 Joe Orton * neon-xml-parser.m4: Added --with-libxml1 and --with-libxml2 arguments. Tue Apr 17 23:06:25 2001 Joe Orton * neon-ssl.m4: Define neon_ssl_message for configure output. Wed Apr 11 23:14:33 2001 Joe Orton * neon.m4 (NEON_COMMON_BUILD): Fix specifying a list of object files. Fri Apr 6 23:09:58 2001 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Call NEON_SOCKS. Fri Apr 6 23:08:39 2001 Joe Orton * neon-socks.m4: Add basic SOCKSv5 support (untested). Mon Apr 2 21:42:40 2001 Joe Orton * neon.m4: Version is 0.13.0, interface version 13:0:0. Mon Apr 2 00:27:37 2001 Joe Orton * neon.m4: Move check for 'ar' program to NEON_NORMAL_BUILD, it's not necessary for libtool build. Mon Apr 2 00:17:58 2001 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Check for xmlversion.h header from libxml2. Sun Apr 1 21:23:26 2001 Joe Orton * neon-xml-parser.m4: Add expat2 support (Sam TH ). Wed Mar 21 10:56:03 2001 Joe Orton * neon-xml-parser.m4: Add libxml2 support. Sun Mar 4 15:45:21 2001 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Use an m4 ifelse rather than a shell test to code the conditional on whether an argument was passed to the macro or not. Sun Mar 4 15:23:47 2001 Joe Orton * neon.m4: Add "actions if not bundled" argument to *_BUNDLED macros. Mon Feb 26 22:52:24 2001 Joe Orton * neon.m4: Version is 0.12.0. Mon Feb 26 22:06:13 2001 Joe Orton * neon.m4: Versionn is 0.12.0-dev. Sun Feb 25 17:12:49 2001 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Add checks for endianness (for md5 code), inline, and const. Sun Feb 25 17:00:07 2001 Joe Orton * neon.m4 (NEON_COMMON): Rename NEON_IS_BUNDLED to NEON_BUILD_BUNDLED. Sun Feb 25 16:52:19 2001 Joe Orton * neon.m4 (NEON_COMMON): Define NEON_IS_BUNDLED to "yes" or "no" appropriately. Sat Feb 24 00:06:09 2001 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Don't set NEON_NEED_XML_PARSER here. (NEON_COMMON): ... set it here instead. (NEON_WITHOUT_WEBDAV): New macro to disable WebDAV support. (NEON_COMMON_BUILD): Select default set of object files to build depending on whether DAV is enabled or not. Fri Feb 23 23:28:09 2001 Joe Orton * neon.m4 (NEON_COMMON_BUILD): Use an m4 'ifelse' for the number of args test. * neon.m4 (NEON_LIBTOOL_BUILD, NEON_NORMAL_BUILD, NEON_COMMON_BUILD): Set NEON_OBJEXT correctly (fixes dependancies). Sun Feb 4 14:55:10 2001 Joe Orton * neon.m4: Version is 0.11.0, interface version is 11:0:0. Sun Jan 28 17:16:27 2001 Joe Orton * neon.m4 (NEON_CHECK_VERSION): Run actions-if-okay if NEON_REQUIRE has not been called. Sun Jan 28 14:53:57 2001 Joe Orton * neon.m4 (NEON_REQUIRE, NEON_CHECK_VERSION): New macros. (NEON_COMMON): If a required version is defined, check that an external neon library matches it. Sun Jan 28 10:39:31 2001 Joe Orton * neon.m4: Define NEON_VERSION, NEON_VERSION_{MAJOR,MINOR} in config.h rather than substituting into neon_config.h. Sat Jan 27 22:55:42 2001 Joe Orton * neon.m4: Include version string in library message. Tue Jan 23 23:14:33 2001 Joe Orton * neon.m4 (NEON_VERSIONS): New macro. (NEON_COMMON): Call it from here. Mon Jan 15 22:26:54 2001 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Append rather than overwrite CFLAGS. Thu Jan 11 20:49:12 2001 Joe Orton * neon-ssl.m4: Check for OpenSSL in /usr too. Thu Jan 11 20:05:34 2001 Joe Orton * neon.m4 (NEON_VPATH_BUNDLED): New macro. (NEON_BUNDLED): Call NEON_COMMON_BUNDLED. (NEON_COMMON_BUNDLED): Abstracted from NEON_BUNDLED. Wed Jan 10 22:44:37 2001 Joe Orton * neon.m4 (NEON_LIBTOOL_BUILD, NEON_NORMAL_BUILD): Pass optional set of objects to build to these macros. Else, all objects go in NEONOBJS. (NEON_COMMON_BUILD): Implement that. Also substitute NEON_LINK_FLAGS. Mon Jan 8 22:23:51 2001 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Put XML parser libs in $NEONLIBS rather than $LIBS. Mon Jan 8 22:20:51 2001 Joe Orton * neon-ssl.m4 (NEON_SSL): Put OpenSSL libs in $NEONLIBS rather than LIBS. Sun Jan 7 17:30:54 2001 Joe Orton * neon.m4 (NEON_BUNDLED): Add optional second argument to specify builddir of bundled sources (Peter Moulder ). Wed Jan 3 21:33:05 2001 Joe Orton * neon.m4: Place libraries needed to use neon in NEONLIBS. Adding them to LIBS breaks bundled builds since libneon doesn't exist at configure-time, and configure uses $LIBS. Wed Jan 3 21:17:00 2001 Joe Orton * neon.m4 (NEON_COMMON_BUILD): Don't set top_builddir using 'pwd'. Wed Jan 3 21:15:04 2001 Joe Orton * neon.m4 (NEON_COMMON): If using bundled neon, add -L to LDFLAGS, and -lneon to LIBS. Fri Dec 22 23:13:39 2000 Joe Orton * neon.m4 (NEON_NORMAL_BUILD, NEON_COMMON_BUILD): New macros. Tue Dec 19 22:13:18 2000 Joe Orton * neon.m4 (NEON_LIBTOOL_BUILD): New macro. Wed Dec 13 22:07:07 2000 Joe Orton * neon.m4: Add a decent interface: NEON_LIBRARY for non-bundled case, NEON_BUNDLED for the bundled case. (LIBNEON_SOURCE_CHECKS): Always set NEON_NEED_XML_PARSER. * neon-xml-parser.m4 (NEON_XML_PARSER): Only execute if "$NEON_NEED_XML_PARSER" = "yes". Sun Nov 19 22:52:56 2000 Joe Orton * neon.m4, neon-ssl.m4, neon-warnings.m4, neon-xml-parser.m4: Clarify that the more liberal license applies to the m4 files only, not neon in general. Sun Nov 19 22:40:01 2000 Joe Orton * neon.m4 (NEON_LIBRARY): Don't call NEON_XML_PARSER, set NEON_NEED_XML_PARSER to "yes" if it needs to be called. Sun Nov 19 22:31:26 2000 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Switch to useing NEON_INCLUDED_EXPAT m4 macro rather than passing arguments. Sun Nov 19 22:20:36 2000 Joe Orton * neon.m4 (NEON_LIBRARY): Switch to using NEON_INCLUDED_SOURCE m4 macro rather than passing arguments to the NEON_LIBRARY macro. Sun Nov 5 23:26:18 2000 Joe Orton * neon-xml-parser.m4: Never set LIBS if using a libtool-built libexpat.la (Greg Stein). 2000-10-10 Joe Orton * neon-xml-parser.m4: If libexpat.la is included in the --with-expat parameter, then use a libtool-friendly LIBS. (Greg Stein) Sat Oct 7 19:16:08 2000 Joe Orton * neon-xml-parser.m4: Link against a libexpat.la if found in --with-expat location. (Greg Stein). Mon Sep 11 15:05:58 2000 Joe Orton * neon.m4: Use AC_SEARCH_LIBS for finding gethostbyname() and socket(). Mon Sep 11 15:03:45 2000 Joe Orton * neon.m4 (NEON_REPLACE_SNPRINTF): New macro. Fri Sep 8 14:30:37 2000 Joe Orton * neon.m4: Check for socket() in -lsocket, -linet. Thu Sep 7 00:11:51 2000 Joe Orton * neon-xml-parser.m4: Added --with-expat flag (patch by Greg Stein). Sun Aug 13 11:12:41 2000 Joe Orton * strftime.m4: New file, from fileutils-4.0i. Thu Jul 27 19:59:18 2000 Joe Orton * neon-ssl.m4: Append the SSL libs on the end of $LIBS rather than redefining it completely. Thu Jul 27 19:43:38 2000 Joe Orton * neon.m4: Define variable neon_library_message to describe what neon library is being used. Mon Jul 24 16:56:34 2000 Joe Orton * neon-ssl.m4: Put -lssl before -lcrypto in LIBS. Thu Jul 20 15:12:14 2000 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Pass directory name containing bundled expat sources as $1. * neon.m4 (NEON_LIBRARY): Pass directory name containing bundled neon sources as $1, and $2 is passed to NEON_XML_PARSER for similar use. Thu Jul 20 15:04:49 2000 Joe Orton * neon-ssl.m4: Rewritten from scratch. Support OpenSSL only. Thu Jul 20 12:41:23 2000 Joe Orton * neon.m4, neon-xml-parser.m4, neon_warnings.m4: Added licensing information. Wed Jul 19 19:30:24 2000 Joe Orton * neon-warnings.m4: New file. (NEON_WARNINGS): Macro for doing --enable-warnings. Sun Jun 18 12:12:23 2000 Joe Orton * neon.m4: Only add --with-included-neon flag if neon is bundled. Sun Jun 18 12:08:23 2000 Joe Orton * gnome-x-checks.m4: Imported from GNOME CVS macros module, adding: descriptive args to AC_DEFINE HAVE_LIBSM call, requiring Gtk 1.2.8 and the Gtk 'gthread' module. Mon May 29 15:10:24 2000 Joe Orton * neon.m4 (LIBNEON_SOURCE_CHECKS): Call NEON_SSL. Tue May 23 19:11:29 2000 Joe Orton * neon.m4: Renamed from neon-checks.m4. Sun May 21 23:52:27 2000 Joe Orton * neon-ssl.m4: New file. Sat May 13 21:08:54 2000 Joe Orton * acconfig.h: Added HAVE_LC_MESSAGE (my lcmessage.m4 is missing the appropriate description arguments). Sat May 13 21:08:40 2000 Joe Orton * acconfig.h: Added PACKAGE and VERSION. Sat May 13 21:02:29 2000 Joe Orton * socklen-arg-type.m4: Added file, modified from a KDE configure.in. Sat May 13 20:44:56 2000 Joe Orton * gnome-x-checks.m4: Added description arguments to AC_DEFINE(HAVE_LIBSM). Wed May 10 19:18:14 2000 Joe Orton * neon-xml-parser.m4: Error if no XML parser is found. Wed May 10 14:33:21 2000 Joe Orton * neon-checks.m4: New file. Wed May 10 14:26:57 2000 Joe Orton * neon-xml-parser.m4 (NEON_XML_PARSER): Use "neon_" prefix for variables. Wed May 10 13:47:04 2000 Joe Orton * acconfig.h: New file. Wed May 10 13:42:16 2000 Joe Orton * neon-xml-parser.m4: New file. Sun May 7 21:57:32 2000 Joe Orton * gnome-x-checks.m4 (GNOME_X_CHECKS): Check for Gtk 1.2.7 or later, passing "gthread" module argument. davix-R_0_5_0/deps/libneon/macros/ld-version-script.m4000066400000000000000000000026261257152637300227660ustar00rootroot00000000000000# ld-version-script.m4 serial 1 dnl Copyright (C) 2008, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Simon Josefsson # FIXME: The test below returns a false positive for mingw # cross-compiles, 'local:' statements does not reduce number of # exported symbols in a DLL. Use --disable-ld-version-script to work # around the problem. # gl_LD_VERSION_SCRIPT # -------------------- # Check if LD supports linker scripts, and define automake conditional # HAVE_LD_VERSION_SCRIPT if so. AC_DEFUN([gl_LD_VERSION_SCRIPT], [ AC_ARG_ENABLE([ld-version-script], AS_HELP_STRING([--enable-ld-version-script], [enable linker version script (default is enabled when possible)]), [have_ld_version_script=$enableval], []) if test -z "$have_ld_version_script"; then AC_MSG_CHECKING([if LD -Wl,--version-script works]) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" cat > conftest.map < -*- autoconf -*- # # This file is free software; you may copy and/or distribute it with # or without modifications, as long as this notice is preserved. # This software 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. # The above license applies to THIS FILE ONLY, the neon library code # itself may be copied and distributed under the terms of the GNU # LGPL, see COPYING.LIB for more details # This file is part of the neon HTTP/WebDAV client library. # See http://www.webdav.org/neon/ for the latest version. # Please send any feedback to # Tests needed for the neon-test common test code. AC_DEFUN([NE_FORMAT_TIMET], [ NEON_FORMAT(time_t, [ #ifdef HAVE_SYS_TIME_H #include #endif]) ]) AC_DEFUN([NEON_TEST], [ AC_REQUIRE([NEON_COMMON_CHECKS]) AC_REQUIRE([NE_FORMAT_TIMET]) AC_REQUIRE([AC_TYPE_PID_T]) AC_REQUIRE([AC_HEADER_TIME]) dnl NEON_XML_PARSER may add things (e.g. -I/usr/local/include) to dnl CPPFLAGS which make "gcc -Werror" fail in NEON_FORMAT; suggest dnl this macro is used first. AC_BEFORE([$0], [NEON_XML_PARSER]) AC_CHECK_HEADERS(sys/time.h stdint.h locale.h signal.h) AC_CHECK_FUNCS(pipe isatty usleep shutdown setlocale gethostname) AC_REQUIRE([NE_FIND_AR]) ]) davix-R_0_5_0/deps/libneon/macros/neon-xml-parser.m4000066400000000000000000000121561257152637300224300ustar00rootroot00000000000000# Copyright (C) 1998-2005, 2007 Joe Orton -*- autoconf -*- # # This file is free software; you may copy and/or distribute it with # or without modifications, as long as this notice is preserved. # This software 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. # The above license applies to THIS FILE ONLY, the neon library code # itself may be copied and distributed under the terms of the GNU # LGPL, see COPYING.LIB for more details # This file is part of the neon HTTP/WebDAV client library. # See http://www.webdav.org/neon/ for the latest version. # Please send any feedback to # Check for XML parser, supporting libxml 2.x and expat 1.95.x, # or a bundled copy of expat. # * Bundled expat if a directory name argument is passed # -> expat dir must contain minimal expat sources, i.e. # xmltok, xmlparse sub-directories. See sitecopy/cadaver for # examples of how to do this. # # Usage: # NEON_XML_PARSER() # or # NEON_XML_PARSER([expat-srcdir], [expat-builddir]) dnl Find expat: run $1 if found, else $2 AC_DEFUN([NE_XML_EXPAT], [ AC_CHECK_HEADER(expat.h, [AC_CHECK_LIB(expat, XML_SetXmlDeclHandler, [ AC_DEFINE(HAVE_EXPAT, 1, [Define if you have expat]) neon_xml_parser_message="expat" NEON_LIBS="$NEON_LIBS -lexpat" neon_xml_parser=expat AC_CHECK_TYPE(XML_Size, [NEON_FORMAT(XML_Size, [#include ])], [AC_DEFINE_UNQUOTED([NE_FMT_XML_SIZE], ["d"])], [#include ]) ], [$1])], [$1]) ]) dnl Find libxml2: run $1 if found, else $2 AC_DEFUN([NE_XML_LIBXML2], [ AC_CHECK_PROG(XML2_CONFIG, xml2-config, xml2-config) if test -n "$XML2_CONFIG"; then neon_xml_parser_message="libxml `$XML2_CONFIG --version`" AC_DEFINE(HAVE_LIBXML, 1, [Define if you have libxml]) # xml2-config in some versions erroneously includes -I/include # in the --cflags output. CPPFLAGS="$CPPFLAGS `$XML2_CONFIG --cflags | sed 's| -I/include||g'`" NEON_LIBS="$NEON_LIBS `$XML2_CONFIG --libs | sed 's|-L/usr/lib ||g'`" AC_CHECK_HEADERS(libxml/xmlversion.h libxml/parser.h,,[ AC_MSG_ERROR([could not find parser.h, libxml installation problem?])]) neon_xml_parser=libxml2 else $1 fi ]) dnl Configure for a bundled expat build. AC_DEFUN([NE_XML_BUNDLED_EXPAT], [ AC_REQUIRE([AC_C_BIGENDIAN]) # Define XML_BYTE_ORDER for expat sources. if test $ac_cv_c_bigendian = "yes"; then ne_xml_border=21 else ne_xml_border=12 fi # mini-expat doesn't pick up config.h CPPFLAGS="$CPPFLAGS -DXML_BYTE_ORDER=$ne_xml_border -DXML_DTD -I$1/xmlparse -I$1/xmltok" AC_DEFINE_UNQUOTED([NE_FMT_XML_SIZE], ["d"]) # Use the bundled expat sources AC_LIBOBJ($2/xmltok/xmltok) AC_LIBOBJ($2/xmltok/xmlrole) AC_LIBOBJ($2/xmlparse/xmlparse) AC_LIBOBJ($2/xmlparse/hashtable) AC_DEFINE(HAVE_EXPAT) AC_DEFINE(HAVE_XMLPARSE_H, 1, [Define if using expat which includes xmlparse.h]) ]) AC_DEFUN([NEON_XML_PARSER], [ dnl Switches to force choice of library AC_ARG_WITH([libxml2], AS_HELP_STRING([--with-libxml2], [force use of libxml 2.x])) AC_ARG_WITH([expat], AS_HELP_STRING([--with-expat], [force use of expat])) dnl Flag to force choice of included expat, if available. ifelse($#, 2, [ AC_ARG_WITH([included-expat], AS_HELP_STRING([--with-included-expat], [use bundled expat sources]),, with_included_expat=no)], with_included_expat=no) if test "$NEON_NEED_XML_PARSER" = "yes"; then # Find an XML parser neon_xml_parser=none # Forced choice of expat: case $with_expat in yes) NE_XML_EXPAT([AC_MSG_ERROR([expat library not found, cannot proceed])]) ;; no) ;; */libexpat.la) # Special case for Subversion ne_expdir=`echo $with_expat | sed 's:/libexpat.la$::'` AC_DEFINE(HAVE_EXPAT) AC_DEFINE_UNQUOTED([NE_FMT_XML_SIZE], ["d"]) CPPFLAGS="$CPPFLAGS -I$ne_expdir" if test "x${NEON_TARGET}" = "xlibneon.la"; then NEON_LTLIBS=$with_expat else # no dependency on libexpat => crippled libneon, so do partial install ALLOW_INSTALL=lib fi neon_xml_parser=expat neon_xml_parser_message="expat in $ne_expdir" ;; /*) AC_MSG_ERROR([--with-expat does not take a directory argument]) ;; esac # If expat wasn't specifically enabled and libxml was: if test "${neon_xml_parser}-${with_libxml2}-${with_included_expat}" = "none-yes-no"; then NE_XML_LIBXML2( [AC_MSG_ERROR([libxml2.x library not found, cannot proceed])]) fi # Otherwise, by default search for expat then libxml2: if test "${neon_xml_parser}-${with_included_expat}" = "none-no"; then NE_XML_EXPAT([NE_XML_LIBXML2([:])]) fi # If an XML parser still has not been found, fail or use the bundled expat if test "$neon_xml_parser" = "none"; then m4_if($1, [], [AC_MSG_ERROR([no XML parser was found: expat or libxml 2.x required])], [# Configure the bundled copy of expat NE_XML_BUNDLED_EXPAT($@) neon_xml_parser_message="bundled expat in $1"]) fi AC_MSG_NOTICE([XML parser used: $neon_xml_parser_message]) fi ]) davix-R_0_5_0/deps/libneon/macros/neon.m4000066400000000000000000001117261257152637300203430ustar00rootroot00000000000000# Copyright (C) 1998-2010 Joe Orton -*- autoconf -*- # Copyright (C) 2004 Aleix Conchillo Flaque # # This file is free software; you may copy and/or distribute it with # or without modifications, as long as this notice is preserved. # This software 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. # The above license applies to THIS FILE ONLY, the neon library code # itself may be copied and distributed under the terms of the GNU # LGPL, see COPYING.LIB for more details # This file is part of the neon HTTP/WebDAV client library. # See http://www.webdav.org/neon/ for the latest version. # Please send any feedback to # # Usage: # # NEON_LIBRARY # or NEON_BUNDLED(srcdir, [ACTIONS-IF-BUNDLED], [ACTIONS-IF-NOT_BUNDLED]) # or NEON_VPATH_BUNDLED(srcdir, builddir, # [ACTIONS-IF-BUNDLED], [ACTIONS-IF-NOT-BUNDLED]) # # where srcdir is the location of bundled neon 'src' directory. # If using a VPATH-enabled build, builddir is the location of the # build directory corresponding to srcdir. # # If a bundled build *is* being used, ACTIONS-IF-BUNDLED will be # evaluated. These actions should ensure that 'make' is run # in srcdir, and that one of NEON_NORMAL_BUILD or NEON_LIBTOOL_BUILD # is called. # # After calling one of the above macros, if the NEON_NEED_XML_PARSER # variable is set to "yes", then you must configure an XML parser # too. You can do this your own way, or do it easily using the # NEON_XML_PARSER() macro. Example usage for where we have bundled the # neon sources in a directory called libneon, and bundled expat # sources in a directory called 'expat'. # # NEON_BUNDLED(libneon, [ # NEON_XML_PARSER(expat) # NEON_NORMAL_BUILD # ]) # # Alternatively, for a simple standalone app with neon as a # dependancy, use just: # # NEON_LIBRARY # # and rely on the user installing neon correctly. # # You are free to configure an XML parser any other way you like, # but the end result must be, either expat or libxml will get linked # in, and HAVE_EXPAT or HAVE_LIBXML is defined appropriately. # # To set up the bundled build environment, call # # NEON_NORMAL_BUILD # or # NEON_LIBTOOL_BUILD # # depending on whether you are using libtool to build, or not. # Both these macros take an optional argument specifying the set # of object files you wish to build: if the argument is not given, # all of neon will be built. AC_DEFUN([NEON_BUNDLED],[ neon_bundled_srcdir=$1 neon_bundled_builddir=$1 NEON_COMMON_BUNDLED([$2], [$3]) ]) AC_DEFUN([NEON_VPATH_BUNDLED],[ neon_bundled_srcdir=$1 neon_bundled_builddir=$2 NEON_COMMON_BUNDLED([$3], [$4]) ]) AC_DEFUN([NEON_COMMON_BUNDLED],[ AC_PREREQ(2.50) AC_ARG_WITH(included-neon, AS_HELP_STRING([--with-included-neon], [force use of included neon library]), [neon_force_included="$withval"], [neon_force_included="no"]) NEON_COMMON # The colons are here so there is something to evaluate # in case the argument was not passed. if test "$neon_force_included" = "yes"; then : $1 else : $2 fi ]) dnl Not got any bundled sources: AC_DEFUN([NEON_LIBRARY],[ AC_PREREQ(2.50) neon_force_included=no neon_bundled_srcdir= neon_bundled_builddir= NEON_COMMON ]) AC_DEFUN([NE_DEFINE_VERSIONS], [ NEON_VERSION="${NE_VERSION_MAJOR}.${NE_VERSION_MINOR}.${NE_VERSION_PATCH}${NE_VERSION_TAG}" AC_DEFINE_UNQUOTED([NEON_VERSION], ["${NEON_VERSION}"], [Define to be the neon version string]) AC_DEFINE_UNQUOTED([NE_VERSION_MAJOR], [(${NE_VERSION_MAJOR})], [Define to be neon library major version]) AC_DEFINE_UNQUOTED([NE_VERSION_MINOR], [(${NE_VERSION_MINOR})], [Define to be neon library minor version]) AC_DEFINE_UNQUOTED([NE_VERSION_PATCH], [(${NE_VERSION_PATCH})], [Define to be neon library patch version]) ]) AC_DEFUN([NE_VERSIONS_BUNDLED], [ # Define the current versions. NE_VERSION_MAJOR=0 NE_VERSION_MINOR=29 NE_VERSION_PATCH=6 NE_VERSION_TAG= # 0.29.x is backwards-compatible to 0.27.x, so AGE=2 NE_LIBTOOL_VERSINFO="29:${NE_VERSION_PATCH}:2" NE_DEFINE_VERSIONS ]) dnl Adds an ABI variation tag which will be added to the SONAME of dnl a shared library. e.g. NE_ADD_ABITAG(FOO) AC_DEFUN([NE_ADD_ABITAG], [ if test "x${NE_LIBTOOL_RELEASE}y" = "xy"; then NE_LIBTOOL_RELEASE="$1" else NE_LIBTOOL_RELEASE="${NE_LIBTOOL_RELEASE}-$1" fi ]) dnl Define the minimum required versions, usage: dnl NE_REQUIRE_VERSIONS([major-version], [minor-versions]) dnl e.g. dnl NE_REQUIRE_VERSIONS([0], [24 25]) dnl to require neon 0.24.x or neon 0.25.x. AC_DEFUN([NE_REQUIRE_VERSIONS], [ m4_define([ne_require_major], [$1]) m4_define([ne_require_minor], [$2]) ]) dnl Check that the external library found in a given location dnl matches the min. required version (if any). Requires that dnl NEON_CONFIG be set the the full path of a valid neon-config dnl script dnl dnl Usage: dnl NEON_CHECK_VERSION(ACTIONS-IF-OKAY, ACTIONS-IF-FAILURE) dnl AC_DEFUN([NEON_CHECK_VERSION], [ m4_ifdef([ne_require_major], [ # Check whether the library is of required version ne_save_LIBS="$LIBS" ne_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS `$NEON_CONFIG --cflags`" LIBS="$LIBS `$NEON_CONFIG --libs`" ne_libver=`$NEON_CONFIG --version | sed -e "s/neon //g"` # Check whether it's possible to link against neon AC_CACHE_CHECK([linking against neon], [ne_cv_lib_neon], [AC_LINK_IFELSE( [AC_LANG_PROGRAM([[#include ]], [[ne_version_match(0, 0);]])], [ne_cv_lib_neon=yes], [ne_cv_lib_neon=no])]) if test "$ne_cv_lib_neon" = "yes"; then ne_cv_lib_neonver=no for v in ne_require_minor; do case $ne_libver in ne_require_major.$v.*) ne_cv_lib_neonver=yes ;; esac done fi ne_goodver=$ne_cv_lib_neonver LIBS=$ne_save_LIBS CFLAGS=$ne_save_CFLAGS ], [ # NE_REQUIRE_VERSIONS not used; presume all versions OK! ne_goodver=yes ne_libver="(version unknown)" ]) if test "$ne_goodver" = "yes"; then AC_MSG_NOTICE([using neon library $ne_libver]) $1 else AC_MSG_NOTICE([incompatible neon library version $ne_libver: wanted ne_require_major.ne_require_minor]) $2 fi]) dnl NEON_CHECK_SUPPORT(feature, var, name) AC_DEFUN([NEON_CHECK_SUPPORT], [ if $NEON_CONFIG --support $1 >/dev/null; then NE_ENABLE_SUPPORT($2, [$3 is supported by neon]) else NE_DISABLE_SUPPORT($2, [$3 is not supported by neon]) fi ]) dnl enable support for feature $1 with define NE_HAVE_$1, message $2 AC_DEFUN([NE_ENABLE_SUPPORT], [ NE_FLAG_$1=yes AC_SUBST(NE_FLAG_$1) AC_DEFINE([NE_HAVE_]$1, 1, [Defined if $1 is supported]) m4_if([$2], [], [ne_$1_message="support enabled" AC_MSG_NOTICE([$1 support is enabled])], [ne_$1_message="$2" AC_MSG_NOTICE([$2])]) ]) dnl Disable support for feature $1, giving message $2 AC_DEFUN([NE_DISABLE_SUPPORT], [ NE_FLAG_$1=no AC_SUBST(NE_FLAG_$1) m4_if([$2], [], [ne_$1_message="not supported" AC_MSG_NOTICE([$1 support is not enabled])], [ne_$1_message="$2" AC_MSG_NOTICE([$2])]) ]) AC_DEFUN([NEON_USE_EXTERNAL], [ # Configure to use an external neon, given a neon-config script # found at $NEON_CONFIG. neon_prefix=`$NEON_CONFIG --prefix` NEON_CHECK_VERSION([ # Pick up CFLAGS and LIBS needed CFLAGS="$CFLAGS `$NEON_CONFIG --cflags`" NEON_LIBS="$NEON_LIBS `$NEON_CONFIG --libs`" # Pick up library version set dummy `$NEON_CONFIG --version | sed 's/\./ /g'` NE_VERSION_MAJOR=[$]3; NE_VERSION_MINOR=[$]4; NE_VERSION_PATCH=[$]5 NE_DEFINE_VERSIONS neon_library_message="library in ${neon_prefix} (${NEON_VERSION})" neon_xml_parser_message="using whatever neon uses" NEON_CHECK_SUPPORT([ssl], [SSL], [SSL]) NEON_CHECK_SUPPORT([zlib], [ZLIB], [zlib]) NEON_CHECK_SUPPORT([ipv6], [IPV6], [IPv6]) NEON_CHECK_SUPPORT([lfs], [LFS], [LFS]) NEON_CHECK_SUPPORT([ts_ssl], [TS_SSL], [thread-safe SSL]) neon_got_library=yes if test $NE_FLAG_LFS = yes; then NEON_FORMAT(off64_t) AC_DEFINE_UNQUOTED([NE_FMT_NE_OFF_T], [NE_FMT_OFF64_T], [Define to be printf format string for ne_off_t]) else AC_DEFINE_UNQUOTED([NE_FMT_NE_OFF_T], [NE_FMT_OFF_T]) fi ], [neon_got_library=no]) ]) AC_DEFUN([NEON_COMMON],[ AC_REQUIRE([NEON_COMMON_CHECKS]) AC_ARG_WITH(neon, [ --with-neon[[=DIR]] specify location of neon library], [case $withval in yes|no) neon_force_external=$withval; neon_ext_path= ;; *) neon_force_external=yes; neon_ext_path=$withval ;; esac;], [ neon_force_external=no neon_ext_path= ]) if test "$neon_force_included" = "no"; then # There is no included neon source directory, or --with-included-neon # wasn't given (so we're not forced to use it). # Default to no external neon. neon_got_library=no if test "x$neon_ext_path" = "x"; then AC_PATH_PROG([NEON_CONFIG], neon-config, none) if test "x${NEON_CONFIG}" = "xnone"; then AC_MSG_NOTICE([no external neon library found]) elif test -x "${NEON_CONFIG}"; then NEON_USE_EXTERNAL else AC_MSG_NOTICE([ignoring non-executable ${NEON_CONFIG}]) fi else AC_MSG_CHECKING([for neon library in $neon_ext_path]) NEON_CONFIG="$neon_ext_path/bin/neon-config" if test -x ${NEON_CONFIG}; then AC_MSG_RESULT([found]) NEON_USE_EXTERNAL else AC_MSG_RESULT([not found]) # ...will fail since force_external=yes fi fi if test "$neon_got_library" = "no"; then if test $neon_force_external = yes; then AC_MSG_ERROR([could not use external neon library]) elif test -n "$neon_bundled_srcdir"; then # Couldn't find external neon, forced to use bundled sources neon_force_included="yes" else # Couldn't find neon, and don't have bundled sources AC_MSG_ERROR(could not find neon) fi fi fi if test "$neon_force_included" = "yes"; then NE_VERSIONS_BUNDLED AC_MSG_NOTICE([using bundled neon ($NEON_VERSION)]) NEON_BUILD_BUNDLED="yes" LIBNEON_SOURCE_CHECKS CFLAGS="$CFLAGS -I$neon_bundled_srcdir" NEON_LIBS="-L$neon_bundled_builddir -lneon $NEON_LIBS" NEON_NEED_XML_PARSER=yes neon_library_message="included libneon (${NEON_VERSION})" else # Don't need to configure an XML parser NEON_NEED_XML_PARSER=no NEON_BUILD_BUNDLED=no fi AC_SUBST(NEON_BUILD_BUNDLED) ]) dnl AC_SEARCH_LIBS done differently. Usage: dnl NE_SEARCH_LIBS(function, libnames, [extralibs], [actions-if-not-found], dnl [actions-if-found]) dnl Tries to find 'function' by linking againt `-lLIB $NEON_LIBS' for each dnl LIB in libnames. If link fails and 'extralibs' is given, will also dnl try linking against `-lLIB extralibs $NEON_LIBS`. dnl Once link succeeds, `-lLIB [extralibs]` is prepended to $NEON_LIBS, and dnl `actions-if-found' are executed, if given. dnl If link never succeeds, run `actions-if-not-found', if given, else dnl give an error and fail configure. AC_DEFUN([NE_SEARCH_LIBS], [ AC_REQUIRE([NE_CHECK_OS]) AC_CACHE_CHECK([for library containing $1], [ne_cv_libsfor_$1], [ AC_LINK_IFELSE( [AC_LANG_PROGRAM([], [[$1();]])], [ne_cv_libsfor_$1="none needed"], [ ne_sl_save_LIBS=$LIBS ne_cv_libsfor_$1="not found" for lib in $2; do # The w32api libraries link using the stdcall calling convention. case ${lib}-${ne_cv_os_uname} in ws2_32-MINGW*) ne__code="__stdcall $1();" ;; *) ne__code="$1();" ;; esac LIBS="$ne_sl_save_LIBS -l$lib $NEON_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [$ne__code])], [ne_cv_libsfor_$1="-l$lib"; break]) m4_if($3, [], [], dnl If $3 is specified, then... [LIBS="$ne_sl_save_LIBS -l$lib $3 $NEON_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [$ne__code])], [ne_cv_libsfor_$1="-l$lib $3"; break])]) done LIBS=$ne_sl_save_LIBS])]) if test "$ne_cv_libsfor_$1" = "not found"; then m4_if([$4], [], [AC_MSG_ERROR([could not find library containing $1])], [$4]) elif test "$ne_cv_libsfor_$1" = "none needed"; then m4_if([$5], [], [:], [$5]) else NEON_LIBS="$ne_cv_libsfor_$1 $NEON_LIBS" $5 fi]) dnl Check for presence and suitability of zlib library AC_DEFUN([NEON_ZLIB], [ AC_ARG_WITH(zlib, AS_HELP_STRING([--without-zlib], [disable zlib support]), ne_use_zlib=$withval, ne_use_zlib=yes) if test "$ne_use_zlib" = "yes"; then AC_CHECK_HEADER(zlib.h, [ AC_CHECK_LIB(z, inflate, [ NEON_LIBS="$NEON_LIBS -lz" NE_ENABLE_SUPPORT(ZLIB, [zlib support enabled, using -lz]) ], [NE_DISABLE_SUPPORT(ZLIB, [zlib library not found])]) ], [NE_DISABLE_SUPPORT(ZLIB, [zlib header not found])]) else NE_DISABLE_SUPPORT(ZLIB, [zlib not enabled]) fi ]) AC_DEFUN([NE_CHECK_OS], [ # Check for Darwin, which needs extra cpp and linker flags. AC_CACHE_CHECK([for uname], ne_cv_os_uname, [ ne_cv_os_uname=`uname -s 2>/dev/null` ]) if test "$ne_cv_os_uname" = "Darwin"; then CPPFLAGS="$CPPFLAGS -no-cpp-precomp" LDFLAGS="$LDFLAGS -flat_namespace" # poll has various issues in various Darwin releases if test x${ac_cv_func_poll+set} != xset; then ac_cv_func_poll=no fi fi ]) AC_DEFUN([NEON_COMMON_CHECKS], [ # These checks are done whether or not the bundled neon build # is used. ifdef([AC_USE_SYSTEM_EXTENSIONS], [AC_USE_SYSTEM_EXTENSIONS], [AC_ISC_POSIX]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_C_INLINE]) AC_REQUIRE([AC_C_CONST]) AC_REQUIRE([AC_TYPE_SIZE_T]) AC_REQUIRE([AC_TYPE_OFF_T]) AC_REQUIRE([NE_CHECK_OS]) AC_REQUIRE([AC_PROG_MAKE_SET]) AC_REQUIRE([AC_HEADER_STDC]) AC_CHECK_HEADERS([errno.h stdarg.h string.h stdlib.h]) NEON_FORMAT(size_t,,u) dnl size_t is unsigned; use %u formats NEON_FORMAT(off_t) NEON_FORMAT(ssize_t) ]) AC_DEFUN([NEON_FORMAT_PREP], [ AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) if test "$GCC" = "yes"; then AC_CACHE_CHECK([for gcc -Wformat -Werror sanity], ne_cv_cc_werror, [ # See whether a simple test program will compile without errors. ne_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -Wformat -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[int i = 42; printf("%d", i);]])], [ne_cv_cc_werror=yes], [ne_cv_cc_werror=no]) CPPFLAGS=$ne_save_CPPFLAGS]) ne_fmt_trycompile=$ne_cv_cc_werror else ne_fmt_trycompile=no fi ]) dnl Check for LFS support AC_DEFUN([NE_LARGEFILE], [ dnl Need the size of off_t AC_REQUIRE([NEON_COMMON_CHECKS]) if test -z "$ac_cv_sizeof_off_t"; then NE_DISABLE_SUPPORT(LFS, [LFS support omitted: off_t size unknown!]) elif test $ac_cv_sizeof_off_t != 4; then NE_DISABLE_SUPPORT(LFS, [LFS support unnecessary, off_t is not 32-bit]) AC_CHECK_FUNCS([strtoll strtoq], [break]) elif test -z "$ac_cv_sizeof_long_long"; then NE_DISABLE_SUPPORT(LFS, [LFS support omitted: long long size unknown]) elif test $ac_cv_sizeof_long_long != 8; then NE_DISABLE_SUPPORT(LFS, [LFS support omitted: long long not 64-bit]) else ne_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE" AC_CHECK_TYPE(off64_t, [ NEON_FORMAT(off64_t) ne_lfsok=no AC_CHECK_FUNCS([strtoll strtoq], [ne_lfsok=yes; break]) AC_CHECK_FUNCS([lseek64 fstat64], [], [ne_lfsok=no; break]) if test x$ne_lfsok = xyes; then NE_ENABLE_SUPPORT(LFS, [LFS (large file) support enabled]) NEON_CFLAGS="$NEON_CFLAGS -D_LARGEFILE64_SOURCE -DNE_LFS" ne_save_CPPFLAGS="$CPPFLAGS -DNE_LFS" else NE_DISABLE_SUPPORT(LFS, [LFS support omitted: 64-bit support functions not found]) fi], [NE_DISABLE_SUPPORT(LFS, [LFS support omitted: off64_t type not found])]) CPPFLAGS=$ne_save_CPPFLAGS fi if test "$NE_FLAG_LFS" = "yes"; then AC_DEFINE_UNQUOTED([NE_FMT_NE_OFF_T], [NE_FMT_OFF64_T], [Define to be printf format string for ne_off_t]) else AC_DEFINE_UNQUOTED([NE_FMT_NE_OFF_T], [NE_FMT_OFF_T]) fi ]) dnl NEON_FORMAT(TYPE[, HEADERS[, [SPECIFIER]]) dnl dnl This macro finds out which modifier is needed to create a dnl printf format string suitable for printing integer type TYPE (which dnl may be an int, long, or long long). dnl The default specifier is 'd', if SPECIFIER is not given. dnl TYPE may be defined in HEADERS; sys/types.h is always used first. AC_DEFUN([NEON_FORMAT], [ AC_REQUIRE([NEON_FORMAT_PREP]) AC_CHECK_SIZEOF($1,, [AC_INCLUDES_DEFAULT $2]) dnl Work out which specifier character to use m4_ifdef([ne_spec], [m4_undefine([ne_spec])]) m4_if($#, 3, [m4_define(ne_spec,$3)], [m4_define(ne_spec,d)]) m4_ifdef([ne_cvar], [m4_undefine([ne_cvar])])dnl m4_define([ne_cvar], m4_translit(ne_cv_fmt_[$1], [ ], [_]))dnl AC_CACHE_CHECK([how to print $1], [ne_cvar], [ ne_cvar=none if test $ne_fmt_trycompile = yes; then oflags="$CPPFLAGS" # Consider format string mismatches as errors CPPFLAGS="$CPPFLAGS -Wformat -Werror" dnl obscured for m4 quoting: "for str in d ld lld; do" for str in ne_spec l]ne_spec[ ll]ne_spec[; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include $2 #include ]], [[$1 i = 1; printf("%$str", i);]])], [ne_cvar=$str; break]) done CPPFLAGS=$oflags else # Best guess. Don't have to be too precise since we probably won't # get a warning message anyway. case $ac_cv_sizeof_]m4_translit($1, [ ], [_])[ in $ac_cv_sizeof_int) ne_cvar="ne_spec" ;; $ac_cv_sizeof_long) ne_cvar="l]ne_spec[" ;; $ac_cv_sizeof_long_long) ne_cvar="ll]ne_spec[" ;; esac fi ]) if test "x$ne_cvar" = "xnone"; then AC_MSG_ERROR([format string for $1 not found]) fi AC_DEFINE_UNQUOTED([NE_FMT_]m4_translit($1, [a-z ], [A-Z_]), "$ne_cvar", [Define to be printf format string for $1]) ]) dnl Wrapper for AC_CHECK_FUNCS; uses libraries from $NEON_LIBS. AC_DEFUN([NE_CHECK_FUNCS], [ ne_cf_save_LIBS=$LIBS LIBS="$LIBS $NEON_LIBS" AC_CHECK_FUNCS($@) LIBS=$ne_cf_save_LIBS]) dnl Checks needed when compiling the neon source. AC_DEFUN([LIBNEON_SOURCE_CHECKS], [ dnl Run all the normal C language/compiler tests AC_REQUIRE([NEON_COMMON_CHECKS]) dnl Needed for building the MD5 code. AC_REQUIRE([AC_C_BIGENDIAN]) dnl Is strerror_r present; if so, which variant AC_REQUIRE([AC_FUNC_STRERROR_R]) AC_CHECK_HEADERS([sys/time.h limits.h sys/select.h arpa/inet.h libintl.h \ signal.h sys/socket.h netinet/in.h netinet/tcp.h netdb.h sys/poll.h \ sys/limits.h fcntl.h iconv.h],,, [AC_INCLUDES_DEFAULT /* netinet/tcp.h requires netinet/in.h on some platforms. */ #ifdef HAVE_NETINET_IN_H #include #endif]) AC_REQUIRE([NE_SNPRINTF]) AC_CACHE_CHECK([for timezone global], ne_cv_cc_timezone, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[time_t t = 0 - timezone; timezone = 1;]])], ne_cv_cc_timezone=yes, ne_cv_cc_timezone=no)]) if test "$ne_cv_cc_timezone" = "yes"; then AC_DEFINE([HAVE_TIMEZONE], 1, [Define if the timezone global is available]) fi dnl Check for large file support NE_LARGEFILE AC_REPLACE_FUNCS(strcasecmp) AC_CHECK_FUNCS(signal setvbuf setsockopt stpcpy poll fcntl getsockopt) if test "x${ac_cv_func_poll}${ac_cv_header_sys_poll_h}y" = "xyesyesy"; then AC_DEFINE([NE_USE_POLL], 1, [Define if poll() should be used]) fi if test "$ac_cv_func_stpcpy" = "yes"; then AC_CHECK_DECLS(stpcpy) fi # Modern AIXes with the "Linux-like" libc have an undeclared stpcpy AH_BOTTOM([#if defined(HAVE_STPCPY) && defined(HAVE_DECL_STPCPY) && !HAVE_DECL_STPCPY && !defined(stpcpy) char *stpcpy(char *, const char *); #endif]) # Unixware 7 can only link gethostbyname with -lnsl -lsocket # Pick up -lsocket first, then the gethostbyname check will work. # Haiku requires -lnetwork for socket functions. NE_SEARCH_LIBS(socket, socket inet ws2_32 network) # Enable getaddrinfo support if it, gai_strerror and inet_ntop are # all available. NE_SEARCH_LIBS(getaddrinfo, nsl,, [ne_enable_gai=no], [# HP-UX boxes commonly get into a state where getaddrinfo is present # but borked: http://marc.theaimsgroup.com/?l=apr-dev&m=107730955207120&w=2 case x`uname -sr 2>/dev/null`y in xHP-UX*11.[[01]]*y) AC_MSG_NOTICE([getaddrinfo support disabled on HP-UX 11.0x/11.1x]) ;; *) ne_enable_gai=yes NE_CHECK_FUNCS(gai_strerror getnameinfo inet_ntop inet_pton,, [ne_enable_gai=no; break]) ;; esac ]) if test $ne_enable_gai = yes; then NE_ENABLE_SUPPORT(IPV6, [IPv6 support is enabled]) AC_DEFINE(USE_GETADDRINFO, 1, [Define if getaddrinfo() should be used]) AC_CACHE_CHECK([for working AI_ADDRCONFIG], [ne_cv_gai_addrconfig], [ AC_RUN_IFELSE([AC_LANG_PROGRAM([#include #include ], [struct addrinfo hints = {0}, *result; hints.ai_flags = AI_ADDRCONFIG; if (getaddrinfo("localhost", NULL, &hints, &result) != 0) return 1;])], ne_cv_gai_addrconfig=yes, ne_cv_gai_addrconfig=no, ne_cv_gai_addrconfig=no)]) if test $ne_cv_gai_addrconfig = yes; then AC_DEFINE(USE_GAI_ADDRCONFIG, 1, [Define if getaddrinfo supports AI_ADDRCONFIG]) fi else # Checks for non-getaddrinfo() based resolver interfaces. # QNX has gethostbyname in -lsocket. BeOS only has it in -lbind. # CygWin/Winsock2 has it in -lws2_32, allegedly. # Haiku requires -lnetwork for socket functions. NE_SEARCH_LIBS(gethostbyname, socket nsl bind ws2_32 network) NE_SEARCH_LIBS(hstrerror, resolv,,[:]) NE_CHECK_FUNCS(hstrerror) # Older Unixes don't declare h_errno. AC_CHECK_DECLS(h_errno,,,[#include ]) AC_CHECK_TYPE(in_addr_t,,[ AC_DEFINE([in_addr_t], [unsigned int], [Define if in_addr_t is not available])], [ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif ]) fi AC_CHECK_TYPES(socklen_t,, # Linux accept(2) says this should be size_t for SunOS 5... gah. [AC_DEFINE([socklen_t], [int], [Define if socklen_t is not available])],[ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif ]) AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,, [#include ]) if test ${ac_cv_member_struct_tm_tm_gmtoff}${ac_cv_member_struct_tm___tm_gmtoff}${ne_cv_cc_timezone} = nonono; then AC_MSG_WARN([no timezone handling in date parsing on this platform]) fi ifdef([neon_no_zlib], [NE_DISABLE_SUPPORT(ZLIB, [zlib not supported])], [NEON_ZLIB()]) # Conditionally enable ACL support AC_MSG_CHECKING([whether to enable ACL support in neon]) if test "x$neon_no_acl" = "xyes"; then AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_oldacl ne_acl3744" fi NEON_SSL() NEON_GSSAPI() NEON_LIBPROXY() AC_SUBST(NEON_CFLAGS) AC_SUBST(NEON_LIBS) AC_SUBST(NEON_LTLIBS) ]) dnl Call to put lib/snprintf.o in LIBOBJS and define HAVE_SNPRINTF_H dnl if snprintf isn't in libc. AC_DEFUN([NEON_REPLACE_SNPRINTF], [ # Check for snprintf AC_CHECK_FUNC(snprintf,,[ AC_DEFINE(HAVE_SNPRINTF_H, 1, [Define if need to include snprintf.h]) AC_LIBOBJ(lib/snprintf)]) ]) dnl turn off webdav, boo hoo. AC_DEFUN([NEON_WITHOUT_WEBDAV], [ neon_no_webdav=yes neon_no_acl=yes NEON_NEED_XML_PARSER=no neon_xml_parser_message="none needed" ]) dnl Turn off zlib support AC_DEFUN([NEON_WITHOUT_ZLIB], [ define(neon_no_zlib, yes) ]) AC_DEFUN([NEON_WITHOUT_ACL], [ # Turn off ACL support neon_no_acl=yes ]) dnl Common macro to NEON_LIBTOOL_BUILD and NEON_NORMAL_BUILD dnl Sets NEONOBJS appropriately if it has not already been set. dnl dnl NOT FOR EXTERNAL USE: use LIBTOOL_BUILD or NORMAL_BUILD. dnl AC_DEFUN([NEON_COMMON_BUILD], [ # Using the default set of object files to build. # Add the extension to EXTRAOBJS ne="$NEON_EXTRAOBJS" NEON_EXTRAOBJS= for o in $ne; do NEON_EXTRAOBJS="$NEON_EXTRAOBJS $o.$NEON_OBJEXT" done # Was DAV support explicitly turned off? if test "x$neon_no_webdav" = "xyes"; then # No WebDAV support NEONOBJS="$NEONOBJS \$(NEON_BASEOBJS)" NE_DISABLE_SUPPORT(DAV, [WebDAV support is not enabled]) NE_ADD_ABITAG(NODAV) else # WebDAV support NEONOBJS="$NEONOBJS \$(NEON_DAVOBJS)" NE_ENABLE_SUPPORT(DAV, [WebDAV support is enabled]) fi AC_SUBST(NEON_TARGET) AC_SUBST(NEON_OBJEXT) AC_SUBST(NEONOBJS) AC_SUBST(NEON_EXTRAOBJS) AC_SUBST(NEON_LINK_FLAGS) ]) # The libtoolized build case: AC_DEFUN([NEON_LIBTOOL_BUILD], [ NEON_TARGET=libneon.la NEON_OBJEXT=lo NEON_COMMON_BUILD($#, $*) ]) dnl Find 'ar' and 'ranlib', fail if ar isn't found. AC_DEFUN([NE_FIND_AR], [ # Search in /usr/ccs/bin for Solaris ne_PATH=$PATH:/usr/ccs/bin AC_PATH_TOOL(AR, ar, notfound, $ne_PATH) if test "x$AR" = "xnotfound"; then AC_MSG_ERROR([could not find ar tool]) fi AC_PATH_TOOL(RANLIB, ranlib, :, $ne_PATH) ]) # The non-libtool build case: AC_DEFUN([NEON_NORMAL_BUILD], [ NEON_TARGET=libneon.a NEON_OBJEXT=o AC_REQUIRE([NE_FIND_AR]) NEON_COMMON_BUILD($#, $*) ]) AC_DEFUN([NE_SNPRINTF], [ AC_CHECK_FUNCS(snprintf vsnprintf,,[ ne_save_LIBS=$LIBS LIBS="$LIBS -lm" # Always need -lm AC_CHECK_LIB(trio, trio_vsnprintf, [AC_CHECK_HEADERS(trio.h,, AC_MSG_ERROR([trio installation problem? libtrio found but not trio.h])) AC_MSG_NOTICE(using trio printf replacement library) NEON_LIBS="$NEON_LIBS -ltrio -lm" AC_DEFINE(HAVE_TRIO, 1, [Use trio printf replacement library])], [AC_MSG_NOTICE([no vsnprintf/snprintf detected in C library]) AC_MSG_ERROR([Install the trio library from http://daniel.haxx.se/projects/trio/])]) LIBS=$ne_save_LIBS break ])]) dnl Usage: NE_CHECK_OPENSSLVER(variable, version-string, version-hex) dnl Define 'variable' to 'yes' if OpenSSL version is >= version-hex AC_DEFUN([NE_CHECK_OPENSSLVER], [ AC_CACHE_CHECK([OpenSSL version is >= $2], $1, [ AC_EGREP_CPP(good, [#include #if OPENSSL_VERSION_NUMBER >= $3 good #endif], [$1=yes], [$1=no])])]) dnl Less noisy replacement for PKG_CHECK_MODULES AC_DEFUN([NE_PKG_CONFIG], [ m4_define([ne_cvar], m4_translit(ne_cv_pkg_[$2], [.-], [__]))dnl AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test "$PKG_CONFIG" = "no"; then : Not using pkg-config $4 else AC_CACHE_CHECK([for $2 pkg-config data], ne_cvar, [if $PKG_CONFIG $2; then ne_cvar=yes else ne_cvar=no fi]) if test "$ne_cvar" = "yes"; then $1_CFLAGS=`$PKG_CONFIG --cflags $2` $1_LIBS=`$PKG_CONFIG --libs $2` : Using provided pkg-config data $3 else : No pkg-config for $2 provided $4 fi fi m4_undefine([ne_cvar]) ]) dnl Check for an SSL library (GNU TLS or OpenSSL) AC_DEFUN([NEON_SSL], [ AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=openssl|gnutls], [enable SSL support (default OpenSSL)])) AC_ARG_WITH(egd, [[ --with-egd[=PATH] enable EGD support [using EGD socket at PATH]]]) AC_ARG_WITH(pakchois, AS_HELP_STRING([--without-pakchois], [disable support for PKCS#11 using pakchois])) case $with_ssl in /*) AC_MSG_NOTICE([to use SSL libraries in non-standard locations, try --with-ssl --with-libs=$with_ssl]) AC_MSG_ERROR([--with-ssl does not take a path argument]) ;; yes|openssl) NE_PKG_CONFIG(NE_SSL, openssl, [AC_MSG_NOTICE(using SSL library configuration from pkg-config) CPPFLAGS="$CPPFLAGS ${NE_SSL_CFLAGS}" NEON_LIBS="$NEON_LIBS ${NE_SSL_LIBS}"], [# Either OpenSSL library may require -ldl if built with dynamic engine support NE_SEARCH_LIBS(RSA_new, crypto, -ldl) NE_SEARCH_LIBS(SSL_library_init, ssl, -ldl)]) AC_CHECK_HEADERS(openssl/ssl.h openssl/opensslv.h,, [AC_MSG_ERROR([OpenSSL headers not found, cannot enable SSL support])]) # Enable EGD support if using 0.9.7 or newer NE_CHECK_OPENSSLVER(ne_cv_lib_ssl097, 0.9.7, 0x00907000L) if test "$ne_cv_lib_ssl097" = "yes"; then AC_MSG_NOTICE([OpenSSL >= 0.9.7; EGD support not needed in neon]) NE_ENABLE_SUPPORT(SSL, [SSL support enabled, using OpenSSL (0.9.7 or later)]) NE_CHECK_FUNCS(CRYPTO_set_idptr_callback SSL_SESSION_cmp) else # Fail if OpenSSL is older than 0.9.6 NE_CHECK_OPENSSLVER(ne_cv_lib_ssl096, 0.9.6, 0x00906000L) if test "$ne_cv_lib_ssl096" != "yes"; then AC_MSG_ERROR([OpenSSL 0.9.6 or later is required]) fi NE_ENABLE_SUPPORT(SSL, [SSL support enabled, using OpenSSL (0.9.6 or later)]) case "$with_egd" in yes|no) ne_cv_lib_sslegd=$with_egd ;; /*) ne_cv_lib_sslegd=yes AC_DEFINE_UNQUOTED([EGD_PATH], "$with_egd", [Define to specific EGD socket path]) ;; *) # Guess whether EGD support is needed AC_CACHE_CHECK([whether to enable EGD support], [ne_cv_lib_sslegd], [if test -r /dev/random || test -r /dev/urandom; then ne_cv_lib_sslegd=no else ne_cv_lib_sslegd=yes fi]) ;; esac if test "$ne_cv_lib_sslegd" = "yes"; then AC_MSG_NOTICE([EGD support enabled for seeding OpenSSL PRNG]) AC_DEFINE([ENABLE_EGD], 1, [Define if EGD should be supported]) fi fi AC_DEFINE([HAVE_OPENSSL], 1, [Define if OpenSSL support is enabled]) NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_openssl" AC_DEFINE([HAVE_NTLM], 1, [Define if NTLM is supported]) ;; gnutls) NE_PKG_CONFIG(NE_SSL, gnutls, [AC_MSG_NOTICE(using GnuTLS configuration from pkg-config) CPPFLAGS="$CPPFLAGS ${NE_SSL_CFLAGS}" NEON_LIBS="$NEON_LIBS ${NE_SSL_LIBS}" ne_gnutls_ver=`$PKG_CONFIG --modversion gnutls` ], [ # Fall back on libgnutls-config script AC_PATH_PROG(GNUTLS_CONFIG, libgnutls-config, no) if test "$GNUTLS_CONFIG" = "no"; then AC_MSG_ERROR([could not find libgnutls-config in \$PATH]) fi CPPFLAGS="$CPPFLAGS `$GNUTLS_CONFIG --cflags`" NEON_LIBS="$NEON_LIBS `$GNUTLS_CONFIG --libs`" ne_gnutls_ver=`$GNUTLS_CONFIG --version` ]) AC_CHECK_HEADER([gnutls/gnutls.h],, [AC_MSG_ERROR([could not find gnutls/gnutls.h in include path])]) NE_ENABLE_SUPPORT(SSL, [SSL support enabled, using GnuTLS $ne_gnutls_ver]) NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_gnutls" AC_DEFINE([HAVE_GNUTLS], 1, [Define if GnuTLS support is enabled]) # Check for functions in later releases NE_CHECK_FUNCS([gnutls_session_get_data2 gnutls_x509_dn_get_rdn_ava \ gnutls_sign_callback_set \ gnutls_certificate_get_x509_cas \ gnutls_certificate_verify_peers2]) # fail if gnutls_certificate_verify_peers2 is not found if test x${ac_cv_func_gnutls_certificate_verify_peers2} != xyes; then AC_MSG_ERROR([GnuTLS version predates gnutls_certificate_verify_peers2, newer version required]) fi # Check for iconv support if using the new RDN access functions: if test ${ac_cv_func_gnutls_x509_dn_get_rdn_ava}X${ac_cv_header_iconv_h} = yesXyes; then AC_CHECK_FUNCS(iconv) fi ;; *) # Default to off; only create crypto-enabled binaries if requested. NE_DISABLE_SUPPORT(SSL, [SSL support is not enabled]) NE_DISABLE_SUPPORT(TS_SSL, [Thread-safe SSL support is not enabled]) NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_stubssl" ;; esac AC_SUBST(NEON_SUPPORTS_SSL) AC_ARG_WITH(ca-bundle, AS_HELP_STRING(--with-ca-bundle, specify filename of an SSL CA root bundle),, with_ca_bundle=no) case ${NE_FLAG_SSL}-${with_ca_bundle} in *-no) ;; yes-*) AC_DEFINE_UNQUOTED([NE_SSL_CA_BUNDLE], ["${with_ca_bundle}"], [Define to be filename of an SSL CA root bundle]) AC_MSG_NOTICE([Using ${with_ca_bundle} as default SSL CA bundle]) ;; esac AC_ARG_ENABLE(threadsafe-ssl, AS_HELP_STRING(--enable-threadsafe-ssl=posix, [enable SSL library thread-safety using POSIX threads: suitable CC/CFLAGS/LIBS must be used to make the POSIX library interfaces available]),, enable_threadsafe_ssl=no) case $enable_threadsafe_ssl in posix|yes) ne_pthr_ok=yes AC_CHECK_FUNCS([pthread_mutex_init pthread_mutex_lock],,[ne_pthr_ok=no]) if test "${ne_pthr_ok}" = "no"; then AC_MSG_ERROR([could not find POSIX mutex interfaces; (try CC="${CC} -pthread"?)]) fi NE_ENABLE_SUPPORT(TS_SSL, [Thread-safe SSL supported using POSIX threads]) ;; *) NE_DISABLE_SUPPORT(TS_SSL, [Thread-safe SSL not supported]) ;; esac case ${with_pakchois}X${ac_cv_func_gnutls_sign_callback_set}Y${ne_cv_lib_ssl097} in noX*Y*) ;; *X*Yyes|*XyesY*) # PKCS#11... ho! NE_PKG_CONFIG(NE_PK11, pakchois, [AC_MSG_NOTICE([[using pakchois for PKCS#11 support]]) AC_DEFINE(HAVE_PAKCHOIS, 1, [Define if pakchois library supported]) CPPFLAGS="$CPPFLAGS ${NE_PK11_CFLAGS}" NEON_LIBS="${NEON_LIBS} ${NE_PK11_LIBS}"], [AC_MSG_NOTICE([[pakchois library not found; no PKCS#11 support]])]) ;; esac ]) dnl -- end defun NEON_SSL dnl Check for Kerberos installation AC_DEFUN([NEON_GSSAPI], [ AC_ARG_WITH(gssapi, AS_HELP_STRING(--without-gssapi, disable GSSAPI support)) if test "$with_gssapi" != "no"; then AC_PATH_PROG([KRB5_CONFIG], krb5-config, none, $PATH:/usr/kerberos/bin) else KRB5_CONFIG=none fi if test "x$KRB5_CONFIG" != "xnone"; then ne_save_CPPFLAGS=$CPPFLAGS ne_save_LIBS=$NEON_LIBS NEON_LIBS="$NEON_LIBS `${KRB5_CONFIG} --libs gssapi`" CPPFLAGS="$CPPFLAGS `${KRB5_CONFIG} --cflags gssapi`" # MIT and Heimdal put gssapi.h in different places AC_CHECK_HEADERS(gssapi/gssapi.h gssapi.h, [ NE_CHECK_FUNCS(gss_init_sec_context, [ ne_save_CPPFLAGS=$CPPFLAGS ne_save_LIBS=$NEON_LIBS AC_MSG_NOTICE([GSSAPI authentication support enabled]) AC_DEFINE(HAVE_GSSAPI, 1, [Define if GSSAPI support is enabled]) AC_CHECK_HEADERS(gssapi/gssapi_generic.h) # Older versions of MIT Kerberos lack GSS_C_NT_HOSTBASED_SERVICE AC_CHECK_DECL([GSS_C_NT_HOSTBASED_SERVICE],, [AC_DEFINE([GSS_C_NT_HOSTBASED_SERVICE], gss_nt_service_name, [Define if GSS_C_NT_HOSTBASED_SERVICE is not defined otherwise])], [#ifdef HAVE_GSSAPI_GSSAPI_H #include #else #include #endif])]) break ]) CPPFLAGS=$ne_save_CPPFLAGS NEON_LIBS=$ne_save_LIBS fi]) AC_DEFUN([NEON_LIBPROXY], [ AC_ARG_WITH(libproxy, AS_HELP_STRING(--without-libproxy, disable libproxy support)) if test "x$with_libproxy" != "xno"; then NE_PKG_CONFIG(NE_PXY, libproxy-1.0, [AC_DEFINE(HAVE_LIBPROXY, 1, [Define if libproxy is supported]) CPPFLAGS="$CPPFLAGS $NE_PXY_CFLAGS" NEON_LIBS="$NEON_LIBS ${NE_PXY_LIBS}" NE_ENABLE_SUPPORT(LIBPXY, [libproxy support enabled])], [NE_DISABLE_SUPPORT(LIBPXY, [libproxy support not enabled])]) else NE_DISABLE_SUPPORT(LIBPXY, [libproxy support not enabled]) fi ]) dnl Adds an --enable-warnings argument to configure to allow enabling dnl compiler warnings AC_DEFUN([NEON_WARNINGS],[ AC_REQUIRE([AC_PROG_CC]) dnl so that $GCC is set AC_ARG_ENABLE(warnings, AS_HELP_STRING(--enable-warnings, [enable compiler warnings])) if test "$enable_warnings" = "yes"; then case $GCC:`uname` in yes:*) CFLAGS="$CFLAGS -Wall -Wmissing-declarations -Wshadow -Wreturn-type -Wsign-compare -Wundef -Wpointer-arith -Wbad-function-cast -Wformat-security" if test -z "$with_ssl" -o "$with_ssl" = "no"; then # OpenSSL headers fail strict prototypes checks CFLAGS="$CFLAGS -Wstrict-prototypes" fi ;; no:OSF1) CFLAGS="$CFLAGS -check -msg_disable returnchecks -msg_disable alignment -msg_disable overflow" ;; no:IRIX) CFLAGS="$CFLAGS -fullwarn" ;; no:UnixWare) CFLAGS="$CFLAGS -v" ;; *) AC_MSG_WARN([warning flags unknown for compiler on this platform]) ;; esac fi ]) dnl Adds an --disable-debug argument to configure to allow disabling dnl debugging messages. dnl Usage: dnl NEON_WARNINGS([actions-if-debug-enabled], [actions-if-debug-disabled]) dnl AC_DEFUN([NEON_DEBUG], [ AC_ARG_ENABLE(debug, AS_HELP_STRING(--disable-debug,[disable runtime debugging messages])) # default is to enable debugging case $enable_debug in no) AC_MSG_NOTICE([debugging is disabled]) $2 ;; *) AC_MSG_NOTICE([debugging is enabled]) AC_DEFINE(NE_DEBUGGING, 1, [Define to enable debugging]) $1 ;; esac]) dnl Macro to optionally enable socks support AC_DEFUN([NEON_SOCKS], [ ]) AC_DEFUN([NEON_WITH_LIBS], [ AC_ARG_WITH([libs], [[ --with-libs=DIR[:DIR2...] look for support libraries in DIR/{bin,lib,include}]], [case $with_libs in yes|no) AC_MSG_ERROR([--with-libs must be passed a directory argument]) ;; *) ne_save_IFS=$IFS; IFS=: for dir in $with_libs; do ne_add_CPPFLAGS="$ne_add_CPPFLAGS -I${dir}/include" ne_add_LDFLAGS="$ne_add_LDFLAGS -L${dir}/lib" ne_add_PATH="${ne_add_PATH}${dir}/bin:" PKG_CONFIG_PATH=${PKG_CONFIG_PATH}${PKG_CONFIG_PATH+:}${dir}/lib/pkgconfig done IFS=$ne_save_IFS CPPFLAGS="${ne_add_CPPFLAGS} $CPPFLAGS" LDFLAGS="${ne_add_LDFLAGS} $LDFLAGS" PATH=${ne_add_PATH}$PATH export PKG_CONFIG_PATH ;; esac])]) AC_DEFUN([NEON_I18N], [ dnl Check for NLS iff libintl.h was detected. AC_ARG_ENABLE(nls, AS_HELP_STRING(--disable-nls, [disable internationalization support]),, [enable_nls=${ac_cv_header_libintl_h}]) if test x${enable_nls} = xyes; then # presume that dgettext() is available if bindtextdomain() is... # checking for dgettext() itself is awkward because gcc has a # builtin of that function, which confuses AC_CHECK_FUNCS et al. NE_SEARCH_LIBS(bindtextdomain, intl,,[enable_nls=no]) NE_CHECK_FUNCS(bind_textdomain_codeset) fi if test "$enable_nls" = "no"; then NE_DISABLE_SUPPORT(I18N, [Internationalization support not enabled]) else NE_ENABLE_SUPPORT(I18N, [Internationalization support enabled]) eval localedir="${datadir}/locale" AC_DEFINE_UNQUOTED([LOCALEDIR], "$localedir", [Define to be location of localedir]) fi ]) davix-R_0_5_0/deps/libneon/macros/socklen-arg-type.m4000066400000000000000000000017031257152637300225610ustar00rootroot00000000000000dnl This function is (C) 1997,98,99 Stephan Kulow (coolo@kde.org) dnl Modifications (C) Joe Orton 1999,2000 AC_DEFUN([SOCKLEN_ARG_TYPE],[ dnl Check for the type of the third argument of getsockname AC_MSG_CHECKING(for the third argument of getsockname) AC_CACHE_VAL(ac_cv_ksize_t, [AC_TRY_COMPILE([ #include #include ],[ socklen_t a=0; getsockname(0,(struct sockaddr*)0, &a); ], ac_cv_ksize_t=socklen_t, ac_cv_ksize_t=) if test -z "$ac_cv_ksize_t"; then ac_safe_cflags="$CFLAGS" if test "$GCC" = "yes"; then CFLAGS="-Werror $CFLAGS" fi AC_TRY_COMPILE([ #include #include ],[ int a=0; getsockname(0,(struct sockaddr*)0, &a); ], ac_cv_ksize_t=int, ac_cv_ksize_t=size_t) CFLAGS="$ac_safe_cflags" fi ]) if test -z "$ac_cv_ksize_t"; then ac_cv_ksize_t=int fi AC_MSG_RESULT($ac_cv_ksize_t) AC_DEFINE_UNQUOTED(ksize_t, $ac_cv_ksize_t, [Define to be the type of the third argument to getsockname]) ])davix-R_0_5_0/deps/libneon/neon-config.in000066400000000000000000000036561257152637300204120ustar00rootroot00000000000000#! /bin/sh # Originally from libxml, Copyright (C) Daniel Veillard # Modifications for neon Copyright (C) 2000-2006 Joe Orton. prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ usage() { cat <&2 ;; esac shift done exit 0 davix-R_0_5_0/deps/libneon/neon.mak000066400000000000000000000161141257152637300173020ustar00rootroot00000000000000#**** neon Win32 -*- Makefile -*- ******************************************** # # Define DEBUG_BUILD to create a debug version of the library. !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF ######## # Debug vs. Release build !IF "$(DEBUG_BUILD)" == "" INTDIR = Release CFLAGS = /MD /W3 /GX /O2 /D "NDEBUG" TARGET = .\libneon.lib !ELSE INTDIR = Debug CFLAGS = /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" TARGET = .\libneonD.lib !ENDIF ######## # Whether to build SSPI !IF "$(SSPI_BUILD)" != "" CFLAGS = $(CFLAGS) /D HAVE_SSPI !ENDIF ######## # Support for Expat integration # # If EXPAT_SRC or EXPAT_INC are set, then assume compiling against a # pre-built binary Expat 1.95.X. You can use either EXPAT_SRC # to specify the top-level Expat directory, or EXPAT_INC to directly # specify the Expat include directory. (If both are set, EXPAT_SRC # is ignored). # # If EXPAT_SRC and EXPAT_INC are not set, then the user can # still set EXPAT_FLAGS to specify very specific compile behavior. # # If none of EXPAT_SRC, EXPAT_INC and EXPAT_FLAGS are set, disable # WebDAV support. !IF "$(EXPAT_INC)" == "" !IF "$(EXPAT_SRC)" != "" EXPAT_INC = $(EXPAT_SRC)\Source\Lib !ENDIF !ENDIF BUILD_EXPAT = 1 !IF "$(EXPAT_INC)" == "" !IFNDEF EXPAT_FLAGS EXPAT_FLAGS = BUILD_EXPAT = !ENDIF !ELSE EXPAT_FLAGS = /I "$(EXPAT_INC)" /D HAVE_EXPAT /D HAVE_EXPAT_H /D NE_HAVE_DAV !ENDIF ######## # Support for OpenSSL integration !IF "$(OPENSSL_SRC)" == "" OPENSSL_FLAGS = !ELSE OPENSSL_FLAGS = /I "$(OPENSSL_SRC)\inc32" /D NE_HAVE_SSL /D HAVE_OPENSSL !ENDIF ######## # Support for zlib integration !IF "$(ZLIB_SRC)" == "" ZLIB_FLAGS = ZLIB_LIBS = ZLIB_CLEAN = !ELSE ZLIB_CLEAN = ZLIB_CLEAN !IF "$(DEBUG_BUILD)" == "" ZLIB_STATICLIB = zlib.lib ZLIB_SHAREDLIB = zlib1.dll ZLIB_IMPLIB = zdll.lib ZLIB_LDFLAGS = /nologo /release !ELSE ZLIB_STATICLIB = zlib_d.lib ZLIB_SHAREDLIB = zlib1_d.dll ZLIB_IMPLIB = zdll_d.lib ZLIB_LDFLAGS = /nologo /debug !ENDIF ZLIB_FLAGS = /I "$(ZLIB_SRC)" /D NE_HAVE_ZLIB !IF "$(ZLIB_DLL)" == "" ZLIB_LIBS = "$(ZLIB_SRC)\$(ZLIB_STATICLIB)" !ELSE ZLIB_FLAGS = $(ZLIB_FLAGS) /D ZLIB_DLL ZLIB_LIBS = "$(ZLIB_SRC)\$(ZLIB_IMPLIB)" !ENDIF !ENDIF ######## # Support for IPv6 !IF "$(ENABLE_IPV6)" == "yes" IPV6_FLAGS = /D USE_GETADDRINFO !ENDIF # Exclude stuff we don't need from the Win32 headers WIN32_DEFS = /D WIN32_LEAN_AND_MEAN /D NOUSER /D NOGDI /D NONLS /D NOCRYPT CPP=cl.exe CPP_PROJ = /c /nologo $(CFLAGS) $(WIN32_DEFS) $(EXPAT_FLAGS) $(OPENSSL_FLAGS) $(ZLIB_FLAGS) $(IPV6_FLAGS) /D "HAVE_CONFIG_H" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" LIB32=link.exe -lib LIB32_FLAGS=/nologo /out:"$(TARGET)" LIB32_OBJS= \ "$(INTDIR)\ne_alloc.obj" \ "$(INTDIR)\ne_auth.obj" \ "$(INTDIR)\ne_basic.obj" \ "$(INTDIR)\ne_compress.obj" \ "$(INTDIR)\ne_dates.obj" \ "$(INTDIR)\ne_i18n.obj" \ "$(INTDIR)\ne_md5.obj" \ "$(INTDIR)\ne_pkcs11.obj" \ "$(INTDIR)\ne_redirect.obj" \ "$(INTDIR)\ne_request.obj" \ "$(INTDIR)\ne_session.obj" \ "$(INTDIR)\ne_socket.obj" \ "$(INTDIR)\ne_socks.obj" \ "$(INTDIR)\ne_sspi.obj" \ "$(INTDIR)\ne_string.obj" \ "$(INTDIR)\ne_uri.obj" \ "$(INTDIR)\ne_utils.obj" !IF "$(BUILD_EXPAT)" != "" LIB32_OBJS= \ $(LIB32_OBJS) \ "$(INTDIR)\ne_207.obj" \ "$(INTDIR)\ne_xml.obj" \ "$(INTDIR)\ne_xmlreq.obj" \ "$(INTDIR)\ne_oldacl.obj" \ "$(INTDIR)\ne_acl3744.obj" \ "$(INTDIR)\ne_props.obj" \ "$(INTDIR)\ne_locks.obj" !ENDIF !IF "$(OPENSSL_SRC)" != "" LIB32_OBJS = $(LIB32_OBJS) "$(INTDIR)\ne_openssl.obj" !IFDEF OPENSSL_STATIC LIB32_OBJS = $(LIB32_OBJS) "$(OPENSSL_SRC)\out32\libeay32.lib" \ "$(OPENSSL_SRC)\out32\ssleay32.lib" !ELSE LIB32_OBJS = $(LIB32_OBJS) "$(OPENSSL_SRC)\out32dll\libeay32.lib" \ "$(OPENSSL_SRC)\out32dll\ssleay32.lib" !ENDIF !ELSE # Provide ABI-compatibility stubs for SSL interface LIB32_OBJS = $(LIB32_OBJS) "$(INTDIR)\ne_stubssl.obj" !ENDIF !IF "$(ZLIB_SRC)" != "" LIB32_OBJS = $(LIB32_OBJS) $(ZLIB_LIBS) !ENDIF ALL: ".\src\config.h" "$(TARGET)" CLEAN: $(ZLIB_CLEAN) -@erase "$(INTDIR)\ne_207.obj" -@erase "$(INTDIR)\ne_alloc.obj" -@erase "$(INTDIR)\ne_oldacl.obj" -@erase "$(INTDIR)\ne_acl3744.obj" -@erase "$(INTDIR)\ne_auth.obj" -@erase "$(INTDIR)\ne_basic.obj" -@erase "$(INTDIR)\ne_compress.obj" -@erase "$(INTDIR)\ne_dates.obj" -@erase "$(INTDIR)\ne_i18n.obj" -@erase "$(INTDIR)\ne_locks.obj" -@erase "$(INTDIR)\ne_md5.obj" -@erase "$(INTDIR)\ne_props.obj" -@erase "$(INTDIR)\ne_redirect.obj" -@erase "$(INTDIR)\ne_request.obj" -@erase "$(INTDIR)\ne_session.obj" -@erase "$(INTDIR)\ne_openssl.obj" -@erase "$(INTDIR)\ne_stubssl.obj" -@erase "$(INTDIR)\ne_pkcs11.obj" -@erase "$(INTDIR)\ne_socket.obj" -@erase "$(INTDIR)\ne_socks.obj" -@erase "$(INTDIR)\ne_sspi.obj" -@erase "$(INTDIR)\ne_string.obj" -@erase "$(INTDIR)\ne_uri.obj" -@erase "$(INTDIR)\ne_utils.obj" -@erase "$(INTDIR)\ne_xml.obj" -@erase "$(INTDIR)\ne_xmlreq.obj" -@erase "$(TARGET)" -@erase ".\src\config.h" "$(TARGET)": $(DEF_FILE) $(LIB32_OBJS) -@if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" $(LIB32) @<< $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) << {src}.c{$(INTDIR)}.obj:: -@if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" $(CPP) @<< $(CPP_PROJ) $< << ".\src\config.h": config.hw -@if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" < nul echo Created config.h from config.hw << "$(INTDIR)\ne_207.obj": .\src\ne_207.c "$(INTDIR)\ne_alloc.obj": .\src\ne_alloc.c "$(INTDIR)\ne_acl3744.obj": .\src\ne_acl3744.c "$(INTDIR)\ne_oldacl.obj": .\src\ne_oldacl.c "$(INTDIR)\ne_auth.obj": .\src\ne_auth.c "$(INTDIR)\ne_basic.obj": .\src\ne_basic.c "$(INTDIR)\ne_compress.obj": .\src\ne_compress.c "$(INTDIR)\ne_dates.obj": .\src\ne_dates.c "$(INTDIR)\ne_i18n.obj": .\src\ne_i18n.c "$(INTDIR)\ne_locks.obj": .\src\ne_locks.c "$(INTDIR)\ne_md5.obj": .\src\ne_md5.c "$(INTDIR)\ne_props.obj": .\src\ne_props.c "$(INTDIR)\ne_redirect.obj": .\src\ne_redirect.c "$(INTDIR)\ne_request.obj": .\src\ne_request.c "$(INTDIR)\ne_session.obj": .\src\ne_session.c "$(INTDIR)\ne_openssl.obj": .\src\ne_openssl.c "$(INTDIR)\ne_stubssl.obj": .\src\ne_stubssl.c "$(INTDIR)\ne_pkcs11.obj": .\src\ne_pkcs11.c "$(INTDIR)\ne_socket.obj": .\src\ne_socket.c "$(INTDIR)\ne_socks.obj": .\src\ne_socks.c "$(INTDIR)\ne_sspi.obj": .\src\ne_sspi.c "$(INTDIR)\ne_string.obj": .\src\ne_string.c "$(INTDIR)\ne_uri.obj": .\src\ne_uri.c "$(INTDIR)\ne_utils.obj": .\src\ne_utils.c "$(INTDIR)\ne_xml.obj": .\src\ne_xml.c "$(INTDIR)\ne_xmlreq.obj": .\src\ne_xmlreq.c "$(ZLIB_SRC)\$(ZLIB_STATICLIB)": < Language-Team: cz MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-2 Content-Transfer-Encoding: 8bit Nelze se pipojit k proxy serveruNelze se pipojit k serveruNelze zpracovat velikost blokuNelze nast velikost blokuNelze nast tlo odpovdiNelze pest stavov dekNelze poslat poadavekNelze odeslat tlo poadavkuNelze zapsat do souboru: %sChyba pi ten hlaviek odpovdiPota nenalezenNeplatn dka HTTP stavu ve stavovm prvku na dku %d odpovdi: Stavov dka byla: %sdek je pli dlouhHlavika odpovdi je pli dlouhdavix-R_0_5_0/deps/libneon/po/cs.po000066400000000000000000000343241257152637300172370ustar00rootroot00000000000000# The czech translation for sitecopy # Copyright (C) 2000 Free Software Foundation, Inc. # Petr Prazak , 2000-2002. # msgid "" msgstr "" "Project-Id-Version: sitecopy 0.11.4\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2002-04-09 11:12+0100\n" "Last-Translator: Petr Prazak \n" "Language-Team: cz\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-2\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" "Neplatn dka HTTP stavu ve stavovm prvku na dku %d odpovdi:\n" "Stavov dka byla: %s" # src/console_fe.c:961 #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "Nelze se pipojit k serveru" # src/console_fe.c:961 #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "Nelze se pipojit k proxy serveru" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 #, fuzzy msgid "GSSAPI authentication error: " msgstr "Je vyadovna autentizace na %s `%s':\n" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "Nelze zpracovat velikost bloku" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "Nelze zpracovat velikost bloku" # src/console_fe.c:992 #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "Nelze zjistit dlku souboru: %s" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, fuzzy, c-format msgid "Range is not satisfiable" msgstr "Rozsah nen uspokojiv." #: src/ne_basic.c:188 #, fuzzy, c-format msgid "Resource does not support ranged GET requests" msgstr "Server nedovoluje sten pkazy GET." #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" # src/console_fe.c:992 #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "Nelze otevt soubor: " # src/console_fe.c:992 #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "Nelze otevt soubor: " #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" # src/console_fe.c:992 #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "Nelze zapsat do souboru: %s" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" # src/console_fe.c:992 #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "Nelze zapsat do souboru: %s" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 #, fuzzy msgid "Response exceeds maximum property count" msgstr "Odpov pekrocila maximln poet poloek v hlavicce." #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "Nelze zpracovat stavov dek odpovdi." #: src/ne_request.c:194 #, fuzzy, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: proxy server ukonil spojen." #: src/ne_request.c:197 #, fuzzy, c-format msgid "%s: connection was closed by server" msgstr "%s: server ukonil spojen." #: src/ne_request.c:202 #, fuzzy, c-format msgid "%s: connection timed out" msgstr "%s: spojen vyprelo." # src/console_fe.c:992 #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "Nelze zapsat do souboru: %s" # src/console_fe.c:992 #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "Nelze zapsat do souboru: %s" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" # src/console_fe.c:992 #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "Nelze zapsat do souboru: %s" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "Nelze odeslat tlo poadavku" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "Nelze nast velikost bloku" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "Nelze zpracovat velikost bloku" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "Nelze nast tlo odpovdi" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "Nelze nast velikost bloku" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "Nelze pest stavov dek" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "Nelze zpracovat stavov dek odpovdi." #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "Nelze nast tlo odpovdi" #: src/ne_request.c:964 msgid "Could not send request" msgstr "Nelze poslat poadavek" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "Chyba pi ten hlaviek odpovdi" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "Hlavika odpovdi je pli dlouh" #: src/ne_request.c:1140 #, fuzzy msgid "Response exceeded maximum number of header fields" msgstr "Odpov pekrocila maximln poet poloek v hlavicce." # src/console_fe.c:956 #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: Chyba: Nelze najt adresu vzdlenho potae (%s).\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" # src/console_fe.c:992 #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "Nelze zapsat do souboru: %s" #: src/ne_request.c:1445 #, fuzzy, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "Nelze navzat SSL spojen pes proxy server." #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "Nelze navzat SSL spojen" # src/console_fe.c:961 #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "Nelze se pipojit k serveru" # src/console_fe.c:961 #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "Nelze se pipojit k proxy serveru" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "Nelze navzat SSL spojen pes proxy server." #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 #, fuzzy msgid "Connection closed" msgstr "Server ukonil spojen." #: src/ne_socket.c:622 src/ne_socket.c:728 #, fuzzy msgid "Secure connection truncated" msgstr "Spojen vyprelo." #: src/ne_socket.c:634 src/ne_socket.c:740 #, fuzzy, c-format msgid "SSL error: %s" msgstr "%s: Chyba: %s\n" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, fuzzy, c-format msgid "SSL alert received: %s" msgstr "%s: Chyba: %s\n" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "dek je pli dlouh" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "Pota nenalezen" #: src/ne_socket.c:1221 #, fuzzy msgid "Connection timed out" msgstr "%s: spojen vyprelo." #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 #, fuzzy msgid "Could not create SSL structure" msgstr "Nelze navzat SSL spojen" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 #, fuzzy msgid "connection not permitted" msgstr "%s: spojen vyprelo." #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "Nelze odeslat tlo poadavku" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "Nelze nast tlo odpovdi" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "Nelze poslat poadavek" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "Nelze pest stavov dek" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "Je vyadovna autentizace na %s `%s':\n" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "Nelze poslat poadavek" # src/console_fe.c:961 #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "Nelze se pipojit k serveru" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" # src/console_fe.c:961 #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "Nelze se pipojit k serveru" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "Nelze nast tlo odpovdi" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" # src/console_fe.c:961 #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "Nelze se pipojit k serveru" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "Nelze nast tlo odpovdi" # src/console_fe.c:821 #: src/ne_xml.c:280 #, fuzzy, c-format msgid "XML parse error at line %d: invalid element name" msgstr "Chyba zpracovn XML na dku %d: %s." # src/common.c:87 #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr "Neznm systmov chyba" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" # src/console_fe.c:821 #: src/ne_xml.c:667 #, fuzzy, c-format msgid "XML parse error at line %d: %s" msgstr "Chyba zpracovn XML na dku %d: %s." #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "Nelze nast tlo odpovdi" #, fuzzy #~ msgid "%s: %s" #~ msgstr "%s: Chyba: %s\n" davix-R_0_5_0/deps/libneon/po/de.gmo000066400000000000000000000032601257152637300173610ustar00rootroot00000000000000 h!i+GcV F/V)+($+*'V+~)5 [ z'   Could not connect to proxy serverCould not connect to serverCould not parse chunk sizeCould not read chunk sizeCould not read response bodyCould not read status lineCould not send requestCould not send request bodyCould not write to file: %sError reading response headersHost not foundInvalid HTTP status line in status element at line %d of response: Status line was: %sLine too longResponse header too longProject-Id-Version: sitecopy 0.11.3 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2002-01-13 13:37+0100 Last-Translator: Thomas Schultz Language-Team: de MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Verbindungsaufbau zum Proxy-Server gescheitert.Verbindungsaufbau zum Server gescheitert.Parser-Fehler bei Ermittlung der BlockgreLesefehler bei Ermittlung der BlockgreKonnte Rumpf der Antwort nicht lesenKonnte Status-Zeile des Servers nicht lesenKonnte keine Anfrage (request) schickenKonnte den Rumpf der Anfrage nicht schickenKonnte nicht in diese Datei schreiben: %sFehler beim Lesen der Kopfzeilen (header) der AntwortHost nicht gefundenUngltige HTTP Status-Zeile im Status-Element in Zeile %d der Antwort: Status-Zeile war: %sZeile zu langKopfzeilen (header) der Antwort zu langdavix-R_0_5_0/deps/libneon/po/de.po000066400000000000000000000346101257152637300172200ustar00rootroot00000000000000# The German translation for sitecopy. # Copyright (C) 2000, Thomas Schultz # msgid "" msgstr "" "Project-Id-Version: sitecopy 0.11.3\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2002-01-13 13:37+0100\n" "Last-Translator: Thomas Schultz \n" "Language-Team: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" "Ungltige HTTP Status-Zeile im Status-Element in Zeile %d der Antwort:\n" "Status-Zeile war: %s" #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "Verbindungsaufbau zum Server gescheitert." #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "Verbindungsaufbau zum Proxy-Server gescheitert." #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 #, fuzzy msgid "GSSAPI authentication error: " msgstr "Anmeldung wird bentigt auf %s `%s':\n" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "Parser-Fehler bei Ermittlung der Blockgre" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "Parser-Fehler bei Ermittlung der Blockgre" #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "Konnte Lnge der Datei nicht herausfinden: %s" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, fuzzy, c-format msgid "Range is not satisfiable" msgstr "Range is not satisfiable." #: src/ne_basic.c:188 #, fuzzy, c-format msgid "Resource does not support ranged GET requests" msgstr "Server ermglicht keine teilweisen GETs." #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "Konnte Datei nicht ffnen: " #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "Konnte Datei nicht ffnen: " #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "Konnte nicht in diese Datei schreiben: %s" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "Konnte nicht in diese Datei schreiben: %s" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 #, fuzzy msgid "Response exceeds maximum property count" msgstr "Antwort hatte zu viele Header-Felder." #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "Konnte Status-Zeile des Servers nicht interpretieren." #: src/ne_request.c:194 #, fuzzy, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: Verbindung vom Proxy-Server geschlossen." #: src/ne_request.c:197 #, fuzzy, c-format msgid "%s: connection was closed by server" msgstr "%s: Verbindung vom Server geschlossen." #: src/ne_request.c:202 #, fuzzy, c-format msgid "%s: connection timed out" msgstr "%s: Verbindung wegen Zeitberschreitung geschlossen." #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "Konnte nicht in diese Datei schreiben: %s" #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "Konnte nicht in diese Datei schreiben: %s" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "Konnte nicht in diese Datei schreiben: %s" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "Konnte den Rumpf der Anfrage nicht schicken" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "Lesefehler bei Ermittlung der Blockgre" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "Parser-Fehler bei Ermittlung der Blockgre" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "Konnte Rumpf der Antwort nicht lesen" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "Lesefehler bei Ermittlung der Blockgre" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "Konnte Status-Zeile des Servers nicht lesen" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "Konnte Status-Zeile des Servers nicht interpretieren." #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "Konnte Rumpf der Antwort nicht lesen" #: src/ne_request.c:964 msgid "Could not send request" msgstr "Konnte keine Anfrage (request) schicken" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "Fehler beim Lesen der Kopfzeilen (header) der Antwort" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "Kopfzeilen (header) der Antwort zu lang" #: src/ne_request.c:1140 #, fuzzy msgid "Response exceeded maximum number of header fields" msgstr "Antwort hatte zu viele Header-Felder." #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: Fehler: Konnte den Namen des Servers nicht auflsen (%s).\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "Konnte nicht in diese Datei schreiben: %s" #: src/ne_request.c:1445 #, fuzzy, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "Konnte durch den Proxy-Server keine SSL-Verbindung herstellen" #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "Konnte keine SSL-Sitzung herstellen" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "Verbindungsaufbau zum Server gescheitert." #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "Verbindungsaufbau zum Proxy-Server gescheitert." #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "Konnte durch den Proxy-Server keine SSL-Verbindung herstellen" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 #, fuzzy msgid "Connection closed" msgstr "Verbindung vom Server geschlossen" #: src/ne_socket.c:622 src/ne_socket.c:728 #, fuzzy msgid "Secure connection truncated" msgstr "Verbindung wegen Zeitberschreitung abgebrochen." #: src/ne_socket.c:634 src/ne_socket.c:740 #, fuzzy, c-format msgid "SSL error: %s" msgstr "%s: Fehler: %s\n" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, fuzzy, c-format msgid "SSL alert received: %s" msgstr "%s: Fehler: %s\n" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "Zeile zu lang" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "Host nicht gefunden" #: src/ne_socket.c:1221 #, fuzzy msgid "Connection timed out" msgstr "%s: Verbindung wegen Zeitberschreitung geschlossen." #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 #, fuzzy msgid "Could not create SSL structure" msgstr "Konnte keine SSL-Sitzung herstellen" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 #, fuzzy msgid "connection not permitted" msgstr "%s: Verbindung wegen Zeitberschreitung geschlossen." #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "Konnte den Rumpf der Anfrage nicht schicken" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "Konnte Rumpf der Antwort nicht lesen" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "Konnte keine Anfrage (request) schicken" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "Konnte Status-Zeile des Servers nicht lesen" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "Anmeldung wird bentigt auf %s `%s':\n" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "Konnte keine Anfrage (request) schicken" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "Verbindungsaufbau zum Server gescheitert." #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "Verbindungsaufbau zum Server gescheitert." #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "Konnte Rumpf der Antwort nicht lesen" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "Verbindungsaufbau zum Server gescheitert." #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "Konnte Rumpf der Antwort nicht lesen" #: src/ne_xml.c:280 #, fuzzy, c-format msgid "XML parse error at line %d: invalid element name" msgstr "Fehler beim XML-Parsing in Zeile %d: %s." #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr "Unbekannter System-Fehler" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, fuzzy, c-format msgid "XML parse error at line %d: %s" msgstr "Fehler beim XML-Parsing in Zeile %d: %s." #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "Konnte Rumpf der Antwort nicht lesen" #, fuzzy #~ msgid "%s: %s" #~ msgstr "%s: %s\n" davix-R_0_5_0/deps/libneon/po/fr.gmo000066400000000000000000000006031257152637300173760ustar00rootroot00000000000000$,8I9Project-Id-Version: sitecopy 0.9.3 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2000-01-31 00:00+0100 Last-Translator: Sylvain Glaize Language-Team: fr MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit davix-R_0_5_0/deps/libneon/po/fr.po000066400000000000000000000344111257152637300172360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) 2000 Sylvain Glaize # #, fuzzy msgid "" msgstr "" "Project-Id-Version: sitecopy 0.9.3\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2000-01-31 00:00+0100\n" "Last-Translator: Sylvain Glaize \n" "Language-Team: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 msgid "GSSAPI authentication error: " msgstr "" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "" #: src/ne_basic.c:188 #, c-format msgid "Resource does not support ranged GET requests" msgstr "" #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "" #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:194 #, fuzzy, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_request.c:197 #, c-format msgid "%s: connection was closed by server" msgstr "" #: src/ne_request.c:202 #, c-format msgid "%s: connection timed out" msgstr "" #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "" #: src/ne_request.c:735 #, fuzzy msgid "Could not parse chunk size" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:964 msgid "Could not send request" msgstr "" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "" #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: erreur: impossible de trouver le nom de l'hte distant.\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, fuzzy, c-format msgid "Could not write to file: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_request.c:1445 #, fuzzy, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_request.c:1518 #, fuzzy msgid "Could not connect to server" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_request.c:1520 #, fuzzy msgid "Could not connect to proxy server" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 msgid "Connection closed" msgstr "" #: src/ne_socket.c:622 src/ne_socket.c:728 msgid "Secure connection truncated" msgstr "" #: src/ne_socket.c:634 src/ne_socket.c:740 #, fuzzy, c-format msgid "SSL error: %s" msgstr "" "%s: dans issue_error\n" "%s" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, fuzzy, c-format msgid "SSL alert received: %s" msgstr "" "%s: dans issue_error\n" "%s" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "" #: src/ne_socket.c:1221 msgid "Connection timed out" msgstr "" #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 #, fuzzy msgid "Could not create SSL structure" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 msgid "connection not permitted" msgstr "" #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "%s: erreur: impossible de se connecter l'hte distant.\n" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #: src/ne_xml.c:280 #, fuzzy, c-format msgid "XML parse error at line %d: invalid element name" msgstr "" "%s: erreur dans le fichier de ressources la ligne %d:\n" "%s\n" #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr "Erreur systme inconnue" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, fuzzy, c-format msgid "XML parse error at line %d: %s" msgstr "" "%s: erreur dans le fichier de ressources la ligne %d:\n" "%s\n" #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "%s: erreur: impossible d'ouvrir le fichier de ressources: %s\n" #, fuzzy #~ msgid "%s: %s" #~ msgstr "" #~ "%s: dans issue_error\n" #~ "%s" davix-R_0_5_0/deps/libneon/po/ja.gmo000066400000000000000000000015551257152637300173700ustar00rootroot00000000000000T !,ISe""9TCould not connect to proxy serverCould not connect to serverCould not parse chunk sizeCould not read chunk sizeCould not read response bodyCould not write to file: %sProject-Id-Version: sitecopy 0.10.14 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2001-01-16 07:32+0900 Last-Translator: Nobuyuki Tsuchimura Language-Team: ja MIME-Version: 1.0 Content-Type: text/plain; charset=EUC-JP Content-Transfer-Encoding: 8-bit ץС³ǤޤץС³Ǥޤchunk 礭ϤǤޤchunk 礭ɤޤresponse body ɤޤե뤬񤱤ޤ: %sdavix-R_0_5_0/deps/libneon/po/ja.po000066400000000000000000000326201257152637300172210ustar00rootroot00000000000000# The Japanese translation for sitecopy # Copyright (C) 2000 Nobuyuki Tsuchimura # #, fuzzy msgid "" msgstr "" "Project-Id-Version: sitecopy 0.10.14\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2001-01-16 07:32+0900\n" "Last-Translator: Nobuyuki Tsuchimura \n" "Language-Team: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=EUC-JP\n" "Content-Transfer-Encoding: 8-bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "ץС³Ǥޤ" #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "ץС³Ǥޤ" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 #, fuzzy msgid "GSSAPI authentication error: " msgstr "%s ؤǧڤ %s ɬפǤ '%s':\n" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "chunk 礭ϤǤޤ" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "chunk 礭ϤǤޤ" #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "ե뤬ɤޤ: " #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "" #: src/ne_basic.c:188 #, fuzzy, c-format msgid "Resource does not support ranged GET requests" msgstr "Сեʬ򥵥ݡȤƤޤ" #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "ե뤬ɤޤ: " #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "ե뤬񤱤ޤ: " #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "ե뤬񤱤ޤ: %s" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "ե뤬񤱤ޤ: %s" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "" #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "chunk 礭ϤǤޤ" #: src/ne_request.c:194 #, fuzzy, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: ³ץСڤޤ" #: src/ne_request.c:197 #, fuzzy, c-format msgid "%s: connection was closed by server" msgstr "%s: ³Сڤޤ" #: src/ne_request.c:202 #, fuzzy, c-format msgid "%s: connection timed out" msgstr "%s: ³ॢȤǤ" #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "ե뤬񤱤ޤ: %s" #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "ե뤬񤱤ޤ: %s" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "ե뤬񤱤ޤ: %s" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "chunk 礭ɤޤ" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "chunk 礭ϤǤޤ" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "response body ɤޤ" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "chunk 礭ɤޤ" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "response body ɤޤ" #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "response body ɤޤ" #: src/ne_request.c:964 msgid "Could not send request" msgstr "" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "" #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: 顼: СΥۥ̾ (%s) IP ɥ쥹ѴǤޤ\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "ե뤬񤱤ޤ: %s" #: src/ne_request.c:1445 #, fuzzy, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "ץС SSL ³Ǥޤ" #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "ץС SSL ³Ǥޤ" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "ץС³Ǥޤ" #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "ץС³Ǥޤ" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "ץС SSL ³Ǥޤ" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 #, fuzzy msgid "Connection closed" msgstr "%s: ³Сڤޤ" #: src/ne_socket.c:622 src/ne_socket.c:728 #, fuzzy msgid "Secure connection truncated" msgstr "³ॢȡ" #: src/ne_socket.c:634 src/ne_socket.c:740 #, c-format msgid "SSL error: %s" msgstr "" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, c-format msgid "SSL alert received: %s" msgstr "" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "" #: src/ne_socket.c:1221 #, fuzzy msgid "Connection timed out" msgstr "%s: ³ॢȤǤ" #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 #, fuzzy msgid "Could not create SSL structure" msgstr "ץС SSL ³Ǥޤ" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 #, fuzzy msgid "connection not permitted" msgstr "%s: ³ॢȤǤ" #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "response body ɤޤ" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "response body ɤޤ" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "chunk 礭ɤޤ" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "chunk 礭ɤޤ" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "%s ؤǧڤ %s ɬפǤ '%s':\n" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "ץС³Ǥޤ" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "ץС³Ǥޤ" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "ץС³Ǥޤ" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "response body ɤޤ" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "ץС³Ǥޤ" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "response body ɤޤ" #: src/ne_xml.c:280 #, fuzzy, c-format msgid "XML parse error at line %d: invalid element name" msgstr "" "%s: rcfile %d ԤǴְäƤޤ:\n" "%s\n" #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr "̤ΤΥƥ२顼" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, fuzzy, c-format msgid "XML parse error at line %d: %s" msgstr "" "%s: rcfile %d ԤǴְäƤޤ:\n" "%s\n" #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "response body ɤޤ" #, fuzzy #~ msgid "%s: %s" #~ msgstr "桼̾: %s\n" davix-R_0_5_0/deps/libneon/po/neon.pot000066400000000000000000000270041257152637300177520ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" #: src/ne_auth.c:134 #, c-format msgid "Could not authenticate to server: %s" msgstr "" #: src/ne_auth.c:139 #, c-format msgid "Could not authenticate to proxy server: %s" msgstr "" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 msgid "GSSAPI authentication error: " msgstr "" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 msgid "could not parse domain in Digest challenge" msgstr "" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 msgid "could not parse challenge" msgstr "" #: src/ne_basic.c:98 #, c-format msgid "Could not determine file size: %s" msgstr "" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "" #: src/ne_basic.c:188 #, c-format msgid "Resource does not support ranged GET requests" msgstr "" #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 msgid "Could not inflate data" msgstr "" #: src/ne_compress.c:293 msgid "Could not initialize zlib" msgstr "" #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, c-format msgid "Could not verify server certificate: %s" msgstr "" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, c-format msgid "SSL handshake failed: %s" msgstr "" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "" #: src/ne_redirect.c:92 #, c-format msgid "Could not parse redirect destination URL" msgstr "" #: src/ne_request.c:194 #, c-format msgid "%s: connection was closed by proxy server" msgstr "" #: src/ne_request.c:197 #, c-format msgid "%s: connection was closed by server" msgstr "" #: src/ne_request.c:202 #, c-format msgid "%s: connection timed out" msgstr "" #: src/ne_request.c:305 #, c-format msgid "Premature EOF in request body file" msgstr "" #: src/ne_request.c:312 #, c-format msgid "Failed reading request body file: %s" msgstr "" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "" #: src/ne_request.c:788 msgid "Could not read chunk delimiter" msgstr "" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "" #: src/ne_request.c:918 msgid "Could not parse response status line" msgstr "" #: src/ne_request.c:930 msgid "Could not read interim response headers" msgstr "" #: src/ne_request.c:964 msgid "Could not send request" msgstr "" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "" #: src/ne_request.c:1155 #, c-format msgid "Could not resolve hostname `%s': %s" msgstr "" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "" #: src/ne_request.c:1445 #, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "" #: src/ne_request.c:1484 #, c-format msgid "Could not create socket" msgstr "" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "" #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 msgid "Connection closed" msgstr "" #: src/ne_socket.c:622 src/ne_socket.c:728 msgid "Secure connection truncated" msgstr "" #: src/ne_socket.c:634 src/ne_socket.c:740 #, c-format msgid "SSL error: %s" msgstr "" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, c-format msgid "SSL alert received: %s" msgstr "" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "" #: src/ne_socket.c:1221 msgid "Connection timed out" msgstr "" #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 msgid "Could not create SSL structure" msgstr "" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 msgid "connection not permitted" msgstr "" #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 msgid "Could not send message to proxy" msgstr "" #: src/ne_socks.c:133 msgid "Could not read initial response from proxy" msgstr "" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 msgid "Could not send login message" msgstr "" #: src/ne_socks.c:162 msgid "Could not read login reply" msgstr "" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 msgid "Authentication failed" msgstr "" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 msgid "Could not send connect request" msgstr "" #: src/ne_socks.c:215 msgid "Could not read connect reply" msgstr "" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 msgid "Could not connect" msgstr "" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 msgid "Could not read address in connect reply" msgstr "" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 msgid "could not establish connection to identd" msgstr "" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 msgid "Could not read response from proxy" msgstr "" #: src/ne_xml.c:280 #, c-format msgid "XML parse error at line %d: invalid element name" msgstr "" #: src/ne_xml.c:474 msgid "Unknown error" msgstr "" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, c-format msgid "XML parse error at line %d: %s" msgstr "" #: src/ne_xmlreq.c:36 #, c-format msgid "Could not parse response: %s" msgstr "" davix-R_0_5_0/deps/libneon/po/nn.gmo000066400000000000000000000031321257152637300174020ustar00rootroot00000000000000 h!i+GcV t",+ 7UuT7F   Could not connect to proxy serverCould not connect to serverCould not parse chunk sizeCould not read chunk sizeCould not read response bodyCould not read status lineCould not send requestCould not send request bodyCould not write to file: %sError reading response headersHost not foundInvalid HTTP status line in status element at line %d of response: Status line was: %sLine too longResponse header too longProject-Id-Version: sitecopy 0.11.4 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2002-11-07 18:11+0100 Last-Translator: Karl Ove Hufthammer Language-Team: Norwegian Nynorsk MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Klarte ikkje kopla til mellomtenarKlarte ikkje kopla til tenaren.Klarte ikkje tolka storleik på oppdelt svarKlarte ikkje lesa storleik på oppdelt svarKlarte ikkje lesa svarKlarte ikkje lesa statuslinjaKlarte ikkje senda førespurnadKlarte ikkje senda førespurnadKlarte ikkje skriva til fil: %sFeil ved lesing av svarhovudFann ikkje vertUgyldig HTTP-statuslinje i statuselement på linje %d av svaret: Statuslinja var: %sFor lang linjeFor langt svarhovuddavix-R_0_5_0/deps/libneon/po/nn.po000066400000000000000000000352511257152637300172450ustar00rootroot00000000000000# Norwegian Nynorsk sitecopy translation. # Copyright (C) 2001 Karl Ove Hufthammer. # Karl Ove Hufthammer , 2002. # msgid "" msgstr "" "Project-Id-Version: sitecopy 0.11.4\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2002-11-07 18:11+0100\n" "Last-Translator: Karl Ove Hufthammer \n" "Language-Team: Norwegian Nynorsk \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" "Ugyldig HTTP-statuslinje i statuselement på linje %d av svaret:\n" "Statuslinja var: %s" #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "Klarte ikkje kopla til tenaren." #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "Klarte ikkje kopla til mellomtenar" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 #, fuzzy msgid "GSSAPI authentication error: " msgstr "Krev autentisering på %s «%s»:\n" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, fuzzy, c-format msgid "Negotiate response verification failure: %s" msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "Klarte ikkje tolka storleik på oppdelt svar" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "Klarte ikkje tolka storleik på oppdelt svar" #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "Fann ikkje fillengda: %s" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, fuzzy, c-format msgid "Range is not satisfiable" msgstr "Området finst ikkje." #: src/ne_basic.c:188 #, fuzzy, c-format msgid "Resource does not support ranged GET requests" msgstr "Tenaren kan ikkje handtera kommandoar for delvis GET." #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "Klarte ikkje opna fil: " #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "Klarte ikkje opna fil: " #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "Klarte ikkje skriva til fil: %s" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "Klarte ikkje skriva til fil: %s" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, fuzzy, c-format msgid "Server certificate changed: connection intercepted?" msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_props.c:371 src/ne_props.c:435 #, fuzzy msgid "Response exceeds maximum property count" msgstr "Svaret inneheld for mange header-felt." #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "Klarte ikkje tolka vidaresendingsadresse." #: src/ne_request.c:194 #, fuzzy, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: tilkoplinga vart lukka av mellomtenaren." #: src/ne_request.c:197 #, fuzzy, c-format msgid "%s: connection was closed by server" msgstr "%s: tilkoplinga vart lukka av tenaren." #: src/ne_request.c:202 #, fuzzy, c-format msgid "%s: connection timed out" msgstr "%s: sambandet vart tidsavbrote." #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "Klarte ikkje skriva til fil: %s" #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "Klarte ikkje skriva til fil: %s" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "Klarte ikkje skriva til fil: %s" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "Klarte ikkje senda førespurnad" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "Klarte ikkje lesa storleik på oppdelt svar" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "Klarte ikkje tolka storleik på oppdelt svar" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "Klarte ikkje lesa svar" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "Klarte ikkje lesa storleik på oppdelt svar" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "Klarte ikkje lesa statuslinja" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "Klarte ikkje tolka statuslinja i svaret." #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "Klarte ikkje lesa svarlinje" #: src/ne_request.c:964 msgid "Could not send request" msgstr "Klarte ikkje senda førespurnad" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "Feil ved lesing av svarhovud" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "For langt svarhovud" #: src/ne_request.c:1140 #, fuzzy msgid "Response exceeded maximum number of header fields" msgstr "Svaret inneheld for mange header-felt." #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: Feil: Fann ikkje adressa til nettverksvert (%s).\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "Klarte ikkje skriva til fil: %s" #: src/ne_request.c:1445 #, fuzzy, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "Klarte ikkje oppretta SSL-tilkopling til mellomtenar" #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "Klarte ikkje forhandla SSL-økt" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "Klarte ikkje kopla til tenaren." #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "Klarte ikkje kopla til mellomtenar" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "Klarte ikkje oppretta SSL-tilkopling til mellomtenar" #: src/ne_session.c:530 src/ne_session.c:541 #, fuzzy msgid "[invalid date]" msgstr "[ugyldig dato]" #: src/ne_session.c:554 #, fuzzy msgid "certificate is not yet valid" msgstr "Sertifikatet er gyldig" #: src/ne_session.c:555 #, fuzzy msgid "certificate has expired" msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_session.c:556 #, fuzzy msgid "certificate issued for a different hostname" msgstr "Sertifikatet er utferda av:" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 #, fuzzy msgid "bad certificate chain" msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_session.c:559 #, fuzzy msgid "certificate has been revoked" msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_session.c:564 #, fuzzy msgid "Server certificate verification failed: " msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 #, fuzzy msgid "Connection closed" msgstr "Tilkoplinga vart lukka av tenaren" #: src/ne_socket.c:622 src/ne_socket.c:728 #, fuzzy msgid "Secure connection truncated" msgstr "Sambandet vart tidsavbrote." #: src/ne_socket.c:634 src/ne_socket.c:740 #, fuzzy, c-format msgid "SSL error: %s" msgstr "%s: Feil: %s\n" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, fuzzy, c-format msgid "SSL alert received: %s" msgstr "%s: Feil: %s\n" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "For lang linje" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "Fann ikkje vert" #: src/ne_socket.c:1221 #, fuzzy msgid "Connection timed out" msgstr "%s: sambandet vart tidsavbrote." #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 #, fuzzy msgid "Client certificate verification failed" msgstr "Tenarsertifikatet er utgått på dato." #: src/ne_socket.c:1717 #, fuzzy msgid "SSL disabled due to lack of entropy" msgstr "SSL avslått grunna mangel på entropi" #: src/ne_socket.c:1724 #, fuzzy msgid "SSL disabled due to library version mismatch" msgstr "SSL avslått grunna mangel på entropi" #: src/ne_socket.c:1730 #, fuzzy msgid "Could not create SSL structure" msgstr "Klarte ikkje forhandla SSL-økt" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 #, fuzzy msgid "connection not permitted" msgstr "%s: sambandet vart tidsavbrote." #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "Klarte ikkje senda førespurnad" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "Klarte ikkje lesa svar" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "Klarte ikkje senda førespurnad" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "Klarte ikkje lesa statuslinja" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "Krev autentisering på %s «%s»:\n" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "Klarte ikkje senda førespurnad" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "Klarte ikkje kopla til tenaren." #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "Klarte ikkje kopla til tenaren." #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "Klarte ikkje lesa svar" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "Klarte ikkje kopla til tenaren." #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "Klarte ikkje lesa svar" #: src/ne_xml.c:280 #, fuzzy, c-format msgid "XML parse error at line %d: invalid element name" msgstr "XML-tolkingsfeil på linje %d: %s." #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr "Ukjend systemfeil" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, fuzzy, c-format msgid "XML parse error at line %d: %s" msgstr "XML-tolkingsfeil på linje %d: %s." #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "Klarte ikkje lesa «LIST»-svar." #, fuzzy #~ msgid "%s: %s" #~ msgstr "%s: %s\n" #~ msgid "Server was not authenticated correctly." #~ msgstr "Tenaren vart ikkje rett autentisert." #~ msgid "Proxy server was not authenticated correctly." #~ msgstr "Mellomtenaren vart ikkje rett autentisert." davix-R_0_5_0/deps/libneon/po/pl.gmo000066400000000000000000000321571257152637300174130ustar00rootroot00000000000000L|H I Z )s #    " 4 &P w  * $  ! " 8> w  ! ; = Ja{($+'-Ut*'"6Y#t4 )@'\;A8FW=2A"YV| !'5 ]Ek+#8:-S(1'"@#W,{ : &#Ja3}(C%+Dp '% #07hw +G](v*%*8"c% $4Yt2%%71!Sq"(2( !@ 2b ,  , & !<2!"o!!(!<!B" X" d"&"0"-"# #>/#5n#*#&#+#5"$8X$)$&$($" %+.%>Z%*%)%(%&$5&0Z&&M&U&AN'Z'R'3>(r(((+(*(c)/v),)()1).*\@*-***I*(@+.i+,+<+8,!;,.],,',8,--J.-#y-'-+- -<.4O.B.*./."/?/-X/-//%/,/G0_0u0000 00$1'&1N1e1$11-111 2($2*M2-x222%2"3'3;3X34n3 303:3#04T4s_E:] (X"1`F|*f Z7njk.=25MC?qb8,c%U!tG^iRl ) +oL[#g ADv0~w$aS6eNrpd93Tm;/-IKuhOHJ>B} yx\W{@QzY<V4&P'%s: %s (code %d)%s: connection timed out%s: connection was closed by proxy server%s: connection was closed by server%s: unrecognized error (%u)%s: unrecognized failure (%u)Authentication failedCertificate verification error: %sChunk delimiter was invalidClient certificate verification failedConnection closedConnection timed outCould not authenticate to proxy server: %sCould not authenticate to server: %sCould not connectCould not connect to proxy serverCould not connect to serverCould not create SSL connection through proxy server: %sCould not create SSL structureCould not create socketCould not determine file size: %sCould not establish connection from SOCKS proxy (%s:%u): %sCould not find IPv4 address of hostname %s for SOCKS v4 proxyCould not inflate dataCould not initialize zlibCould not parse chunk sizeCould not parse redirect destination URLCould not parse response status lineCould not parse response: %sCould not read FQDN length in connect replyCould not read address in connect replyCould not read chunk delimiterCould not read chunk sizeCould not read connect replyCould not read initial response from proxyCould not read interim response headersCould not read login replyCould not read response bodyCould not read response from proxyCould not read status lineCould not resolve hostname `%s': %sCould not seek to offset %s of request body file: %sCould not send connect requestCould not send login messageCould not send message to proxyCould not send requestCould not send request bodyCould not verify server certificate: %sCould not write to file: %sDigest mutual authentication failure: client nonce mismatchDigest mutual authentication failure: could not parse nonce countDigest mutual authentication failure: missing parametersDigest mutual authentication failure: nonce count mismatch (%u not %u)Digest mutual authentication failure: request-digest mismatchError reading response headersGSSAPI authentication error: GSSAPI failure (code %u)Host not foundInvalid Byte Order MarkInvalid Content-Length in responseInvalid HTTP status line in status element at line %d of response: Status line was: %sInvalid version in connect replyInvalid version in login replyInvalid version in proxy responseLOCK response missing Lock-Token headerLine too longNegotiate response verification failed: invalid response header tokenNegotiate response verification failure: %sNo acceptable authentication methodNo activelock for <%s> returned in LOCK refresh responseRange is not satisfiableResource does not support ranged GET requestsResponse did not include requested rangeResponse exceeded maximum number of header fieldsResponse exceeds maximum property countResponse header too longResponse missing activelock for %sSSL alert received: %sSSL disabled due to lack of entropySSL disabled due to library version mismatchSSL error code %d/%d/%luSSL error: %sSSL handshake failed, client certificate was requested: %sSSL handshake failed: %sSSL server did not present certificateSSL socket read failedSecure connection truncatedServer certificate changed: connection intercepted?Server certificate verification failed: Server certificate was missing commonName attribute in subject nameServer did not send certificate chainSocket descriptor number exceeds FD_SETSIZESocket family not supportedTTL expiredUnexpected authentication method chosenUnknown address type in connect replyUnknown errorUnknown transfer-coding in responseXML parse error at line %d: %sXML parse error at line %d: invalid element name[invalid date][unprintable:#%lu][unprintable]address type not supportedbad certificate chaincertificate has been revokedcertificate has expiredcertificate is not yet validcertificate issued for a different hostnamecommand not supportedconnection not permittedcould not establish connection to identdcould not parse challengecould not parse domain in Digest challengefailurehost unreachableignored %s challengeignoring empty Negotiate continuationincompatible algorithm in Digest challengeinitial Digest challenge was staleinvalid Negotiate tokenissuer is not trustedmissing parameter in Digest challengemissing realm in Basic challengenetwork unreachableoffset invalidrejected %s challengerejected due to identd user mismatchrequest rejected or failedsigned using insecure algorithmstale Digest challenge with new algorithm or realmunknown algorithm in Digest challengeunrecognized errors (%u)Project-Id-Version: Neon 0.29.0 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2009-09-04 02:00+0200 Last-Translator: Arfrever Frehtes Taifersar Arahesis Language-Team: Polish Neon Translator Arfrever Frehtes Taifersar Arahesis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit %s: %s (kod %d)%s: czas połączenia się skończył%s: połączenie zostało zamknięte przez serwer proxy%s: połączenie zostało zamknięte przez serwer%s: nierozpoznany błąd (%u)%s: nierozpoznana porażka (%u)Błąd uwierzytelnianiaBłąd weryfikacji certyfikatu: %sOgranicznik kawałka był nieprawidłowyWeryfikacja certyfikatu klienta nie powiodła sięPołączenie zamknięteCzas połączenia się skończyłNie można autentykować się do serwera proxy: %sNie można autentykować się do serwera: %sNie można połączyć sięNie można połączyć się z serwerem proxyNie można połączyć się z serweremNie można utworzyć połączenia SSL przez serwer proxy: %sNie można utworzyć struktury SSLNie można utworzyć gniazdaNie można określić rozmiaru pliku: %sNie można nawiązać połączenia z proxy SOCKS (%s:%u): %sNie można znaleźć adresu IPv4 nazwy hosta %s dla proxy SOCKS v4Nie można Nie można zainicjalizować zlibNie można parsować rozmiaru kawałkaNie można parsować URL-u przeadresowanego celuNie można parsować linii statusu odpowiedziNie można parsować odpowiedzi: %sNie można odczytać długości FQDN w odpowiedzi połączeniaNie można odczytać adresu w odpowiedzi połączeniaNie można odczytać ogranicznika kawałkaNie można odczytać rozmiaru kawałkaNie można odczytac odpowiedzi połączeniaNie można odczytać początkowej odpowiedzi od proxyNie można odczytać nagłówków tymczasowej odpowiedziNie można odczytać odpowiedzi logowaniaNie można odczytać ciała odpowiedziNie można odczytać odpowiedzi od proxyNie można odczytać linii statusuNie można rozwiązać nazwy hosta `%s': %sNie można szukać przesunięcia %s pliku ciała żądania: %sNie można wysłać żądania połączeniaNie można wysłać wiadomości logowaniaNie można wysłać wiadomości do proxyNie można wysłać żądaniaNie można wysłać ciała żądaniaNie można zweryfikować certyfikatu serwera: %sNie można pisać do pliku: %sPorażka wzajemnego uwierzytelniania Digest: niezgodność posłańca klientaPorażka wzajemnego uwierzytelniania Digest: nie można parsować licznika posłańcaPorażka wzajemnego uwierzytelniania Digest: brakujące parametryPorażka wzajemnego uwierzytelniania Digest: niezgodność licznika posłańca (%u nie %u)Porażka wzajemnego uwierzytelniania Digest: niezgodność request-digest mismatchBłąd podczas odczytywania nagłówków odpowiedziBłąd autentykacji GSSAPI: Porażka GSSAPI (kod %u)Host nieznalezionyNieprawidłowy Znacznik Kolejności BajtówNieprawidłowe Content-Length w odpowiedziNiewłaściwa linia statusu HTTP w elemencie statusu w linii %d odpowiedzi: Linia statusu była: %sNieprawidłowa wersja w odpowiedzi połączeniaNieprawidłowa wersja w odpowiedzi logowaniaNieprawidłowa wersja w odpowiedzi proxyOdpowiedź LOCK nie zawiera nagłówka Lock-TokenLinia zbyt długaweryfikacja odpowiedzi Negotiate nie udała się: niewłaściwy żeton nagłówka odpowiedziporażka weryfikacji odpowiedzi Negotiate: %sBrak akceptowalnej metody uwierzytelnianiaNie zwrócono żadnej aktywnej blokady dla <%s> w odpowiedzi LOCK refreshZakres nie może być usatysfakcjonowanyZasób nie obsługuje zakresowych żądań GETOdpowiedź nie zawierała wymaganego zakresuOdpowiedź przekroczyła maksymalną liczbę pól nagłówkaOdpowiedź przekracza maksymalną liczbę właściwościNagłówek odpowiedzi zbyt długiOdpowiedź nie zawiera aktywnej blokady dla %sAlarm SSL otrzymany: %sSSL wyłączone z powodu braku entropiiSSL wyłączone z powodu niezgodności wersji bibliotekiKod błędu SSL %d/%d/%luBłąd SSL: %sUzgodnienie SSL nie udało się, certyfikat klienta został zażądany: %sUzgodnienie SSL nie udało się: %sSerwer SSL nie przedstawił certyfikatuOdczytywanie gniazda SSL nie powiodło sięBezpieczne połączenie obcięteCertyfikat serwera zmienił się: połączenie przechwycone?Weryfikacja certyfikatu serwera nie powiodła się: Certyfikat serwera nie posiada atrybutu commonName w nazwie tematuSerwer nie wysłał łańcucha certyfikatuNumer deskryptoru gniazda przekracza FD_SETSIZERodzina gniazda niewspieranaTTL utraciło ważnośćNieoczekiwana metoda uwierzytelniania wybranaNieznany typ adresu w odpowiedzi połączeniaNieznany błądNieznane transfer-coding w odpowiedziBłąd podczas parsowania XML w linii %d: %sBłąd podczas parsowania XML w linii %d: nieprawidłowa nazwa elementu[nieprawidłowa data][niedrukowalne:#%lu][niedrukowalne]typ adresu niewspieranyzły łańcuch certyfikatucertyfikat został unieważnionycertyfikat wygasłcertyfikat nie jest jeszcze poprawnycertyfikat wydany dla innej nazwy hostapolecenie niewspieranepołączenie niedozwoloneNie można połączyć się z identdnie można parsować wezwanianie można parsować domeny w wezwaniu Digestporażkahost nieosiągalnywezwanie %s zignorowaneignorowanie pustej kontynuacji Negotiateniekompatybilny algorytm w wezwaniu Digestpoczątkowe wezwanie Digest było nieaktualneniewłaściwy żeton Negotiatewydawca nie jest zaufanybrakujący parametr w wezwaniu Digestbrakująca domena w wezwaniu Basicsieć nieosiągalnanieprawidłowe przesunięcieodrzucone wezwanie %sodrzucone z powodu niezgodności użytkownika identdżądanie odrzucone lub nieudanepodpisane przy użyciu niebezpiecznego algorytmunieaktualne wezwanie Digest z nowym algorytmem lub domenąnieznany algorytm w wezwaniu Digestnierozpoznane błędy (%u)davix-R_0_5_0/deps/libneon/po/pl.po000066400000000000000000000417561257152637300172540ustar00rootroot00000000000000# The Polish translation for Neon. # Copyright (C) 2007-2009 Arfrever Frehtes Taifersar Arahesis # This file is distributed under the same license as the Neon package. # Arfrever Frehtes Taifersar Arahesis , 2007-2009. # msgid "" msgstr "" "Project-Id-Version: Neon 0.29.0\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2009-09-04 02:00+0200\n" "Last-Translator: Arfrever Frehtes Taifersar Arahesis \n" "Language-Team: Polish Neon Translator Arfrever Frehtes Taifersar Arahesis " "\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" "Niewłaściwa linia statusu HTTP w elemencie statusu w linii %d odpowiedzi:\n" "Linia statusu była: %s" #: src/ne_auth.c:134 #, c-format msgid "Could not authenticate to server: %s" msgstr "Nie można autentykować się do serwera: %s" #: src/ne_auth.c:139 #, c-format msgid "Could not authenticate to proxy server: %s" msgstr "Nie można autentykować się do serwera proxy: %s" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "odrzucone wezwanie %s" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "brakująca domena w wezwaniu Basic" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "niewłaściwy żeton Negotiate" #: src/ne_auth.c:508 msgid "GSSAPI authentication error: " msgstr "Błąd autentykacji GSSAPI: " #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "Porażka GSSAPI (kod %u)" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "ignorowanie pustej kontynuacji Negotiate" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" "weryfikacja odpowiedzi Negotiate nie udała się: niewłaściwy żeton nagłówka " "odpowiedzi" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "porażka weryfikacji odpowiedzi Negotiate: %s" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "nieznany algorytm w wezwaniu Digest" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "niekompatybilny algorytm w wezwaniu Digest" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "brakujący parametr w wezwaniu Digest" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "początkowe wezwanie Digest było nieaktualne" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "nieaktualne wezwanie Digest z nowym algorytmem lub domeną" #: src/ne_auth.c:796 msgid "could not parse domain in Digest challenge" msgstr "nie można parsować domeny w wezwaniu Digest" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "Porażka wzajemnego uwierzytelniania Digest: brakujące parametry" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" "Porażka wzajemnego uwierzytelniania Digest: niezgodność posłańca klienta" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" "Porażka wzajemnego uwierzytelniania Digest: nie można parsować licznika " "posłańca" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" "Porażka wzajemnego uwierzytelniania Digest: niezgodność licznika posłańca (%" "u nie %u)" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" "Porażka wzajemnego uwierzytelniania Digest: niezgodność request-digest " "mismatch" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "wezwanie %s zignorowane" #: src/ne_auth.c:1378 msgid "could not parse challenge" msgstr "nie można parsować wezwania" #: src/ne_basic.c:98 #, c-format msgid "Could not determine file size: %s" msgstr "Nie można określić rozmiaru pliku: %s" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "Odpowiedź nie zawierała wymaganego zakresu" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "Zakres nie może być usatysfakcjonowany" #: src/ne_basic.c:188 #, c-format msgid "Resource does not support ranged GET requests" msgstr "Zasób nie obsługuje zakresowych żądań GET" #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "%s: %s (kod %d)" #: src/ne_compress.c:232 msgid "Could not inflate data" msgstr "Nie można " #: src/ne_compress.c:293 msgid "Could not initialize zlib" msgstr "Nie można zainicjalizować zlib" #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "[niedrukowalne:#%lu]" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "[niedrukowalne]" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "podpisane przy użyciu niebezpiecznego algorytmu" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "nierozpoznane błędy (%u)" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "Certyfikat serwera nie posiada atrybutu commonName w nazwie tematu" #: src/ne_gnutls.c:879 #, c-format msgid "Could not verify server certificate: %s" msgstr "Nie można zweryfikować certyfikatu serwera: %s" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "Błąd weryfikacji certyfikatu: %s" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "Uzgodnienie SSL nie udało się, certyfikat klienta został zażądany: %s" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, c-format msgid "SSL handshake failed: %s" msgstr "Uzgodnienie SSL nie udało się: %s" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "Serwer nie wysłał łańcucha certyfikatu" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "Odpowiedź LOCK nie zawiera nagłówka Lock-Token" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "Odpowiedź nie zawiera aktywnej blokady dla %s" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" "Nie zwrócono żadnej aktywnej blokady dla <%s> w odpowiedzi LOCK refresh" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "Serwer SSL nie przedstawił certyfikatu" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "Certyfikat serwera zmienił się: połączenie przechwycone?" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "Odpowiedź przekracza maksymalną liczbę właściwości" #: src/ne_redirect.c:92 #, c-format msgid "Could not parse redirect destination URL" msgstr "Nie można parsować URL-u przeadresowanego celu" #: src/ne_request.c:194 #, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: połączenie zostało zamknięte przez serwer proxy" #: src/ne_request.c:197 #, c-format msgid "%s: connection was closed by server" msgstr "%s: połączenie zostało zamknięte przez serwer" #: src/ne_request.c:202 #, c-format msgid "%s: connection timed out" msgstr "%s: czas połączenia się skończył" #: src/ne_request.c:305 #, c-format msgid "Premature EOF in request body file" msgstr "" #: src/ne_request.c:312 #, c-format msgid "Failed reading request body file: %s" msgstr "" #: src/ne_request.c:332 msgid "offset invalid" msgstr "nieprawidłowe przesunięcie" #: src/ne_request.c:337 #, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "Nie można szukać przesunięcia %s pliku ciała żądania: %s" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "Nie można wysłać ciała żądania" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "Nie można odczytać rozmiaru kawałka" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "Nie można parsować rozmiaru kawałka" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "Nie można odczytać ciała odpowiedzi" #: src/ne_request.c:788 msgid "Could not read chunk delimiter" msgstr "Nie można odczytać ogranicznika kawałka" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "Ogranicznik kawałka był nieprawidłowy" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "Nie można odczytać linii statusu" #: src/ne_request.c:918 msgid "Could not parse response status line" msgstr "Nie można parsować linii statusu odpowiedzi" #: src/ne_request.c:930 msgid "Could not read interim response headers" msgstr "Nie można odczytać nagłówków tymczasowej odpowiedzi" #: src/ne_request.c:964 msgid "Could not send request" msgstr "Nie można wysłać żądania" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "Błąd podczas odczytywania nagłówków odpowiedzi" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "Nagłówek odpowiedzi zbyt długi" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "Odpowiedź przekroczyła maksymalną liczbę pól nagłówka" #: src/ne_request.c:1155 #, c-format msgid "Could not resolve hostname `%s': %s" msgstr "Nie można rozwiązać nazwy hosta `%s': %s" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "Nieznane transfer-coding w odpowiedzi" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "Nieprawidłowe Content-Length w odpowiedzi" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "Nie można pisać do pliku: %s" #: src/ne_request.c:1445 #, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "Nie można utworzyć połączenia SSL przez serwer proxy: %s" #: src/ne_request.c:1484 #, c-format msgid "Could not create socket" msgstr "Nie można utworzyć gniazda" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "Nie można połączyć się z serwerem" #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "Nie można połączyć się z serwerem proxy" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "Nie można znaleźć adresu IPv4 nazwy hosta %s dla proxy SOCKS v4" #: src/ne_request.c:1621 #, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "Nie można nawiązać połączenia z proxy SOCKS (%s:%u): %s" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "[nieprawidłowa data]" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "certyfikat nie jest jeszcze poprawny" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "certyfikat wygasł" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "certyfikat wydany dla innej nazwy hosta" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "wydawca nie jest zaufany" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "zły łańcuch certyfikatu" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "certyfikat został unieważniony" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "Weryfikacja certyfikatu serwera nie powiodła się: " #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 msgid "Connection closed" msgstr "Połączenie zamknięte" #: src/ne_socket.c:622 src/ne_socket.c:728 msgid "Secure connection truncated" msgstr "Bezpieczne połączenie obcięte" #: src/ne_socket.c:634 src/ne_socket.c:740 #, c-format msgid "SSL error: %s" msgstr "Błąd SSL: %s" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "Kod błędu SSL %d/%d/%lu" #: src/ne_socket.c:721 #, c-format msgid "SSL alert received: %s" msgstr "Alarm SSL otrzymany: %s" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "Odczytywanie gniazda SSL nie powiodło się" #: src/ne_socket.c:867 msgid "Line too long" msgstr "Linia zbyt długa" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "Host nieznaleziony" #: src/ne_socket.c:1221 msgid "Connection timed out" msgstr "Czas połączenia się skończył" #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "Numer deskryptoru gniazda przekracza FD_SETSIZE" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "Rodzina gniazda niewspierana" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "Weryfikacja certyfikatu klienta nie powiodła się" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "SSL wyłączone z powodu braku entropii" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "SSL wyłączone z powodu niezgodności wersji biblioteki" #: src/ne_socket.c:1730 msgid "Could not create SSL structure" msgstr "Nie można utworzyć struktury SSL" #: src/ne_socks.c:65 msgid "failure" msgstr "porażka" #: src/ne_socks.c:68 msgid "connection not permitted" msgstr "połączenie niedozwolone" #: src/ne_socks.c:71 msgid "network unreachable" msgstr "sieć nieosiągalna" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "host nieosiągalny" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "TTL utraciło ważność" #: src/ne_socks.c:80 msgid "command not supported" msgstr "polecenie niewspierane" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "typ adresu niewspierany" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "%s: nierozpoznany błąd (%u)" #: src/ne_socks.c:128 src/ne_socks.c:328 msgid "Could not send message to proxy" msgstr "Nie można wysłać wiadomości do proxy" #: src/ne_socks.c:133 msgid "Could not read initial response from proxy" msgstr "Nie można odczytać początkowej odpowiedzi od proxy" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "Nieprawidłowa wersja w odpowiedzi proxy" #: src/ne_socks.c:157 msgid "Could not send login message" msgstr "Nie można wysłać wiadomości logowania" #: src/ne_socks.c:162 msgid "Could not read login reply" msgstr "Nie można odczytać odpowiedzi logowania" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "Nieprawidłowa wersja w odpowiedzi logowania" #: src/ne_socks.c:168 msgid "Authentication failed" msgstr "Błąd uwierzytelniania" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "Brak akceptowalnej metody uwierzytelniania" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "Nieoczekiwana metoda uwierzytelniania wybrana" #: src/ne_socks.c:210 msgid "Could not send connect request" msgstr "Nie można wysłać żądania połączenia" #: src/ne_socks.c:215 msgid "Could not read connect reply" msgstr "Nie można odczytac odpowiedzi połączenia" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "Nieprawidłowa wersja w odpowiedzi połączenia" #: src/ne_socks.c:221 src/ne_socks.c:337 msgid "Could not connect" msgstr "Nie można połączyć się" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "Nie można odczytać długości FQDN w odpowiedzi połączenia" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "Nieznany typ adresu w odpowiedzi połączenia" #: src/ne_socks.c:245 msgid "Could not read address in connect reply" msgstr "Nie można odczytać adresu w odpowiedzi połączenia" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "żądanie odrzucone lub nieudane" #: src/ne_socks.c:269 msgid "could not establish connection to identd" msgstr "Nie można połączyć się z identd" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "odrzucone z powodu niezgodności użytkownika identd" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "%s: nierozpoznana porażka (%u)" #: src/ne_socks.c:333 msgid "Could not read response from proxy" msgstr "Nie można odczytać odpowiedzi od proxy" #: src/ne_xml.c:280 #, c-format msgid "XML parse error at line %d: invalid element name" msgstr "Błąd podczas parsowania XML w linii %d: nieprawidłowa nazwa elementu" #: src/ne_xml.c:474 msgid "Unknown error" msgstr "Nieznany błąd" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "Nieprawidłowy Znacznik Kolejności Bajtów" #: src/ne_xml.c:667 #, c-format msgid "XML parse error at line %d: %s" msgstr "Błąd podczas parsowania XML w linii %d: %s" #: src/ne_xmlreq.c:36 #, c-format msgid "Could not parse response: %s" msgstr "Nie można parsować odpowiedzi: %s" davix-R_0_5_0/deps/libneon/po/ru.gmo000066400000000000000000000005771257152637300174270ustar00rootroot00000000000000$,8E9Project-Id-Version: sitecopy 0.11.5 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2002-11-11 14:28+0000 Last-Translator: Michael Sobolev Language-Team: ru MIME-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8bit davix-R_0_5_0/deps/libneon/po/ru.po000066400000000000000000000326151257152637300172610ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) 1999 Michael Sobolev # #, fuzzy msgid "" msgstr "" "Project-Id-Version: sitecopy 0.11.5\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2002-11-11 14:28+0000\n" "Last-Translator: Michael Sobolev \n" "Language-Team: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "%s: : : %s\n" #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "%s: : : %s\n" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 msgid "GSSAPI authentication error: " msgstr "" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "%s: : : %s\n" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "%s: : : %s\n" #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "%s: : : %s\n" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "" #: src/ne_basic.c:188 #, c-format msgid "Resource does not support ranged GET requests" msgstr "" #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "%s: : : %s\n" #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "%s: : : %s\n" #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "%s: : : %s\n" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "%s: : : %s\n" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "" #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "%s: : : %s\n" #: src/ne_request.c:194 #, c-format msgid "%s: connection was closed by proxy server" msgstr "" #: src/ne_request.c:197 #, c-format msgid "%s: connection was closed by server" msgstr "" #: src/ne_request.c:202 #, c-format msgid "%s: connection timed out" msgstr "" #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "%s: : : %s\n" #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "%s: : : %s\n" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "%s: : : %s\n" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "" #: src/ne_request.c:735 #, fuzzy msgid "Could not parse chunk size" msgstr "%s: : : %s\n" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "%s: : : %s\n" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "%s: : : %s\n" #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "%s: : : %s\n" #: src/ne_request.c:964 msgid "Could not send request" msgstr "" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "" #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: : : %s.\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, fuzzy, c-format msgid "Could not write to file: %s" msgstr "%s: : : %s\n" #: src/ne_request.c:1445 #, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "" #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "%s: : : %s\n" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "" #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 msgid "Connection closed" msgstr "" #: src/ne_socket.c:622 src/ne_socket.c:728 msgid "Secure connection truncated" msgstr "" #: src/ne_socket.c:634 src/ne_socket.c:740 #, c-format msgid "SSL error: %s" msgstr "" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, c-format msgid "SSL alert received: %s" msgstr "" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "" #: src/ne_socket.c:1221 msgid "Connection timed out" msgstr "" #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 msgid "Could not create SSL structure" msgstr "" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 msgid "connection not permitted" msgstr "" #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "%s: : : %s\n" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "%s: : : %s\n" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "%s: : : %s\n" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "%s: : : %s\n" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "%s: : : %s\n" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "%s: : : %s\n" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "%s: : : %s\n" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "%s: : : %s\n" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 msgid "Could not read address in connect reply" msgstr "" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 msgid "could not establish connection to identd" msgstr "" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "%s: : : %s\n" #: src/ne_xml.c:280 #, c-format msgid "XML parse error at line %d: invalid element name" msgstr "" #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr " " #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, c-format msgid "XML parse error at line %d: %s" msgstr "" #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "%s: : : %s\n" #, fuzzy #~ msgid "%s: %s" #~ msgstr "%s\n" davix-R_0_5_0/deps/libneon/po/tr.gmo000066400000000000000000000027631257152637300174250ustar00rootroot00000000000000 h!i+GcV G!Wy &DdVv   Could not connect to proxy serverCould not connect to serverCould not parse chunk sizeCould not read chunk sizeCould not read response bodyCould not read status lineCould not send requestCould not send request bodyCould not write to file: %sError reading response headersHost not foundInvalid HTTP status line in status element at line %d of response: Status line was: %sLine too longResponse header too longProject-Id-Version: sitecopy-0.10.10 Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2001-01-03 HO:MI+ZONE Last-Translator: A. Sinan Unur Language-Team: tr MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-9 Content-Transfer-Encoding: 8bit Ara sunucuyla balant kurulamadSunucuyla balant kurulamadPara boyutu anlalamadPara boyutu renilemediYant metni okunamadDurum satr okunamadstek gnderilemedistek metni gnderilemedi%s dosyasna yazm yaplamadYant balklar okunurken hataSunucu bulunamadInvalid HTTP status line in status element at line %d of response: Status line was: %sSatr ok uzunYant bal ok uzundavix-R_0_5_0/deps/libneon/po/tr.po000066400000000000000000000334341257152637300172600ustar00rootroot00000000000000# sitecopy localization for turkish (tr) # Copyright (C) 2001 Free Software Foundation, Inc. # A. Sinan Unur , 2001. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: sitecopy-0.10.10\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2001-01-03 HO:MI+ZONE\n" "Last-Translator: A. Sinan Unur \n" "Language-Team: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-9\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" #: src/ne_auth.c:134 #, fuzzy, c-format msgid "Could not authenticate to server: %s" msgstr "Sunucuyla balant kurulamad" #: src/ne_auth.c:139 #, fuzzy, c-format msgid "Could not authenticate to proxy server: %s" msgstr "Ara sunucuyla balant kurulamad" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "" #: src/ne_auth.c:508 msgid "GSSAPI authentication error: " msgstr "" #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "" #: src/ne_auth.c:796 #, fuzzy msgid "could not parse domain in Digest challenge" msgstr "Para boyutu anlalamad" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "" #: src/ne_auth.c:1378 #, fuzzy msgid "could not parse challenge" msgstr "Para boyutu anlalamad" #: src/ne_basic.c:98 #, fuzzy, c-format msgid "Could not determine file size: %s" msgstr "Dosya alamad: " #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "" #: src/ne_basic.c:188 #, fuzzy, c-format msgid "Resource does not support ranged GET requests" msgstr "Sunucu ksmi GET ilemini desteklemiyor." #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "" #: src/ne_compress.c:232 #, fuzzy msgid "Could not inflate data" msgstr "Dosya alamad: " #: src/ne_compress.c:293 #, fuzzy msgid "Could not initialize zlib" msgstr "Dosyaya yazm yaplamad: " #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "%s dosyasna yazm yaplamad" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "%s dosyasna yazm yaplamad" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "" #: src/ne_redirect.c:92 #, fuzzy, c-format msgid "Could not parse redirect destination URL" msgstr "Durum satr anlalamad." #: src/ne_request.c:194 #, fuzzy, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: balant ara sunucu tarafinden kesildi." #: src/ne_request.c:197 #, fuzzy, c-format msgid "%s: connection was closed by server" msgstr "%s: balant sunucu tarafinden kesildi." #: src/ne_request.c:202 #, fuzzy, c-format msgid "%s: connection timed out" msgstr "%s: balant bekleme snr ald." #: src/ne_request.c:305 #, fuzzy, c-format msgid "Premature EOF in request body file" msgstr "%s dosyasna yazm yaplamad" #: src/ne_request.c:312 #, fuzzy, c-format msgid "Failed reading request body file: %s" msgstr "%s dosyasna yazm yaplamad" #: src/ne_request.c:332 msgid "offset invalid" msgstr "" #: src/ne_request.c:337 #, fuzzy, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "%s dosyasna yazm yaplamad" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "stek metni gnderilemedi" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "Para boyutu renilemedi" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "Para boyutu anlalamad" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "Yant metni okunamad" #: src/ne_request.c:788 #, fuzzy msgid "Could not read chunk delimiter" msgstr "Para boyutu renilemedi" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "Durum satr okunamad" #: src/ne_request.c:918 #, fuzzy msgid "Could not parse response status line" msgstr "Durum satr anlalamad." #: src/ne_request.c:930 #, fuzzy msgid "Could not read interim response headers" msgstr "Yant metni okunamad" #: src/ne_request.c:964 msgid "Could not send request" msgstr "stek gnderilemedi" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "Yant balklar okunurken hata" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "Yant bal ok uzun" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "" #: src/ne_request.c:1155 #, fuzzy, c-format msgid "Could not resolve hostname `%s': %s" msgstr "%s: Hata: %s sunucusunun adresi bulunamad.\n" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "%s dosyasna yazm yaplamad" #: src/ne_request.c:1445 #, fuzzy, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "Ara sunucu zerinden SSL balants kurulamad" #: src/ne_request.c:1484 #, fuzzy, c-format msgid "Could not create socket" msgstr "SSL balants kurulamad" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "Sunucuyla balant kurulamad" #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "Ara sunucuyla balant kurulamad" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "Ara sunucu zerinden SSL balants kurulamad" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "" #: src/ne_session.c:558 msgid "bad certificate chain" msgstr "" #: src/ne_session.c:559 msgid "certificate has been revoked" msgstr "" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 #, fuzzy msgid "Connection closed" msgstr "Balant sunucu tarafndan kesildi" #: src/ne_socket.c:622 src/ne_socket.c:728 #, fuzzy msgid "Secure connection truncated" msgstr "Balant sre snr ald." #: src/ne_socket.c:634 src/ne_socket.c:740 #, fuzzy, c-format msgid "SSL error: %s" msgstr "%s: Hata: %s\n" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "" #: src/ne_socket.c:721 #, fuzzy, c-format msgid "SSL alert received: %s" msgstr "%s: Hata: %s\n" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "" #: src/ne_socket.c:867 msgid "Line too long" msgstr "Satr ok uzun" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "Sunucu bulunamad" #: src/ne_socket.c:1221 #, fuzzy msgid "Connection timed out" msgstr "%s: balant bekleme snr ald." #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "" #: src/ne_socket.c:1730 #, fuzzy msgid "Could not create SSL structure" msgstr "SSL balants kurulamad" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 #, fuzzy msgid "connection not permitted" msgstr "%s: balant bekleme snr ald." #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "stek metni gnderilemedi" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "Yant metni okunamad" #: src/ne_socks.c:136 msgid "Invalid version in proxy response" msgstr "" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "stek gnderilemedi" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "Durum satr okunamad" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "%s dosyasna yazm yaplamad" #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "stek gnderilemedi" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "Sunucuyla balant kurulamad" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "Sunucuyla balant kurulamad" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "Yant metni okunamad" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "Sunucuyla balant kurulamad" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "Yant metni okunamad" #: src/ne_xml.c:280 #, fuzzy, c-format msgid "XML parse error at line %d: invalid element name" msgstr "" "%s: kurulum dosyasnda bozukluk var. satr %d:\n" "%s\n" #: src/ne_xml.c:474 #, fuzzy msgid "Unknown error" msgstr "Bilinmeyen sistem hatas" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "" #: src/ne_xml.c:667 #, fuzzy, c-format msgid "XML parse error at line %d: %s" msgstr "" "%s: kurulum dosyasnda bozukluk var. satr %d:\n" "%s\n" #: src/ne_xmlreq.c:36 #, fuzzy, c-format msgid "Could not parse response: %s" msgstr "Yant metni okunamad" #, fuzzy #~ msgid "%s: %s" #~ msgstr "%s: Hata: %s\n" #~ msgid "Server was not authenticated correctly." #~ msgstr "Server was not authenticated correctly." #~ msgid "Proxy server was not authenticated correctly." #~ msgstr "Proxy server was not authenticated correctly." davix-R_0_5_0/deps/libneon/po/zh_CN.gmo000066400000000000000000000205501257152637300177730ustar00rootroot00000000000000_  )3#]"&* $9 !^  8   ! . E _ (z $    ' F c #~ 4    ;& Ab 8 F =$ b     " V'Y E+8:-S(1'"@#W,{ & 3)(]C%+ #*N0m +/*It%*"%+ Qr2%UF["l  " -Ji6 1Ga}%3)]p03'K.0z"!WD& 0.J`|*$%!"9+\018M  0CRi{*$  $4 Y x  ! !  0!'@! 75>CY4GM" XZW H9236$-ON^<R? ]LF+\'1;UP(I[.A)EB:*0%D V8JKQ#&T,=@!/_S%s: %s (code %d)%s: connection timed out%s: connection was closed by proxy server%s: connection was closed by serverCertificate verification error: %sChunk delimiter was invalidClient certificate verification failedConnection closedConnection timed outCould not authenticate to proxy server: %sCould not authenticate to server: %sCould not connect to proxy serverCould not connect to serverCould not create SSL connection through proxy server: %sCould not create SSL structureCould not create socketCould not determine file size: %sCould not inflate dataCould not initialize zlibCould not parse chunk sizeCould not parse redirect destination URLCould not parse response status lineCould not parse response: %sCould not read chunk delimiterCould not read chunk sizeCould not read interim response headersCould not read response bodyCould not read status lineCould not resolve hostname `%s': %sCould not seek to offset %s of request body file: %sCould not send requestCould not send request bodyCould not write to file: %sDigest mutual authentication failure: client nonce mismatchDigest mutual authentication failure: could not parse nonce countDigest mutual authentication failure: missing parametersDigest mutual authentication failure: nonce count mismatch (%u not %u)Digest mutual authentication failure: request-digest mismatchError reading response headersGSSAPI authentication error: GSSAPI failure (code %u)Host not foundInvalid Byte Order MarkInvalid Content-Length in responseInvalid HTTP status line in status element at line %d of response: Status line was: %sLOCK response missing Lock-Token headerLine too longNegotiate response verification failed: invalid response header tokenNegotiate response verification failure: %sNo activelock for <%s> returned in LOCK refresh responseRange is not satisfiableResource does not support ranged GET requestsResponse did not include requested rangeResponse exceeded maximum number of header fieldsResponse exceeds maximum property countResponse header too longResponse missing activelock for %sSSL alert received: %sSSL disabled due to lack of entropySSL disabled due to library version mismatchSSL error code %d/%d/%luSSL error: %sSSL server did not present certificateSSL socket read failedSecure connection truncatedServer certificate changed: connection intercepted?Server certificate verification failed: Server certificate was missing commonName attribute in subject nameServer did not send certificate chainSocket descriptor number exceeds FD_SETSIZEUnknown errorUnknown transfer-coding in responseXML parse error at line %d: %sXML parse error at line %d: invalid element name[invalid date][unprintable:#%lu][unprintable]certificate has expiredcertificate is not yet validcertificate issued for a different hostnamecould not parse challengecould not parse domain in Digest challengeignored %s challengeignoring empty Negotiate continuationincompatible algorithm in Digest challengeinitial Digest challenge was staleinvalid Negotiate tokenissuer is not trustedmissing parameter in Digest challengemissing realm in Basic challengeoffset invalidrejected %s challengestale Digest challenge with new algorithm or realmunknown algorithm in Digest challengeProject-Id-Version: neon 0.29.x Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk POT-Creation-Date: 2010-10-01 13:30+0100 PO-Revision-Date: 2008-03-03 11:20+0800 Last-Translator: Dongsheng Song Language-Team: neon@webdav.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit %s: %s (代码 %d)%s: 连接超时%s: 连接被代理服务器关闭%s: 连接被服务器关闭证书校验失败:%s非法的分割符客户证书校验失败连接关闭连接超时不能认证到代理服务器: %s不能认证到服务器: %s不能连接到代理服务器不能连接到服务器不能通过代理服务器 “%s” 创建 SSL 连接不能创建 SSL 结构不能创建套接字不能确定的文件大小:%s解压数据失败初始化 zlib 失败不能解析块大小不能解析重定向 URL不能解析响应状态行不能解析响应:%s不能读块分割符不能读块大小不能读临时响应头不能读取响应主体不能读状态行不能解析主机名称 “%s”: %s在请求主体文件不能定位到偏移 %s: %s不能发送请求不能发送请求主体不能写入文件:%s摘要互相认证失败:客户现时不匹配摘要互相认证失败:不能解析现时计数摘要互相认证失败:参数遗漏摘要互相认证失败:现时计算不匹配 (应该是 %u,不是 %u)摘要互相认证失败:请求摘要不匹配读取响应头出错GSSAPI 认证错误: GSSAPI 失败(代码 %u)没有发现主机非法字节顺序标记(BOM)非法的 Content-Length 响应域响应信息中 %d 行的状态元素中发现非法 HTTP 状态行: 状态行是: %sLOCK 的响应遗漏了 Lock-Token 行行太长校验协商响应失败:非法响应头令牌磋商响应校验失败: %s刷新锁定 %s 的响应没有返回主动锁不能满足的范围资源不支持范围读取响应没有包含请求范围响应头的域数量超出了最大数量响应超过了属性的最大计数响应头太长锁定 %s 的响应遗漏了主动锁收到 SSL 警报: %s由于缺少熵,SSL 已经禁用由于库版本不匹配,SSL 已经禁用SSL 错误代码 %d/%d/%luSSL 错误:%sSSL 服务器不能呈现证书SSL 套接字读取失败安全连接切断服务器证书改变:是否被拦截攻击?服务器证书校验失败服务器证书在主题名称遗漏了属性 commonName服务器不能发送证书链套接字数量超过 FD_SETSIZE未知错误响应中的传输代码未知在 %d 行解析 XML 错误: %s在 %d 行解析 XML 错误:非法元素名称[非法日期][非打印字符:#%lu][非打印字符]证书已经过时证书还未生效此证书是为不同的主机名称颁发不能解析挑战在摘要挑战中的不能解析域被忽略的 %s 挑战忽略后续的空磋商在摘要挑战中的算法不兼容陈旧的初始化摘要挑战非法磋商令牌证书发行者不被信任在摘要挑战中的参数丢失在基本挑战中丢失了领域非法偏移被拒绝的 %s 挑战陈旧的摘要挑战用于新算法或新领域在摘要挑战中的算法不可识别davix-R_0_5_0/deps/libneon/po/zh_CN.po000066400000000000000000000354611257152637300176360ustar00rootroot00000000000000# Simplified chinese message for neon # # Copyright (C) 2006-2008 Free Software Foundation, Inc. # This file is distributed under the same license as the neon package. # # Dongsheng Song , 2006-2008 # msgid "" msgstr "" "Project-Id-Version: neon 0.29.x\n" "Report-Msgid-Bugs-To: neon@lists.manyfish.co.uk\n" "POT-Creation-Date: 2010-10-01 13:30+0100\n" "PO-Revision-Date: 2008-03-03 11:20+0800\n" "Last-Translator: Dongsheng Song \n" "Language-Team: neon@webdav.org\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/ne_207.c:198 #, c-format msgid "" "Invalid HTTP status line in status element at line %d of response:\n" "Status line was: %s" msgstr "" "响应信息中 %d 行的状态元素中发现非法 HTTP 状态行:\n" "状态行是: %s" #: src/ne_auth.c:134 #, c-format msgid "Could not authenticate to server: %s" msgstr "不能认证到服务器: %s" #: src/ne_auth.c:139 #, c-format msgid "Could not authenticate to proxy server: %s" msgstr "不能认证到代理服务器: %s" #: src/ne_auth.c:374 #, c-format msgid "rejected %s challenge" msgstr "被拒绝的 %s 挑战" #: src/ne_auth.c:390 msgid "missing realm in Basic challenge" msgstr "在基本挑战中丢失了领域" #: src/ne_auth.c:485 msgid "invalid Negotiate token" msgstr "非法磋商令牌" #: src/ne_auth.c:508 msgid "GSSAPI authentication error: " msgstr "GSSAPI 认证错误: " #: src/ne_auth.c:521 #, c-format msgid "GSSAPI failure (code %u)" msgstr "GSSAPI 失败(代码 %u)" #: src/ne_auth.c:556 msgid "ignoring empty Negotiate continuation" msgstr "忽略后续的空磋商" #: src/ne_auth.c:571 #, c-format msgid "Negotiate response verification failed: invalid response header token" msgstr "校验协商响应失败:非法响应头令牌" #: src/ne_auth.c:593 #, c-format msgid "Negotiate response verification failure: %s" msgstr "磋商响应校验失败: %s" #: src/ne_auth.c:765 msgid "unknown algorithm in Digest challenge" msgstr "在摘要挑战中的算法不可识别" #: src/ne_auth.c:769 msgid "incompatible algorithm in Digest challenge" msgstr "在摘要挑战中的算法不兼容" #: src/ne_auth.c:773 msgid "missing parameter in Digest challenge" msgstr "在摘要挑战中的参数丢失" #: src/ne_auth.c:777 msgid "initial Digest challenge was stale" msgstr "陈旧的初始化摘要挑战" #: src/ne_auth.c:784 msgid "stale Digest challenge with new algorithm or realm" msgstr "陈旧的摘要挑战用于新算法或新领域" #: src/ne_auth.c:796 msgid "could not parse domain in Digest challenge" msgstr "在摘要挑战中的不能解析域" #: src/ne_auth.c:1105 #, c-format msgid "Digest mutual authentication failure: missing parameters" msgstr "摘要互相认证失败:参数遗漏" #: src/ne_auth.c:1110 #, c-format msgid "Digest mutual authentication failure: client nonce mismatch" msgstr "摘要互相认证失败:客户现时不匹配" #: src/ne_auth.c:1120 #, c-format msgid "Digest mutual authentication failure: could not parse nonce count" msgstr "摘要互相认证失败:不能解析现时计数" #: src/ne_auth.c:1125 #, c-format msgid "Digest mutual authentication failure: nonce count mismatch (%u not %u)" msgstr "摘要互相认证失败:现时计算不匹配 (应该是 %u,不是 %u)" #: src/ne_auth.c:1168 #, c-format msgid "Digest mutual authentication failure: request-digest mismatch" msgstr "摘要互相认证失败:请求摘要不匹配" #: src/ne_auth.c:1299 #, c-format msgid "ignored %s challenge" msgstr "被忽略的 %s 挑战" #: src/ne_auth.c:1378 msgid "could not parse challenge" msgstr "不能解析挑战" #: src/ne_basic.c:98 #, c-format msgid "Could not determine file size: %s" msgstr "不能确定的文件大小:%s" #: src/ne_basic.c:149 #, c-format msgid "Response did not include requested range" msgstr "响应没有包含请求范围" #: src/ne_basic.c:183 #, c-format msgid "Range is not satisfiable" msgstr "不能满足的范围" #: src/ne_basic.c:188 #, c-format msgid "Resource does not support ranged GET requests" msgstr "资源不支持范围读取" #: src/ne_compress.c:184 #, c-format msgid "%s: %s (code %d)" msgstr "%s: %s (代码 %d)" #: src/ne_compress.c:232 msgid "Could not inflate data" msgstr "解压数据失败" #: src/ne_compress.c:293 msgid "Could not initialize zlib" msgstr "初始化 zlib 失败" #: src/ne_gnutls.c:172 #, c-format msgid "[unprintable:#%lu]" msgstr "[非打印字符:#%lu]" #: src/ne_gnutls.c:201 msgid "[unprintable]" msgstr "[非打印字符]" #: src/ne_gnutls.c:817 msgid "signed using insecure algorithm" msgstr "" #: src/ne_gnutls.c:820 #, c-format msgid "unrecognized errors (%u)" msgstr "" #: src/ne_gnutls.c:865 src/ne_openssl.c:468 #, c-format msgid "Server certificate was missing commonName attribute in subject name" msgstr "服务器证书在主题名称遗漏了属性 commonName" #: src/ne_gnutls.c:879 #, fuzzy, c-format msgid "Could not verify server certificate: %s" msgstr "不能写入文件:%s" #: src/ne_gnutls.c:891 src/ne_openssl.c:455 #, c-format msgid "Certificate verification error: %s" msgstr "证书校验失败:%s" #: src/ne_gnutls.c:924 src/ne_openssl.c:674 #, c-format msgid "SSL handshake failed, client certificate was requested: %s" msgstr "" #: src/ne_gnutls.c:929 src/ne_openssl.c:679 #, fuzzy, c-format msgid "SSL handshake failed: %s" msgstr "SSL 协商失败:%s" #: src/ne_gnutls.c:939 #, c-format msgid "Server did not send certificate chain" msgstr "服务器不能发送证书链" #: src/ne_locks.c:584 msgid "LOCK response missing Lock-Token header" msgstr "LOCK 的响应遗漏了 Lock-Token 行" #: src/ne_locks.c:759 #, c-format msgid "Response missing activelock for %s" msgstr "锁定 %s 的响应遗漏了主动锁" #: src/ne_locks.c:801 #, c-format msgid "No activelock for <%s> returned in LOCK refresh response" msgstr "刷新锁定 %s 的响应没有返回主动锁" #: src/ne_openssl.c:699 #, c-format msgid "SSL server did not present certificate" msgstr "SSL 服务器不能呈现证书" #: src/ne_openssl.c:708 #, c-format msgid "Server certificate changed: connection intercepted?" msgstr "服务器证书改变:是否被拦截攻击?" #: src/ne_props.c:371 src/ne_props.c:435 msgid "Response exceeds maximum property count" msgstr "响应超过了属性的最大计数" #: src/ne_redirect.c:92 #, c-format msgid "Could not parse redirect destination URL" msgstr "不能解析重定向 URL" #: src/ne_request.c:194 #, c-format msgid "%s: connection was closed by proxy server" msgstr "%s: 连接被代理服务器关闭" #: src/ne_request.c:197 #, c-format msgid "%s: connection was closed by server" msgstr "%s: 连接被服务器关闭" #: src/ne_request.c:202 #, c-format msgid "%s: connection timed out" msgstr "%s: 连接超时" #: src/ne_request.c:305 #, c-format msgid "Premature EOF in request body file" msgstr "" #: src/ne_request.c:312 #, c-format msgid "Failed reading request body file: %s" msgstr "" #: src/ne_request.c:332 msgid "offset invalid" msgstr "非法偏移" #: src/ne_request.c:337 #, c-format msgid "Could not seek to offset %s of request body file: %s" msgstr "在请求主体文件不能定位到偏移 %s: %s" #: src/ne_request.c:385 msgid "Could not send request body" msgstr "不能发送请求主体" #: src/ne_request.c:728 msgid "Could not read chunk size" msgstr "不能读块大小" #: src/ne_request.c:735 msgid "Could not parse chunk size" msgstr "不能解析块大小" #: src/ne_request.c:772 msgid "Could not read response body" msgstr "不能读取响应主体" #: src/ne_request.c:788 msgid "Could not read chunk delimiter" msgstr "不能读块分割符" #: src/ne_request.c:791 msgid "Chunk delimiter was invalid" msgstr "非法的分割符" #: src/ne_request.c:896 msgid "Could not read status line" msgstr "不能读状态行" #: src/ne_request.c:918 msgid "Could not parse response status line" msgstr "不能解析响应状态行" #: src/ne_request.c:930 msgid "Could not read interim response headers" msgstr "不能读临时响应头" #: src/ne_request.c:964 msgid "Could not send request" msgstr "不能发送请求" #: src/ne_request.c:1012 src/ne_request.c:1030 src/ne_request.c:1040 msgid "Error reading response headers" msgstr "读取响应头出错" #: src/ne_request.c:1058 #, c-format msgid "Response header too long" msgstr "响应头太长" #: src/ne_request.c:1140 msgid "Response exceeded maximum number of header fields" msgstr "响应头的域数量超出了最大数量" #: src/ne_request.c:1155 #, c-format msgid "Could not resolve hostname `%s': %s" msgstr "不能解析主机名称 “%s”: %s" #: src/ne_request.c:1286 msgid "Unknown transfer-coding in response" msgstr "响应中的传输代码未知" #: src/ne_request.c:1299 msgid "Invalid Content-Length in response" msgstr "非法的 Content-Length 响应域" #: src/ne_request.c:1372 #, c-format msgid "Could not write to file: %s" msgstr "不能写入文件:%s" #: src/ne_request.c:1445 #, c-format msgid "Could not create SSL connection through proxy server: %s" msgstr "不能通过代理服务器 “%s” 创建 SSL 连接" #: src/ne_request.c:1484 #, c-format msgid "Could not create socket" msgstr "不能创建套接字" #: src/ne_request.c:1518 msgid "Could not connect to server" msgstr "不能连接到服务器" #: src/ne_request.c:1520 msgid "Could not connect to proxy server" msgstr "不能连接到代理服务器" #: src/ne_request.c:1563 #, c-format msgid "Could not find IPv4 address of hostname %s for SOCKS v4 proxy" msgstr "" #: src/ne_request.c:1621 #, fuzzy, c-format msgid "Could not establish connection from SOCKS proxy (%s:%u): %s" msgstr "不能通过代理服务器 “%s” 创建 SSL 连接" #: src/ne_session.c:530 src/ne_session.c:541 msgid "[invalid date]" msgstr "[非法日期]" #: src/ne_session.c:554 msgid "certificate is not yet valid" msgstr "证书还未生效" #: src/ne_session.c:555 msgid "certificate has expired" msgstr "证书已经过时" #: src/ne_session.c:556 msgid "certificate issued for a different hostname" msgstr "此证书是为不同的主机名称颁发" #: src/ne_session.c:557 msgid "issuer is not trusted" msgstr "证书发行者不被信任" #: src/ne_session.c:558 #, fuzzy msgid "bad certificate chain" msgstr "证书已经过时" #: src/ne_session.c:559 #, fuzzy msgid "certificate has been revoked" msgstr "证书已经过时" #: src/ne_session.c:564 msgid "Server certificate verification failed: " msgstr "服务器证书校验失败" #: src/ne_socket.c:516 src/ne_socket.c:612 src/ne_socket.c:716 msgid "Connection closed" msgstr "连接关闭" #: src/ne_socket.c:622 src/ne_socket.c:728 msgid "Secure connection truncated" msgstr "安全连接切断" #: src/ne_socket.c:634 src/ne_socket.c:740 #, c-format msgid "SSL error: %s" msgstr "SSL 错误:%s" #: src/ne_socket.c:637 #, c-format msgid "SSL error code %d/%d/%lu" msgstr "SSL 错误代码 %d/%d/%lu" #: src/ne_socket.c:721 #, c-format msgid "SSL alert received: %s" msgstr "收到 SSL 警报: %s" #: src/ne_socket.c:736 msgid "SSL socket read failed" msgstr "SSL 套接字读取失败" #: src/ne_socket.c:867 msgid "Line too long" msgstr "行太长" #: src/ne_socket.c:1012 src/ne_socket.c:1018 msgid "Host not found" msgstr "没有发现主机" #: src/ne_socket.c:1221 msgid "Connection timed out" msgstr "连接超时" #: src/ne_socket.c:1412 msgid "Socket descriptor number exceeds FD_SETSIZE" msgstr "套接字数量超过 FD_SETSIZE" #: src/ne_socket.c:1474 msgid "Socket family not supported" msgstr "" #: src/ne_socket.c:1701 msgid "Client certificate verification failed" msgstr "客户证书校验失败" #: src/ne_socket.c:1717 msgid "SSL disabled due to lack of entropy" msgstr "由于缺少熵,SSL 已经禁用" #: src/ne_socket.c:1724 msgid "SSL disabled due to library version mismatch" msgstr "由于库版本不匹配,SSL 已经禁用" #: src/ne_socket.c:1730 msgid "Could not create SSL structure" msgstr "不能创建 SSL 结构" #: src/ne_socks.c:65 msgid "failure" msgstr "" #: src/ne_socks.c:68 #, fuzzy msgid "connection not permitted" msgstr "连接超时" #: src/ne_socks.c:71 msgid "network unreachable" msgstr "" #: src/ne_socks.c:74 msgid "host unreachable" msgstr "" #: src/ne_socks.c:77 msgid "TTL expired" msgstr "" #: src/ne_socks.c:80 msgid "command not supported" msgstr "" #: src/ne_socks.c:83 msgid "address type not supported" msgstr "" #: src/ne_socks.c:86 #, c-format msgid "%s: unrecognized error (%u)" msgstr "" #: src/ne_socks.c:128 src/ne_socks.c:328 #, fuzzy msgid "Could not send message to proxy" msgstr "不能发送请求主体" #: src/ne_socks.c:133 #, fuzzy msgid "Could not read initial response from proxy" msgstr "不能读取响应主体" #: src/ne_socks.c:136 #, fuzzy msgid "Invalid version in proxy response" msgstr "非法的 Content-Length 响应域" #: src/ne_socks.c:157 #, fuzzy msgid "Could not send login message" msgstr "不能发送请求" #: src/ne_socks.c:162 #, fuzzy msgid "Could not read login reply" msgstr "不能读状态行" #: src/ne_socks.c:165 msgid "Invalid version in login reply" msgstr "" #: src/ne_socks.c:168 #, fuzzy msgid "Authentication failed" msgstr "GSSAPI 认证错误: " #: src/ne_socks.c:172 msgid "No acceptable authentication method" msgstr "" #: src/ne_socks.c:174 msgid "Unexpected authentication method chosen" msgstr "" #: src/ne_socks.c:210 #, fuzzy msgid "Could not send connect request" msgstr "不能发送请求" #: src/ne_socks.c:215 #, fuzzy msgid "Could not read connect reply" msgstr "不能连接到服务器" #: src/ne_socks.c:218 msgid "Invalid version in connect reply" msgstr "" #: src/ne_socks.c:221 src/ne_socks.c:337 #, fuzzy msgid "Could not connect" msgstr "不能连接到服务器" #: src/ne_socks.c:235 msgid "Could not read FQDN length in connect reply" msgstr "" #: src/ne_socks.c:240 msgid "Unknown address type in connect reply" msgstr "" #: src/ne_socks.c:245 #, fuzzy msgid "Could not read address in connect reply" msgstr "不能读取响应主体" #: src/ne_socks.c:266 msgid "request rejected or failed" msgstr "" #: src/ne_socks.c:269 #, fuzzy msgid "could not establish connection to identd" msgstr "不能连接到服务器" #: src/ne_socks.c:272 msgid "rejected due to identd user mismatch" msgstr "" #: src/ne_socks.c:275 #, c-format msgid "%s: unrecognized failure (%u)" msgstr "" #: src/ne_socks.c:333 #, fuzzy msgid "Could not read response from proxy" msgstr "不能读取响应主体" #: src/ne_xml.c:280 #, c-format msgid "XML parse error at line %d: invalid element name" msgstr "在 %d 行解析 XML 错误:非法元素名称" #: src/ne_xml.c:474 msgid "Unknown error" msgstr "未知错误" #: src/ne_xml.c:579 msgid "Invalid Byte Order Mark" msgstr "非法字节顺序标记(BOM)" #: src/ne_xml.c:667 #, c-format msgid "XML parse error at line %d: %s" msgstr "在 %d 行解析 XML 错误: %s" #: src/ne_xmlreq.c:36 #, c-format msgid "Could not parse response: %s" msgstr "不能解析响应:%s" davix-R_0_5_0/deps/libneon/src/000077500000000000000000000000001257152637300164355ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/src/CMakeLists.txt000066400000000000000000000014211257152637300211730ustar00rootroot00000000000000 LIST(APPEND src_neon "ne_207.c" "ne_acl3744.c" "ne_alloc.c" "ne_auth.c" "ne_basic.c" "ne_compress.c" "ne_dates.c" "ne_i18n.c" "ne_locks.c" "ne_md5.c" "ne_ntlm.c" "ne_oldacl.c" "ne_pkcs11.c" "ne_props.c" "ne_redirect.c" "ne_request.c" "ne_session.c" "ne_socket.c" "ne_socks.c" "ne_sspi.c" "ne_string.c" "ne_uri.c" "ne_utils.c" "ne_xml.c" "ne_xmlreq.c") if(HAVE_OPENSSL) set(src_ssl "ne_openssl.c") endif(HAVE_OPENSSL) if(HAVE_GNUTLS) set(src_ssl "ne_gnutls.c") endif(HAVE_GNUTLS) add_library(neon STATIC ${src_neon} ${src_ssl}) # if the static library is produced, then we need also to install the dependent libraries to be useful if(STATIC_LIBRARY) install(TARGETS neon DESTINATION ${LIB_INSTALL_DIR} ) endif() davix-R_0_5_0/deps/libneon/src/COPYING.LIB000066400000000000000000000613031257152637300201000ustar00rootroot00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Library 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! davix-R_0_5_0/deps/libneon/src/ChangeLog000066400000000000000000005531721257152637300202240ustar00rootroot00000000000000Sun Sep 12 19:21:30 2004 Joe Orton * ne_locks.c (ne_lock_refresh): Fix to pass correct userdata to callbacks, and do call lk_cdata. Sun Sep 12 18:53:15 2004 Joe Orton * Makefile.in (libneon.a): Remove the archive first, avoiding strange problems when build $(OBJECTS) change. Sun Sep 12 18:40:50 2004 Joe Orton * ne_utils.h: Add NE_FEATURE_SOCKS. * ne_utils.c (ne_has_support): Add NE_FEATURE_SOCKS. (version_string): Use NE_HAVE_SOCKS, add NE_HAVE_IDNA. * ne_socket.c (ne_sock_init): Use NE_HAVE_SOCKS. Sun Sep 12 17:29:54 2004 Joe Orton * ne_utils.c (version_string): Declare as array rather than pointer; include "IPv6" component as necessary Sun Sep 12 15:51:38 2004 Joe Orton * ne_socket.c (ne_iaddr_typeof): New function. Sun Sep 12 12:00:10 2004 Joe Orton * ne_defs.h (ne_attribute_malloc): New macro. * ne_alloc.h: Use it to avoid warnings with older GCCs. Wed Aug 25 21:03:40 2004 Joe Orton * ne_string.h (split_string, split_string_c, pair_string, split_string_free, pair_string_free): Remove obsolete interfaces. Wed Aug 25 21:01:03 2004 Joe Orton * ne_cookies.c, ne_cookies.h: Drop cookies support: used old spec revision and wasn't very complete anyway. Wed Aug 25 20:40:26 2004 Joe Orton * ne_socket.c: Remove ne_read, ne_write macros and just use recv and send; remove unused SOCK_ERR macro. Wed Aug 25 20:27:43 2004 Joe Orton * ne_xml.c (declare_nspaces): Drop rejection of names including a colon to prevent breaking SVN deployments. Wed Aug 25 19:45:20 2004 Joe Orton * ne_socket.c (readable_raw): Use poll where available. (ne_sock_connect): Fail if not using poll and fd returned by socket() is greater than FD_SETSIZE. Wed Aug 25 18:40:28 2004 Joe Orton * ne_xml.h (ne_xml_parse): Clarify that a len=0 call is required to signify end-of-document. Wed Aug 25 18:37:13 2004 Joe Orton * ne_request.c (resolve_first, resolve_next): New functions. (lookup_host): Use them to allow user-forced addresses. * ne_session.c (ne_set_addrlist): New function. * ne_private.h (struct ne_session_s): Add addrlist, numaddrs, curaddr fields. Wed Aug 25 18:25:31 2004 Joe Orton * ne_xml.c (struct ne_xml_parser_s): Add bom_pos field. (ne_xml_parse): Skip over the UTF-8 Byte Order Mark since the XML parsers do not support it yet. Wed Jul 7 16:07:44 2004 Joe Orton * ne_request.c (do_connect): Fix ne_conn_connected status call (Shameek Basu). Mon Jul 5 18:40:35 2004 Joe Orton * ne_basic.c (ne_content_type_handler): Use us-ascii as default charset for text/xml, as per RFC3280. Mon Jul 5 10:56:19 2004 Joe Orton * ne_compress.c (struct ne_decompress_s): Add acceptor field. (gz_acceptor): New function. (ne_decompress_reader): Fix to pass the user-supplied userdata pointer to the user-supplied acceptor callback, via gz_acceptor. Mon Jul 5 10:52:40 2004 Joe Orton * ne_compress.c (do_inflate): Don't invoke the reader callback if no bytes where produced by inflate(). (process_footer): Call the reader callback with size=0 to indicate end-of-response for a good checksum match. Sat Jul 3 14:33:56 2004 Joe Orton * ne_auth.c (auth_challenge): Fix to set got_qop in challenge correctly (Hideaki Takahashi). Mon May 17 15:03:54 2004 Joe Orton * ne_socket.h (ne_addr_resolve): Clarify that 'flags' must be passed as zero for forwards-compat. Sun May 2 21:14:14 2004 Joe Orton Fix buffer overflow in RFC1036 date parser, CVE CAN-2004-0389. * ne_dates.c (RFC1036_FORMAT): Specify maximum field with for day name. (ne_rfc1123_parse, ne_rfc1036_parse, ne_asctime_parse): Make thread-safe; remove static buffers. Sun May 2 16:59:39 2004 Joe Orton * ne_dates.c [RFC1123_TEST] (main): Remove embedded test cases. Sun May 2 13:18:29 2004 Joe Orton * Makefile.in (LINK): Add -no-undefined. Fri Apr 16 22:53:59 2004 Joe Orton * ne_xml.c (declare_nspaces, expand_qname): Don't try to include document context in error strings. Fri Apr 16 11:44:34 2004 Joe Orton * Makefile.in (LIBS): Include NEON_LTLIBS. Wed Apr 14 10:39:53 2004 Joe Orton Fix format string vulnerabilities, CVE CAN-2004-0179: * ne_207.c (ne_simple_request): Avoid format string vulnerabilities. * ne_xml.c (ne_xml_set_error): Likewise. * ne_props.c (propfind): Likewise. * ne_locks.c (ne_lock, ne_lock_refresh): Likewise. Wed Apr 14 10:33:46 2004 Joe Orton * ne_auth.c (ah_post_send): Avoid false positives from gcc -Wformat-security. Tue Apr 13 20:51:41 2004 Joe Orton * ne_auth.c: Conditionally include gssapi_generic.h. Thu Apr 8 13:40:03 2004 Joe Orton * ne_props.h: Don't use an anonymous enum for the proppatch operation type, as some C++ compilers don't like it. Wed Apr 7 13:50:10 2004 Joe Orton * ne_request.c (add_fixed_headers): Don't both sending Keep-Alive header if persistent connections are disabled. Wed Apr 7 13:47:46 2004 Joe Orton * ne_auth.c (auth_challenge): Allow Negotiate challenges from a proxy. Wed Apr 7 13:36:55 2004 Joe Orton * ne_auth.c (clean_session): Remove redundant assignment of GSS_C_NO_CONTEXT; gss_delete_sec_context already does this. Wed Apr 7 13:33:10 2004 Joe Orton * ne_auth.c (get_gss_name): Handle failure case internally. (auth_register): Updated accordingly. Wed Apr 7 13:15:57 2004 Joe Orton * ne_request.c: Use strtoq to print off_t's where necessary. Wed Apr 7 11:14:24 2004 Joe Orton * ne_auth.c (get_gss_name): Take a hostname string. (auth_register): Pass proxy or server hostname to get_gss_name as appropriate. Wed Apr 7 11:09:50 2004 Joe Orton * ne_auth.c (continue_negotiate): If given no input token, and the gssctx is not in the initial state, reset it. Mon Mar 29 17:06:49 2004 Joe Orton * ne_auth.c: Adjust to cope with GSSAPI continuation: (struct auth_session_s): Store GSSAPI context, name and mechanism. (get_gss_name): Take an ne_session. (continue_negotiate): Renamed from gssapi_challenge; take input token, handle GSS_S_CONTINUE_NEEDED return value. (verify_digest_response): Renamed from verify_response. (verify_negotiate_response): New function. (auth_challenge): Cope with Negotiate responses which gratuitously break the auth-param grammar. (ah_post_send): Handle Negotiate responses. (free_auth, clean_session): Free persisted GSSAPI objects. (auth_register): Initialize GSSAPI objects. Sun Mar 28 03:03:17 2004 Joe Orton * ne_auth.c (get_gss_name): Don't leak token.value. Sun Mar 28 02:59:58 2004 Joe Orton * ne_auth.c (get_cnonce): Only use RAND_pseudo_bytes() if the PRNG is seeded. Sun Mar 28 02:47:20 2004 Joe Orton * ne_auth.c (gssapi_challenge, get_gss_name): Simplify. Sun Mar 28 02:35:48 2004 Joe Orton * ne_auth.c (request_gssapi, get_gss_name, auth_challenge): Implement the Negotiate protocol rather than the obsoleted GSS-Negotiate. (make_gss_error): New function. (gssapi_challenge): Use it for better error handling (set session error string); fix memory leaks. Don't delegate credentials. Sat Mar 27 20:49:24 2004 Joe Orton * ne_auth.c (ah_post_send): Clear auth header collector buffers after each request. Fri Mar 26 12:16:15 2004 Joe Orton * ne_socket.c (init_ssl): Just initialize the SSL library; delay seeding PRNG until really necessary (performance fix). (seed_ssl_prng): Split from init_ssl. (ne_sock_connect_ssl): Call seed_ssl_prng(). (ne_sock_init): Adjust since init_ssl() can't fail. Fri Mar 26 12:01:38 2004 Joe Orton * ne_utils.c: Include zlib.h before ne_*.h to fix issues on platforms where zconf.h does "#define const". Thu Mar 11 23:38:01 2004 Joe Orton * ne_openssl.c (provide_client_cert): Avoid malloc(0) when server sends no CA names in CertificateRequest. (ne_ssl_cert_write): Be paranoid and clear the OpenSSL error stack on write failures. Sun Mar 7 11:17:04 2004 Joe Orton * Makefile.in (CFLAGS): Don't use NEON_CFLAGS. Mon Feb 23 23:03:08 2004 Joe Orton * ne_string.c (ne_vsnprintf, ne_snprintf): New functions. Sun Feb 22 23:34:47 2004 Joe Orton * ne_private.h (struct ne_session_s): Remove expect100_works field. * ne_request.c (ne_set_request_expect100): New function. (ne_begin_request): Remove req->use_expect100 manipulation. (send_request): Handle enabling 100continue without a request body. * ne_session.c (ne_set_expect100): Removed function. Sun Feb 22 20:17:04 2004 Joe Orton * ne_socket.c (error_ossl): Check for ERR_reason_error_string returning NULL. Sun Feb 22 17:54:43 2004 Joe Orton * ne_socket.c: Don't disable getaddrinfo support here. Sun Feb 22 17:40:07 2004 Joe Orton * ne_utils.h (min): Remove definition to... * ne_uri.c (min): ...here. Sun Feb 22 17:31:35 2004 Joe Orton * ne_props.h: Give the 'type' enum a tag name. Sun Feb 22 17:27:28 2004 Joe Orton * ne_207.c (end_element): Strip whitespace from cdata. Sun Feb 22 16:27:58 2004 Joe Orton * ne_auth.c (struct auth_request): Make auth_hdr, auth_info_hdr fields into ne_buffer *'s. (ah_collect_header): New function. (ah_create): Create ne_buffers for auth_{,info_}hdr; use ah_collect_header rather than ne_duplicate_header to fix handling of multiple auth challenge headers. (ah_post_send): Adjust for char * -> ne_buffer *. (tokenize): Recognize a challenge scheme which is terminated with a comma (i.e. with no challange parameters). (auth_challenge): Fix handling of unrecognized challenges. (ah_destroy): Destroy ne_buffers. Sun Feb 22 15:04:46 2004 Joe Orton * ne_request.c (ne_set_request_body_provider64): New function. Sun Feb 15 13:37:03 2004 Joe Orton * ne_ssl.h: Define that ne_ssl_readable_dname returns UTF-8 encoded strings. * ne_openssl.c (ne_ssl_readable_dname): Convert dname strings to UTF-8, or use "???". Sat Feb 14 21:57:25 2004 Joe Orton * ne_xml.c (invalid_ncname_ch1): New macro. (declare_nspaces): Use it, to reject some more invalid namespace prefixes; also check for a colon anywhere in the NCName. (expand_qname): Likewise for the element name. Mon Feb 9 21:38:03 2004 Joe Orton * ne_dates.c [WIN32] (GMTOFF): Use gmt_to_local_win32; (gmt_to_local_win32): New function, from Jiang Lei. Mon Jan 26 14:38:05 2004 Joe Orton * ne_socket.c (ne_sock_connect_ssl): Check that OpenSSL version matches between library at run-time and headers at compile-time. Sat Jan 24 17:49:27 2004 Joe Orton * ne_dates.c (HAVE_STRUCT_TM___TM_GMTOFF): Alternative GMTOFF() macro. Sat Jan 24 16:49:30 2004 Joe Orton * ne_auth.c (basic_challenge): Cast first parameter to ne_base64 to unsigned char * to fix warnings with some compilers. Sat Jan 3 13:17:36 2004 Joe Orton * ne_request.h (ne_set_request_body_fd64): Define conditional on NE_LFS. * ne_request.c (ne_set_request_body_fd64): Likewise. Thu Jan 1 18:01:45 2004 Joe Orton * ne_request.c: Use NE_HAVE_LFS not _LARGEFILE64_SOURCE in conditional support for off64_t. Thu Jan 1 17:38:55 2004 Joe Orton * ne_request.h [_LARGEFILE64_SOURCE] (ne_set_request_body_fd64): New function. * ne_request.c: Define ne_lseek, ne_off_t, ne_strtoff, NE_OFFT_MAX, FMT_NE_OFF_T appropriately for _LARGEFILE64_SOURCE or otherwise. (struct ne_request_s): Use ne_off_t in place of off_t throughout. (body_fd_send): Use ne_lseek; reset 'remain' after seeking. (clength_hdr_handler): Use ne_off_t, ne_strtoff and NE_OFFT_MAX. (set_body_length): Take an ne_off_t length parameter; use FMT_NE_OFF_T to print it. (ne_set_request_body_fd64): New function. * ne_utils.h (NE_FEATURE_LFS): New feature. * ne_utils.c (ne_has_support): Support NE_FEATURE_LFS. Mon Nov 24 20:13:14 2003 Joe Orton * ne_request.c (struct ne_response): Split handling for chunked vs clength-delimited responses into a union. Use off_t for storing whole-length-of-response values. (read_response_block, ne_read_response_block): Update accordingly. (ne_begin_request): Remove unnecessary variable assignments. Sun Nov 23 16:03:22 2003 Joe Orton * ne_request.h (ne_set_request_body_fd): Take offset and length arguments, return void. (ne_set_request_body_provider): Take off_t length argument. * ne_request.c (struct ne_request_s): Store current position within buffer/file used as request body source. Store request body lengths using off_t type. (body_string_send): Adjust for renamed fields. (body_fd_send): Seek to requested offset; don't read past requested body length. (set_body_length): Renamed from set_body_size. * ne_basic.c (ne_put): Determine file size here; adjust for new ne_set_request_body_fd API. Sun Nov 23 15:05:12 2003 Joe Orton * ne_basic.c, ne_basic.h: Remove two-functions-in-one, ne_put_if_unmodified. Fri Nov 14 14:05:32 2003 Joe Orton * ne_utils.c (ne_has_support): Add NE_FEATURE_IDNA. Fri Nov 14 13:11:49 2003 Joe Orton * ne_session.c (set_hostinfo): [NE_HAVE_LIBIDN]: Use string from IDNA ToAscii operation on provided hostname if successful. Fri Nov 14 11:23:16 2003 Joe Orton All files: replace use of NEON_NODAV with NE_HAVE_DAV, NEON_SSL with NE_HAVE_SSL, NEON_ZLIB with NE_HAVE_ZLIB. Use NE_HAVE_DAV not USE_DAV_LOCKS. * ne_utils.c (ne_has_support): New feature detection interface, replaces ne_supports_ssl. Thu Nov 13 20:38:28 2003 Joe Orton * ne_request.c (ne_begin_request): Presume a 205 response has no message-body too; RFC2616 compliance fix. Thu Nov 13 20:31:07 2003 Joe Orton * ne_auth.c (ah_post_send): Treat a 401 response to a CONNECT request as a valid proxy auth challenge, to work around buggy proxies. Tue Nov 11 21:13:18 2003 Joe Orton Place library-internal symbols in the "ne__" namespace. * ne_request.c (ne__pull_request_body): Renamed from ne_pull_request_body; all callers updated. * ne_session.c (ne__negotiate_ssl): Renamed from ne_negotiate_ssl; all callers updated. Tue Nov 11 21:08:54 2003 Joe Orton * ne_alloc.h: Mark all allocation functions as having 'malloc' attribute for GCC. Tue Nov 11 20:36:12 2003 Joe Orton * ne_xml.h (ne_xml_failure): Replaces ne_xml_valid, inverted and more useful return value. * ne_xml.c (struct ne_xml_parser_s): Replace 'valid' field with 'failure', with inverted logic. (start_element, end_element, char_data): Check failure flag appropriately. Set failure flag to return value of callback. Set failure flag to positive integer on a parse error. (ne_xml_create): Don't initialize failure flag. (ne_xml_parse): Check/set failure flag appropriately. (sax_error): Only set an error string (and the error flag) if failure is zero. * ne_207.c (ne_simple_request): Adjust to use ne_xml_failure. * ne_locks.c (ne_lock, ne_lock_refresh): Likewise. * ne_props.c (propfind): Likewise. Wed Oct 22 22:19:19 2003 Joe Orton * ne_request.c (read_response_block): Treat an EOF without clean SSL closure as a valid request body delimiter in any case. Wed Oct 22 21:44:48 2003 Joe Orton * ne_defs.h (ne_attribute): New macro. * ne_request.h, ne_session.h, ne_utils.h: Use ne_attribute instead of littering #ifdef __GNUC__ and __attribute__ everywhere. Tue Oct 21 20:03:47 2003 Joe Orton Fix various strict signedness bugs: * ne_auth.c (auth_session): Make nonce_count argument unsigned. (get_cnonce): Use unsigned data buffer. (get_gss_name, gssapi_challenge): Use unsigned integers for status variables. (request_digest): Print nonce count as unsigned. (verify_response): Make nonce_count unsigned. Tue Oct 7 20:52:06 2003 Joe Orton When using SSL via a proxy, don't leak server auth credentials to the proxy, and vice versa. * ne_auth.c (auth_session): Add context field. (ah_create): Ignore challenges in a bad context. (ah_pre_send, ah_destroy): Check that the request-private cookie is not NULL. (auth_register): Take an isproxy flag; set context field appropriately in session structure. (ne_set_server_auth, ne_set_proxy_auth): Adjust accordingly. Tue Oct 7 19:58:52 2003 Joe Orton * ne_openssl.c (ne_negotiate_ssl): If the returned cert chain was NULL, try and create one from the peer certificate alone (fix for use of SSLv2 connections). Mon Sep 29 21:57:40 2003 Joe Orton * ne_auth.c [WIN32]: Include windows.h to fix non-SSL build. Thu Sep 25 20:05:18 2003 Joe Orton * ne_xml.c (ne_xml_create): Specify an initial error string. Sun Sep 21 23:00:10 2003 Joe Orton * ne_cookies.c (set_cookie_hdl): Strip whitespace around cookie name and value. Sun Sep 14 10:50:01 2003 Joe Orton * ne_socket.c (ne_addr_resolve): Use result of autoconf test for working AI_ADDRCONFIG support. Sat Sep 6 12:05:00 2003 Joe Orton * ne_openssl.c (check_identity): Take an optional server address argument; check identity against IPaddress extension too if given. (check_certificate): Optionally pass server address to check_identity. (populate_cert): Adjust accordingly. Thu Sep 4 21:41:38 2003 Joe Orton * ne_socket.c (ne_sock_init): Succeed even if PRNG was not seeded. Thu Sep 4 21:33:34 2003 Joe Orton * ne_session.c (ne_set_useragent): Build and store the entire User-Agent header field in sess->user_agent. * ne_request.c (add_fixed_headers): Adjust accordingly; avoid unnecessary calls to ne_buffer_*. Thu Sep 4 21:27:34 2003 Joe Orton * ne_socket.c: Include netinet/tcp.h. (ne_sock_connect): Disable the Nagle algorithm; thanks to Jim Whitehead and Teng Xu for the analysis. Thu Sep 4 11:24:04 2003 Joe Orton * ne_defs.h: Define ssize_t here for Win32. * ne_socket.h: Don't define ssize_t here. Tue Sep 2 20:20:16 2003 Joe Orton * ne_auth.c (auth_challenge): Update to use ne_token not split_string, patch by Tom Lee . Wed Jul 30 21:54:38 2003 Joe Orton * ne_cookies.c (set_cookie_hdl): Fix NULL pointer dereference; thanks to Markus Mueller . Fri Jul 25 11:05:52 2003 Joe Orton * ne_request.c (do_connect): On failure to connect, set error string and call ne_sock_close directly rather than using aborted(); fix leak of socket structure. Wed Jul 23 23:20:42 2003 Joe Orton Fix SEGV if inflateInit2 fails with Z_MEM_ERROR etc. * ne_compress.c (set_zlib_error): New function. (do_inflate, gz_reader): Use it. Wed Jul 23 22:50:50 2003 Joe Orton Add support for GSS-Negotiate; patch from Risko Gergely and Burjan Gabor: * ne_auth.c [HAVE_GSSAPI]: Include gssapi.h. (auth_scheme): Add auth_scheme_gssapi. (auth_session): Add gssapi_token. (clean_session): Free gssapi_token. (request_gssapi, get_gss_name, gssapi_challenge): New functions. (tokenize): Handle challenge with single token. (auth_challenge): Accept and process a GSS-Negotiate challenge. (ah_pre_send): Send GSS-Negotiate handshake. Wed Jul 23 22:46:28 2003 Joe Orton * ne_207.c (ne_207_set_response_handlers, ne_207_set_propstat_handlers): Fix to match declarations (thanks to Diego Trtara). Fri Jun 27 20:30:45 2003 Joe Orton * ne_openssl.c [OPENSSL_VERSION_NUMBER < 0x0090700fL]: Fix build against OpenSSL < 0.9.7. Sun Jun 22 23:07:45 2003 Joe Orton * ne_session.c (ne_session_destroy): Replace unnecessary use of NE_FREE with ne_free. (set_hostinfo): Don't free hostport/hostinfo here. (ne_session_proxy): Free existing proxy hostname here if necessary. Sat Jun 21 12:58:25 2003 Joe Orton * ne_request.c (ne_begin_request): Set or clear is_http11 flag for each request. Wed Jun 18 20:54:44 2003 Joe Orton * ne_socket.c: Add AI_ADDRCONFIG support; [USE_CHECK_IPV6]: Define only if __linux__. (init_ipv6) [USE_CHECK_IPV6]: New conditional. (ne_addr_resolve) [USE_ADDRCONFIG]: Use AI_ADDRCONFIG. Wed Jun 18 20:03:13 2003 Joe Orton * ne_socket.c (ne_sock_create): New function (renamed from create_sock). (ne_sock_connect): Take an ne_socket *, return int. (ne_sock_accept): Likewise. (ne_sock_close): Only call ne_close if fd is non-negative. * ne_request.c (aborted): Handle NE_SOCK_* errors specially. (do_connect): Adapt for ne_sock_create/connect interface. Set sess->connected here on success. (open_connection): Don't set sess->connected here. Sun Jun 15 12:14:22 2003 Joe Orton * ne_ssl.h (ne_ssl_cert_digest): Pass digest as a pointer rather than an array. Sun Jun 15 11:00:09 2003 Joe Orton * ne_stubssl.c (ne_ssl_cert_cmp): Add stub. Wed May 28 21:37:27 2003 Joe Orton * ne_openssl.c (ne_ssl_context_create): Enable workarounds in OpenSSL for better interop with buggy SSL servers. Fri May 23 23:13:30 2003 Joe Orton * ne_stubssl.c (ne_ssl_set_clicert): Add stub. Sat May 10 17:05:26 2003 Joe Orton * ne_xml.c: Rename struct ne_xml_handler to struct handler. Thu May 8 20:55:46 2003 Joe Orton * ne_openssl.c (ne_ssl_clicert_read): Pass "b" to fopen. Tue May 6 22:08:08 2003 Joe Orton * ne_openssl.c (check_certificate): Re-order verify failure handling to allow caller to set a custom session error string. Tue May 6 20:21:27 2003 Joe Orton * ne_md5.c (md5_stream): Restore. Sat Apr 26 19:21:03 2003 Joe Orton * ne_request.c (te_hdr_handler): Treat presence of any T-E response header as implying the response is chunked, regardless of value. Sat Apr 26 18:11:24 2003 Joe Orton * ne_xml.c: Rename struct ne_xml_nspace to struct namespace. Wed Apr 23 22:19:29 2003 Joe Orton * ne_openssl.c (ne_ssl_cert_export): Don't bother checking for i2d_X509() failure; no OpenSSL code ever checks, so everyone's doomed if it really can fail. Wed Apr 23 22:01:23 2003 Joe Orton * ne_openssl.c (ne_ssl_cert_import, ne_ssl_cert_export, ne_ssl_cert_write): Clear OpenSSL error stack on errors. Wed Apr 23 18:23:53 2003 Joe Orton * ne_stubssl.c (ne_ssl_cert_write, ne_ssl_cert_import, ne_ssl_cert_export): Add stubs. Wed Apr 23 14:05:32 2003 Joe Orton * ne_openssl.c (ne_ssl_cert_write): New function. Tue Apr 22 23:21:22 2003 Joe Orton * ne_string.c (ne_unbase64): Optimise out some redundant branches. Tue Apr 22 20:24:44 2003 Joe Orton * ne_openssl.c (ne_ssl_cert_export, ne_ssl_cert_import, ne_ssl_cert_cmp): New functions. Tue Apr 22 18:31:55 2003 Joe Orton * ne_string.c (ne_unbase64): New function. Tue Apr 22 15:53:41 2003 Joe Orton * ne_string.c (ne_base64): Fix encoding binary data; take unsigned argument. Tue Apr 22 13:07:48 2003 Joe Orton * ne_stubssl.c (ne_ssl_cert_validity): Add stub. Tue Apr 22 09:22:26 2003 Joe Orton * ne_openssl.c (ne_ssl_cert_validity): New function. (asn1time_to_string): Format into a fixed-size buffer. Tue Apr 22 08:38:30 2003 Joe Orton * ne_locks.c (ne_lock_discover, ne_lock): Don't leak the cdata buffer. * ne_props.c (ne_propfind_destroy): Don't leak the value buffer. Mon Apr 21 23:52:25 2003 Joe Orton * ne_xml.c (ne_xml_destroy): Free root element. Mon Apr 21 23:46:17 2003 Joe Orton * ne_openssl.c (dup_client_cert): Set decrypted state; dup the friendly name. (ne_ssl_clicert_free): Free friendly name. Mon Apr 21 19:44:55 2003 Joe Orton * ne_md5.h (ne_md5_buffer, ne_md5_stream): Remove unused functions. Mon Apr 21 18:17:14 2003 Joe Orton * ne_locks.c, ne_207.c: s/NE_ELM_/ELM_/ since no element ids are exported. Mon Apr 21 16:38:14 2003 Joe Orton Redesign the XML interface: have startelm callback map {nspace, name} onto a state integer or decline. Remove "valid"/"invalid"; don't abort the parse if no handler accepts an element. Push cdata accumulation down into the caller; drop collect mode, stripws mode. * ne_xml.h (ne_xml_elmid, struct ne_xml_elm): Removed. (ne_xml_startelm_cb): Return a state/acceptance integer, take a state integer, nspace, name and atts. (ne_xml_endelm_cb, ne_xml_cdata_cb): Take a state integer. (ne_xml_push_mixed_handler): Removed. (ne_xml_push_handler): Removed element list argument. (struct ne_xml_idmap, ne_xml_mapid): New interface. * ne_xml.c (struct element): Replaces ne_xml_state. Add name, nspace, state fields. (friendly_name, find_handler, parse_element, ne_xml_push_mixed_handler, push_handler): Removed functions. (declare_nspaces, expand_qname): Factored out from find_handler and parse_element. (start_element): Use expand_qname, declare_nspaces. Find appropriate handler here. Guarantee not to pass a NULL atts array to the start-element callback. Drop collect mode. (end_element): Drop collect mode (ne_xml_push_handler): Fold push_handler back in. (ne_xml_mapid): New function. * ne_207.h (NE_ELM_*): Don't export element id. (NE_207_STATE_PROP, NE_207_STATE_TOP): Export state integers. * ne_207.c (struct ne_207_parser_s): Add cdata field. (map207): Replace element list with idmap array. (can_handle): New function, replacing check_context logic. (start_element): Determine new state integer; only accept the element in valid states. Clear cdata. (end_element): Use state rather than element id. Do nothing for end of 'response' element if element is incomplete. (ne_207_create): Create cdata buffer. (ne_207_destroy): Destroy cdata buffer. (ne_207_ignore_unknown): Removed function. (ne_simple_request): Don't call ne_207_ignore_unknown. * ne_props.h (NE_PROPS_STATE_TOP): Define state. * ne_props.c (struct ne_propfind_handler_s): Add value and depth fields. (ELM_flatprop): Define state. (flat_elms): Removed array. (chardata): Append to value field when in ELM_flatprop state. (startelm): Decline everything other than elements within the 'prop' state. Collect flatprop contents. (endelm): Collect flatprop contents. * ne_locks.c (struct discover_ctx, struct lock_ctx): Store cdata. (element_map): Replace element list with idmap array. (can_accept): Replaces check_context callback. (ld_startelm, lk_cdata, ld_cdata): New functions. Mon Apr 14 00:04:20 2003 Joe Orton * ne_207.h (ne_207_start_response, ne_207_end_response, ne_207_start_propstat, ne_207_end_propstat): Use ANSI-style function pointers in typedefs. * ne_207.c (struct ne_207_parser_s): Updated accordingly. Mon Apr 14 00:02:10 2003 Joe Orton * ne_request.c (read_response_block): Better error messages for invalid chunks, don't use strncmp for a two-character comparison. Mon Apr 7 22:26:50 2003 Joe Orton * ne_stubssl.c (ne_ssl_cert_identity): New function. Mon Apr 7 22:16:16 2003 Joe Orton * ne_openssl.c (struct ne_ssl_certificate_s): Add identity field. (check_identity): Add optional identity argument. (populate_cert): Retrieve cert identity using check_identity. (check_certificate): Pass extra NULL to check_identity. (ne_ssl_cert_identity): New function. (ne_ssl_cert_free): Free the identity field. Mon Apr 7 21:29:54 2003 Joe Orton * ne_openssl.c (check_identity): Take a string hostname rather than a session object. (check_certificate): Adjust accordingly. Sun Apr 6 21:26:05 2003 Joe Orton * ne_string.h (NE_HEX2ASC): Cast result to char to avoid warnings with some compilers. Sun Apr 6 20:11:42 2003 Joe Orton * ne_openssl.c (ne_ssl_readable_dname): Include commonName or emailAddress in returned string if either is the only attribute. Sun Mar 30 10:54:20 2003 Joe Orton Split decryption of client certs into two steps * ne_openssl.c (ne_ssl_clicert_encrypted, ne_ssl_clicert_decrypt): New functions. (ne_ssl_client_cert_s): Add p12 and decrypted fields. (find_friendly_name): New function. (get_friendly_name): Removed function. (ne_ssl_clicert_read): Drop password callback; on decrypt failure, extract friendly name and set decrypted state of clicert. Sun Mar 30 10:54:01 2003 Joe Orton * ne_stubssl.c (ne_ssl_clicert_encrypted, ne_ssl_clicert_decrypt): New stubs. (ne_ssl_clicert_read): Adjusted for API change. Sat Mar 29 14:23:37 2003 Joe Orton * ne_openssl.c (ne_ssl_dname_cmp): New function. * ne_stubssl.c (ne_ssl_dname_cmp): New function. Sat Mar 29 13:52:47 2003 Joe Orton * ne_openssl.c (struct ne_ssl_client_cert_s): Add 'friendly_name' field. (get_friendly_name, ne_ssl_clicert_name): New functions. (ne_ssl_clicert_read): Store the cert's friendly name. * ne_stubssl.c (ne_ssl_clicert_name): New function. Sat Mar 29 13:16:14 2003 Joe Orton * ne_openssl.c (ne_ssl_clicert_owner): New function. Fri Mar 28 22:12:57 2003 Joe Orton * ne_stubssl.c (ne_ssl_cert_digest): New function. * ne_openssl.c (ne_ssl_cert_digest): New function. Wed Mar 26 20:41:57 2003 Joe Orton * ne_session.c (ne_ssl_trust_cert) [NEON_SSL]: Only build when SSL support is present. Wed Mar 26 20:01:00 2003 Joe Orton Begin abstraction of SSL layer to better isolate SSL-library-specific code, and to improve certificate handling interface. Drop support for PEM-encoded client certificates. * ne_session.h (ne_ssl_trust_cert): Replaces ne_ssl_load_ca, in conjunction with ne_ssl_load_cert. (ne_ssl_trust_default_ca): Replaces ne_ssl_load_default_ca. (ne_ssl_keypw_prompt): Removed function, no longer needed. (ne_ssl_set_clicert): Replaces ne_ssl_load_pkcs12, in conjunction with ne_ssl_clicert_read. (ne_ssl_provide_clicert): Replaces ne_ssl_provide_ccert, callback type changed. * ne_openssl.c: New file; much code moved from ne_session.c. * ne_privssl.h: New file, private interface between ne_socket.c and ne_openssl.c. * ne_ssl.h: New file. * ne_private.h (struct ne_session_s): Store pointers to ne_ssl_client_cert etc opaque objects, not OpenSSL structures. * ne_session.c: Most of ne_ssl_* moved to ne_openssl.c. (ne_session_create, ne_session_destroy): Use ne_ssl_cert_* etc to manage cert objects. * ne_socket.c (struct ne_socket_s): Replace SSL *, SSL_CTX * pointers with an ne_ssl_socket * pointer. (readable_ossl, error_ossl, read_ossl, write_ossl, ne_sock_close): Compensate for above change. (ne_sock_use_ssl): Removed function. (ne_sock_switch_ssl): Pass in SSL * as void for time being. (ne_sock_connect_ssl): Renamed and cleaned up version of ne_sock_use_ssl_os. (ne_sock_sslsock): New function. * Makefile.in: Add deps for ne_openssl.c. Sun Mar 23 13:02:58 2003 Joe Orton * ne_session.c (ne_set_useragent): Use ne_malloc. Sat Mar 22 21:06:45 2003 Joe Orton * ne_socket.c (raw_connect): Fill in sin6_family or sin_family since AIX 4.3 fails to do so. Wed Mar 19 20:44:11 2003 Joe Orton * ne_session.c [NEON_SSL] (free_client_cert): Build conditional on NEON_SSL. Mon Mar 17 20:33:32 2003 Joe Orton * ne_socket.c: Include netdb.h conditional on HAVE_NETDB_H. (fix build for older versions of CygWin). Sun Mar 16 23:30:20 2003 Joe Orton * ne_session.c (check_identity): Fix leak of subject alt. name structures. Sun Mar 16 19:21:22 2003 Joe Orton * ne_session.c (free_client_cert): New function. (ne_session_destroy, ne_ssl_load_pem, ne_ssl_load_pkcs12): Call it; prevent memory leak if ne_ssl_load_{pem,pkcs12} are called >1 per session. Sun Mar 16 18:00:34 2003 Joe Orton * ne_session.c (provide_client_cert): Free peer certificate after use. (ne_session_destroy): Free client cert and key if present. Sun Mar 16 14:23:05 2003 Joe Orton * ne_xml.c [HAVE_EXPAT]: Include xmlparse.h for bundled expat build. * ne_utils.c: Only include expat.h if HAVE_XMLPARSE_H is not defined. Wed Mar 12 15:04:13 2003 Joe Orton * ne_redirect.c (struct redirect): Add 'valid' field. (post_send): Set and clear 'valid' to keep track of whether stored URI is valid. (ne_redirect_location): Return NULL if stored URI is not valid. Wed Mar 12 14:52:49 2003 Joe Orton * ne_uri.c (ne_uri_free): Zero-initialize structure after free'ing. Tue Mar 11 22:01:11 2003 Joe Orton * ne_redirect.c (ne_redirect_location): Return NULL if no redirect session is registered, rather than SEGV; Ralf Mattes . Sun Mar 9 16:33:24 2003 Joe Orton Fix a memory leak if an XML parse error occurs during a PROPFIND response: * ne_props.c (ne_propfind_current_private): Return NULL if no propset is being processed. (free_propset): Free propset href here. (end_response): Don't free propset href here. Set current field of handler to NULL after free'ing propset. (ne_propfind_destroy): Free current propset if one was being processed. Sun Mar 9 11:53:58 2003 Joe Orton * ne_207.c (ne_207_destroy): Fix possible leak of reason_phrase string. Sun Mar 9 11:01:15 2003 Joe Orton * ne_utils.c (ne_parse_statusline): Use ne_strclean. * ne_session.c (ne_get_error): Use ne_strclean. Sun Mar 9 10:53:52 2003 Joe Orton * ne_xml.c: Remove broken "UTF-8 decoding" support used for libxml 1.x. Sun Mar 9 09:55:26 2003 Joe Orton * ne_xml.c: Drop support for expat < 1.95.0 and libxml 1.x. * ne_utils.c (version_string): Include expat version string. Sun Mar 9 09:54:00 2003 Joe Orton * ne_socket.c: Don't declare h_errno on Win32 either. Sun Mar 9 08:49:40 2003 Joe Orton * ne_string.c (do_concat) [HAVE_STPCPY]: Use stpcpy rather than strlen/memcpy, when available. Mon Mar 3 22:17:04 2003 Joe Orton * ne_socket.c [!USE_GETADDRINFO && !HAVE_DECL_H_ERRNO): Declare h_errno (fix build on SCO OpenServer 5.0). Sat Mar 1 21:22:19 2003 Joe Orton * ne_redirect.c (free_redirect): Fix once-per-session memory leak. Sat Mar 1 20:23:47 2003 Joe Orton Add implemention of simple memory leak tracking, for testing purposes. * ne_alloc.c [NEON_MEMLEAK] (tracking_malloc, ne_free_ml, ne_malloc_ml, ne_calloc_ml, ne_realloc_ml, ne_strdup_ml, ne_strndup_ml, ne_memleak_dump): New functions. * memleak.h: New header. Sat Mar 1 13:44:26 2003 Joe Orton First step towards automated memory leak tests. * ne_alloc.c (ne_free): New function. * All files: replace use of free() with ne_free(). Sat Mar 1 09:48:39 2003 Joe Orton * ne_uri.c (ne_path_unescape): Fix memory leak on invalid URI. Sat Mar 1 08:03:18 2003 Joe Orton * ne_string.c (ne_strclean): New function. Wed Feb 26 21:45:12 2003 Joe Orton * ne_request.c (ne_begin_request, proxy_tunnel, open_connection) [NEON_SSL] Don't build CONNECT tunnel support code if SSL is not supported. Wed Feb 26 21:44:18 2003 Joe Orton * ne_utils.c (ne_debug_init): Allow ne_debug_init(NULL, 0) to turn off debugging. Fix to produce debug output if the any of the specified "channels" are active, not all. (also fixing NE_DBG_FLUSH support). Tue Feb 25 23:12:31 2003 Joe Orton * ne_compress.c (process_footer): Mention number of extra bytes in error message for oversized footer. Sun Feb 23 21:19:20 2003 Joe Orton * ne_auth.c (verify_response): Fix to parse nonce count as hex string rather than decimal; fix verification of >9 responses. Thu Feb 13 20:35:45 2003 Joe Orton * ne_session.c (ne_set_useragent): Fix to append "neon/x.y.z" to application-supplied token rather prepend. Thu Feb 13 09:06:22 2003 Joe Orton * ne_request.c (open_connection): Fix for CONNECT tunnelling (regression since 0.23.x), thanks to Nathan Hand . Mon Feb 3 22:10:54 2003 Joe Orton Implement Daniel Stenberg's trick to avoid the slow AF_UNSPEC lookups on Linux: * ne_socket.c (init_ipv6, ipv6_disabled): New function and global. (ne_sock_init): Call init_ipv6. (ne_addr_resolve) [USE_GETADDRINFO]: Pass AF_INET in hints if ipv6_disabled is set. Mon Feb 3 20:55:47 2003 Joe Orton * ne_socket.c [__hpux && USE_GETADDRINFO]: Undefine USE_GETADDRINFO to work around broken implementation in HP-UX 11.11. Mon Jan 27 21:39:31 2003 Joe Orton * ne_socket.c (write_raw): Fix for handling EINTR during write(), from Sergey N Ushakov. Thu Jan 16 21:59:03 2003 Joe Orton Allow _init after _finish to succeed: Sergey N Ushakov. * ne_socket.c (init_result): New global variable. (ne_sock_init): Use init_result global rather than result. (ne_sock_finish): Clear init_result. Fri Dec 27 17:03:17 2002 Joe Orton * ne_request.c (build_request): Remove redundant call to ne_buffer_clear. Fri Dec 27 14:38:08 2002 Joe Orton * ne_request.c (ne_request_create): strdup the method string. (ne_request_destroy): free the method. Mon Dec 23 17:04:32 2002 Joe Orton * ne_socket.c (ne_write, ne_read, ne_close, ne_errno): Renamed macros from NEON_WRITE, NEON_READ, NEON_CLOSE, NEON_ERRNO. All callers changed. Mon Dec 23 16:58:43 2002 Joe Orton Add proper Win32 socket error handling, merged efforts of Johan Lindh and Sergey N Ushakov : * ne_socket.c (ne_errno, NE_ISINTR, NE_ISRESET, NE_ISCLOSED): New macros. [WIN32] (print_error): New function. (set_strerror) [WIN32]: Use print_error. (readable_raw, read_raw, write_raw): Use new error handling macros. (ne_addr_resolve) [WIN32]: Use WSAGetLastError() rather than h_errno. (ne_addr_error) [WIN32]: Use print_error. Tue Dec 10 21:41:26 2002 Joe Orton * ne_socket.c (ne_iaddr_print): Renamed from ne_addr_print for consistency with other ne_iaddr_ functions. Sun Dec 8 20:08:31 2002 Joe Orton * ne_auth.c (get_cnonce): Use GetCurrentThreadId() on Win32. Sun Nov 24 18:45:32 2002 Joe Orton * ne_auth.c: Remove qop_values and algorithm_names arrays. (request_digest): Inlined qop, algorithm name lookups accordingly. Sun Nov 24 16:45:39 2002 Joe Orton * ne_auth.h: Renamed ne_request_auth typedef to ne_auth_creds. * ne_auth.c (auth_session): Renamed reqcreds, recreds_ud fields to creds, userdata. (auth_register, ne_set_proxy_auth, ne_set_server_auth): Update for ne_request_auth rename. Fri Nov 22 17:39:35 2002 Joe Orton * ne_auth.c (auth_challenge): Fix support for RFC2617-style digest auth; notice the qop= parameter in challenge. Fix leak of parsed qop array. Fri Nov 22 17:08:01 2002 Joe Orton * ne_auth.c (get_cnonce): Rewrite to use either pseudo-random data from the SSL library (if available), or really-not-random data from gettimeofday/getpid otherwise. Sun Nov 17 22:13:49 2002 Joe Orton * ne_socket.c (ne_addr_print) [USE_GETADDRINFO]: Use the SACAST() macro. Sun Nov 17 19:29:23 2002 Joe Orton * ne_socket.c (ne_sock_connect): Make address argument const. (raw_connect): Make address argument const; adjust to use a copy of the sockaddr structure, which is correct anyway. (ne_addr_first, ne_addr_next): Make return pointer const. * ne_private.h (struct host_info): Store current address as const. Sun Nov 17 19:03:01 2002 Joe Orton * ne_socket.c (ne_register_progress): Removed function. * ne_socket.h (ne_block_reader, ne_progress, ne_register_progress): Removed. * ne_request.c (do_connect): Don't call ne_register_progress. * ne_request.h: Add ne_block_reader typedef. * ne_session.h: Include sys/types.h; add ne_progress typedef. Sun Nov 17 18:59:29 2002 Joe Orton * ne_socket.c (ne_iaddr_make, ne_iaddr_cmp, ne_iaddr_free): New functions. Mon Nov 11 19:51:24 2002 Joe Orton Allow discovery of document encoding. * ne_xml.c [HAVE_EXPAT]: (struct ne_xml_parser_s): Add encoding field. (decl_handler): New function. (ne_xml_doc_encoding): New function. Mon Nov 11 19:48:43 2002 Joe Orton * ne_xml.c (sax_handler): Use sax_error for fatal error callback. Fri Oct 11 23:50:01 2002 Joe Orton * ne_private.h (struct ne_session_s): Change 'connected' to be a simple boolean flag. * ne_session.c (ne_close_connection): Treat 'connected' as a boolean. * ne_request.c (open_connection): Greatly simplified. Fri Oct 11 00:46:52 2002 Joe Orton * ne_props.c (end_propstat): Fix NULL pointer dereference if no status object is given. Tue Oct 8 20:10:24 2002 Joe Orton * ne_xml.c (ne_xml_create) [!HAVE_EXPAT]: Set 'replaceEntities' flag in created parser so that entities are dereferenced in attribute values. Mon Oct 7 22:08:46 2002 Joe Orton * ne_socket.c (init_ssl): Attempt to seed PRNG using EGD socket at path EGD_PATH or a set of predetermined locations if EGD_PATH is not defined. No longer try $EGDSOCKET or $HOME/.entropy. Mon Oct 7 21:32:33 2002 Joe Orton * ne_auth.c (register_hooks): Removed function. (auth_register): Fold in register_hooks. Tue Sep 24 21:24:44 2002 Joe Orton * ne_request.c (ne_request_create): Pass Request-URI to create_request hooks. Tue Sep 24 20:42:45 2002 Joe Orton * ne_socket.c [__hpux]: Define _XOPEN_SOURCE_EXTENDED to 1, to pick up h_errno definition on HP-UX 10.20. Wed Sep 18 21:46:28 2002 Joe Orton * ne_compress.c (struct ne_decompress_s): Add zstrinit field. (gz_reader): Set zstrinit after inflateInit2 succeeds. (ne_decompress_destroy): Only call inflateEnd if zstrinit is set. Wed Sep 18 19:56:00 2002 Joe Orton * ne_auth.c: Remove incomplete domain support. Tue Sep 17 21:05:11 2002 Joe Orton Fix rejection of server certificates which have commonName as the least specific attribute. * ne_session.c (check_identity): Don't ignore commonName if it is the least specific attribute. Tue Sep 10 21:08:18 2002 Joe Orton * ne_request.c (lookup_host): Destroy cached address if resolve fails; fix segfault if a second request in the session is dispatched after the DNS lookup fails on the first. Mon Sep 9 22:26:03 2002 Joe Orton * ne_request.c (RETRY_RET): Treat SSL truncation as a legitimate persistent connection timeout. Fri Aug 30 21:58:45 2002 Joe Orton * ne_request.c (read_response_block): Clear can_persist flag if an EOF was read (fix for read-till-EOF response terminated by an unclean SSL shutdown). Mon Aug 26 18:05:00 2002 Joe Orton * ne_socket.c: Fix HAVE_LIMITS check (Blair Zajac). Sun Aug 25 23:29:06 2002 Joe Orton * ne_request.c (do_connect): Add debug message for connection attempt. Sun Aug 25 22:54:04 2002 Joe Orton * ne_socket.h (ne_addr_print): Make address argument const. Sun Aug 25 11:52:32 2002 Joe Orton * ne_socket.c (ne_addr_print): New function. Sun Aug 25 10:09:10 2002 Joe Orton Fix interop with Tomcat/3.2 SSL server, which performs an unclean shutdown on an HTTP/1.0 response without a C-L header. * ne_request.c (read_response_block): Ignore SSL connection truncation for a read-till-EOF response, where no reseponse content has been read yet. (ne_read_response_block): Always increase 'total' counter. Sun Aug 25 08:47:41 2002 Joe Orton * ne_request.c (aborted): Handle code=0 case specifically, and NE_SOCK_* as default. Sun Aug 25 08:24:48 2002 Joe Orton * ne_socket.h: Add `NE_SOCK_TRUNC' return value. * ne_socket.c (error_ossl): Return NE_SOCK_TRUNC when an EOF is received without a close_notify. Sat Aug 24 17:37:14 2002 Joe Orton * ne_socket.h (ne_inet_addr): New type. (ne_addr_first, ne_addr_next): New public interface. (ne_sock_connect): Change first parameter to ne_inet_addr. * ne_socket.c: Predefine ne_inet_addr for ne_socket.h, replacing ne_raw_addr. (ne_addr_first, ne_addr_first): Renamed from addr_first, addr_next; return type now ne_inet_addr; made public. (ne_sock_connect): Fold in make_socket() macro; just connect to single IP address passed in. * ne_private.h (struct host_info): Renamed 'addr' to 'address', dded 'current' field, removed 'resolved' field. * ne_request.c (lookup_host): Adjust for addr->address rename. (ne_begin_request): Call lookup_host if 'address' is NULL in host_info structure, don't use 'resolved' flag. (do_connect): Replaces init_socket; factor more code out from open_connection. Loop over available addresses until an ne_sock_connect call succeeds. (open_connection): Moved code into do_connect. * ne_session.c (ne_session_destroy): Adjust for addr->address rename. Sat Aug 24 13:45:26 2002 Joe Orton * ne_string.c (count_concat, do_concat): Compact into while() loops. Sat Aug 24 13:36:04 2002 Joe Orton * ne_private.h (VERSION_PRE11): Removed macro. (struct ne_session_s): Add is_http11 field; removed version_major, version_minor fields. * ne_request.c (add_fixed_headers): Use is_http11 flag rather than VERSION_PRE11 macro. (ne_begin_request): Set and use is_http11 flag. * ne_session.c (ne_version_pre_http11): Use is_http11 flag. (ne_session_create): Don't set version_major, version_minor fields. Sat Aug 24 09:00:13 2002 Joe Orton * ne_request.c (struct ne_request_s): Removed abs_path field. (ne_set_request_uri): Removed function. (ne_request_create): Set req->uri to be the actual Request-URI. Don't use an absoluteURI in Request-URI if using SSL via a proxy tunnel, or if passed-in path does not begin with a '/'. (build_request): Use pre-determined Request-URI. (proxy_tunnel): Pass true Request-URI to ne_request_create. (ne_request_destroy): Don't free abs_path. Sat Aug 24 00:37:25 2002 Joe Orton * ne_request.c (aborted): Fix handling of _CLOSED and _TIMEOUT socket errors, and of non-socket errors. Presume ne_sock_error cannot return NULL. Sat Aug 24 00:07:33 2002 Joe Orton * ne_cookies.c (set_cookie_hdl): Ensure that each cookie field is safe to free(). Fri Aug 23 23:46:58 2002 Joe Orton * ne_request.c (aborted): Close the connection after setting the session error, otherwise the socket error is lost. Fri Aug 23 22:50:30 2002 Joe Orton * ne_socket.c (ne_sock_init): Set SIGPIPE disposition before SSL library initalization, so it happens even if SSL library initialization fails. Fri Aug 23 22:03:26 2002 Joe Orton * ne_socket.c [USE_GETADDRINFO] (make_socket): Pass SOCK_STREAM to socket() rather than ai_socktype: on RHL6.2, ai_socktype is returned as zero. Wed Aug 21 18:06:36 2002 Joe Orton * ne_socket.c: Reinstate stdlib.h include. * ne_socket.h: Reinstate sys/socket.h include. Wed Aug 21 12:58:47 2002 Joe Orton * ne_socket.c (ne_addr_resolve): Accept IPv6 addresses enclosed in square brackets. Wed Aug 21 09:37:24 2002 Joe Orton * ne_uri.c (ne_uri_parse): Parse literal IPv6 address using the RFC2732 `[address]' syntax. Mon Aug 19 17:18:45 2002 Joe Orton * ne_socket.c (ne_addr_error): Override a horribly generic error message from gai_strerror(). Mon Aug 19 16:24:37 2002 Joe Orton * ne_socket.h: Remove netinet/in.h etc includes. (ne_sock_addr): Add new opaque type. (ne_addr_resolve, ne_addr_result, ne_addr_error, ne_addr_destroy): New functions. (ne_sock_connect): Changes address argument to `ne_sock_addr *'. (ne_name_lookup): Removed function. * ne_socket.c: Added netinet/in.h etc includes. (ne_sock_addr, ne_raw_addr): Define types. (make_socket): New macro. (ne_addr_resolve): Replace ne_name_lookup; store results (multiple addresses if returned) in returned ne_sock_addr object. Use getaddrinfo() if available. (raw_connect, addr_first, addr_next, ne_addr_result, ne_addr_error, ne_addr_destroy): New functions. (ne_sock_connect): Re-implement to loop through available addresses until a connect() succeeds; use make_socket, raw_connect auxiliaries. * ne_private.h (struct host_info): Store an ne_sock_addr pointer. * ne_request.c (lookup_host): Use new ne_addr_* interface. * ne_session.c (ne_session_destroy): Destroy address objects. Mon Aug 19 00:19:49 2002 Joe Orton * ne_socket.c: Move prng_seeded inside ifdef NEON_SSL region to prevent unused variable warning for non-SSL build. Sun Aug 18 23:21:21 2002 Joe Orton * ne_string.h (ne_strerror): Return buffer. Sun Aug 18 23:17:56 2002 Joe Orton * ne_socket.c (set_error): Use ne_strnzcpy. Sun Aug 18 23:14:07 2002 Joe Orton * ne_string.c (ne_strerror): Use ne_strnzcpy. Sun Aug 18 23:11:45 2002 Joe Orton * ne_string.h (ne_strnzcpy): New macro. Sun Aug 18 22:48:27 2002 Joe Orton * ne_socket.c (ne_sock_init): Check directly for SIGPIPE definition rather than HAVE_SIGPIPE. Sun Aug 18 13:49:49 2002 Joe Orton * ne_session.c (set_hostport): Use %u for printing unsigned int. Sun Aug 18 13:47:43 2002 Joe Orton * ne_utils.h (NE_DBG_SSL): New constant. * ne_session.c [NEON_SSL] (everywhere): Use NE_DBG_SSL channel for debugging messages. Sun Aug 18 08:17:19 2002 Joe Orton * ne_session.c (match_hostname): Fix to use case-insensitive string comparison. Sun Aug 18 08:10:12 2002 Joe Orton * ne_session.c (check_identity): Check the commonName if no alt. names of DNS type were found. Sun Aug 18 07:39:35 2002 Joe Orton * ne_session.c (check_identity): Use the most specific commonName attribute found, not the first. (for RFC2818 compliance) Sun Aug 18 01:54:53 2002 Joe Orton * ne_session.c (match_hostname): Invert return value. (check_identity): New function; split out commonName check from check_certificate, check subjectAltName extension instead if present. (check_certificate): Use check_identity. Sat Aug 17 19:59:21 2002 Joe Orton * ne_session.c (check_certificate): Extend debugging code to dump the whole certificate chain, but #if 0 it by default. Mon Aug 12 12:04:51 2002 Joe Orton * ne_request.c (aborted): Use NE_FMT_SSIZE_T to print ssize_t value. Mon Aug 12 11:08:35 2002 Joe Orton Support PRNG seeding via EGD to make SSL work on platforms which lack /dev/random: * ne_socket.c (init_ssl): New function. (ne_sock_init): Call init_ssl, set prng_seeded global on success. (ne_sock_use_ssl_os): Fail early if prng_seeded is not set, and RAND_status returns false. Tue Aug 6 07:18:30 2002 Joe Orton * ne_socket.c (ne_sock_use_ssl_os): Remove goto-based error handling. Don't call SSL_shutdown after SSL_connect fails. Mon Aug 5 23:18:55 2002 Joe Orton * ne_session.c (ne_ssl_keypw_prompt): Don't set SSL_CTX default password callbacks, since these are never invoked. Implement once, stub for !NEON_SSL is no longer needed. Mon Aug 5 21:01:54 2002 Joe Orton * ne_session.c (ne_ssl_load_pem): Pass private key prompt callback to PEM_read_X509, PEM_read_PrivateKey (patch by Daniel Berlin). Also handle errors properly; call ERR_get_error() to pop the errors of the error stack. Mon Aug 5 20:15:10 2002 Joe Orton * ne_session.c (provide_client_cert): Increase reference count on key and certificate, to prevent them being free'd too early. Sun Aug 4 22:35:27 2002 Joe Orton Fix `retry_after_abort' test in request.c: * ne_request.c (send_request): Don't use the 'persisted' flag until after a new connection has been opened, when it may have been reset. Sun Aug 4 17:26:37 2002 Joe Orton * ne_request.c (struct ne_request_s): Remove reqbuf field. (ne_request_create, ne_request_destroy): Don't (de)allocate reqbuf. (build_request): Allocate the returned buffer internally. (ne_begin_request): Destroy the buffer after use. Sun Aug 4 15:36:01 2002 Joe Orton * ne_session.c (ne_ssl_load_pem): Close file after use. Sun Aug 4 12:55:49 2002 Joe Orton Factor out EPIPE, ECONNRESET handling from write_raw: * ne_socket.c (MAP_ERR): New macro. (write_raw, error_ossl): Use MAP_ERR. Sun Aug 4 12:25:34 2002 Joe Orton * ne_socket.c (ne_sock_switch_ssl): New function. Sun Aug 4 12:24:23 2002 Joe Orton * ne_socket.c (ne_sock_switch_ssl): New function, really just for test suite. Sat Aug 3 22:11:33 2002 Joe Orton * ne_auth.c (ne_forget_auth): Fix segfault if either server or proxy auth is not in use. Sat Aug 3 22:06:32 2002 Joe Orton * ne_redirect.c (create, post_send, ne_redirect_register, ne_redirect_location): Updated for new hook interface. Sat Aug 3 19:02:33 2002 Joe Orton Adjustment of hook interface and use: fixing a design flaw causing a segfault in the auth hooks when two requests are used concurrently for a single session during a CONNECT tunnel. * ne_request.h, ne_session.h: (ne_get_request_private, ne_get_session_private): Replace ne_request_hook_private, ne_session_hook_private. (ne_set_session_private, ne_set_request_private): Replace ne_hook_session_accessor, ne_hook_request_accessor. * ne_request.h (ne_create_request_fn, ne_pre_send_fn, ne_post_send_fn): Add ne_request pointer as first argument. (ne_hook_destroy_request): Take ne_destroy_req_fn function. (ne_hook_destroy_session): Take ne_destroy_sess_fn function. * ne_request.c (struct ne_request_s): Renamed `accessor_hooks' field to `private'. (get_private): Renamed from call_access; don't invoke function. (ne_null_accessor): Removed function. * ne_auth.c (struct auth_class): Store hook id. (auth_session): Remove auth_request pointer. (ah_create): Store auth_request pointer as request-private data. (ah_pre_send, ah_post_send, ah_destroy): Retrieve auth_request pointer from request-private data. (register_hooks, ne_forget_auth): Use ne_{get,set}_session_private. * ne_locks.c (struct lh_req_cookie): New structure. (struct ne_lock_store_s): Remove submit_locks field. (lk_create, lk_pre_send, submit_lock, ne_lock_using_resource, ne_lock_using_parent, lk_destroy): Adjust to use lh_req_cookie pointer as request-private data. * ne_cookies.c (create, pre_send): Adjust for hook prototype changes. Wed Jul 31 23:46:17 2002 Joe Orton * ne_socket.c [NEON_SSL]: Include limits.h for INT_MAX definition. Mon Jul 29 20:55:57 2002 Joe Orton * ne_auth.c (struct auth_class): New structure; abstracts out proxy/server generic auth handling more cleanly. (ah_server_class, ah_proxy_class): Declare variables. (auth_session): Reference an auth_class structure. (auth_register): Replaces auth_create. (ne_set_server_auth, ne_set_proxy_auth): Simplify, use auth_register. (everywhere): Reference req_hdr etc via ->spec-> reference. Sun Jul 28 12:29:23 2002 Joe Orton * ne_request.c (proxy_tunnel): Reset 'persisted' flag, so that a newly tunnelled connection is not treated as persistent. Sun Jul 28 12:26:49 2002 Joe Orton * ne_string.h (CONCAT2, CONCAT3, CONCAT4): Removed macros. Thu Jul 25 23:16:00 2002 Joe Orton * ne_request.c (send_request): Don't clear retry until a status-line has been read. Thu Jul 25 00:03:17 2002 Joe Orton * ne_auth.c (basic_challenge, request_basic): Use ne_concat not the CONCAT? macros. * ne_basic.c (ne_mkcol): Use ne_concat not the CONCAT2 macro. Wed Jul 24 00:16:39 2002 Joe Orton * ne_string.c (count_concat, do_concat): Factored out from ne_buffer_concat. (ne_buffer_concat): Rewrite to use count_concat, do_concat. (ne_concat): New (resurrected) function. Thu Jul 18 21:52:12 2002 Joe Orton * ne_request.c (proxy_tunnel): Don't use server.hostport in Request-URI; always include `:port' even if default port is used; fix CONNECT through Inktomi Traffic-Server. Thu Jul 18 21:33:43 2002 Joe Orton * ne_request.c (aborted, ne_set_request_body_fd): Use ne_strerror. * ne_session.c (ne_ssl_load_pem, ne_ssl_load_pkcs12): Use ne_strerror. * ne_basic.c (get_to_fd): Use ne_strerror. Thu Jul 18 20:19:30 2002 Joe Orton * ne_string.c (ne_strerror): New function. * ne_socket.c (set_strerror): Move portability logic to ne_strerror; just use that here. Thu Jul 18 20:00:46 2002 Joe Orton * ne_socket.c (read_raw, write_raw): Don't re-evaluate 'errno', per Ulrich Drepper's advice. Wed Jul 17 23:47:01 2002 Joe Orton * ne_socket.c (struct ne_socket_s): Store buffer for error string. (set_error, set_strerror): New macros. (everywhere): Use set_error, set_strerror or ne_snprintf to set the socket error string. Wed Jul 17 23:19:18 2002 Joe Orton * ne_utils.c (ne_version_match): Fix inverted minor version test. Sun Jul 14 20:13:59 2002 Joe Orton * ne_uri.h (ne_uri): Store port as unsigned. * ne_uri.c (ne_uri_defaultport): Return unsigned int, and zero for undefined port. Sun Jul 14 20:07:35 2002 Joe Orton * ne_session.c (ne_session_proxy): Take port parameter as unsigned int, as per ne_session_create. Sun Jul 14 20:03:21 2002 Joe Orton * ne_request.c (strip_eol): Take ssize_t 'len' parameter. (read_message_header): Use ssize_t for 'n'. Sun Jul 14 12:45:40 2002 Joe Orton * ne_socket.c (ne_sock_use_ssl_os): Unconditionally enable SSL_MODE_AUTO_RETRY now OpenSSL 0.9.6 is required. Sun Jul 14 12:15:40 2002 Joe Orton * ne_xml.h (NE_XML_MEDIA_TYPE): New definition. * ne_acl.c (ne_acl_set), * ne_props.c (ne_proppatch, propfind): Use NE_XML_MEDIA_TYPE, rather than hard-coding the incorrect "text/xml" media type. Sun Jul 14 10:53:33 2002 Joe Orton * ne_utils.c (ne_version_match): Replace ne_version_minimum. Sat Jul 13 11:40:37 2002 Joe Orton * ne_session.c (ne_negotiate_ssl): Include socket error string in session error if SSL negotiation fails. Sat Jul 13 11:27:50 2002 Joe Orton * ne_socket.c (error_ossl): New function. (ERROR_SSL_STRING): Removed macro. (CAST2INT): New macro; safety harness for OpenSSL compatibility. (read_ossl, write_ossl): Use error_ossl, CAST2INT. (ne_sock_use_ssl_os): Use error_ssl. Sat Jul 13 11:16:07 2002 Joe Orton * ne_socket.c: Define ECONNRESET as WSAECONNRESET on Win32. Sat Jul 13 10:10:03 2002 Joe Orton * ne_private.h (struct ne_session_s): Replace 'reqcount' with 'persisted' flag. * ne_request.c (ne_end_request): Set 'persisted' flag if connection is left open. (send_request): Adjust to allow retry if 'persisted' flag is set. (init_socket): Clear 'persisted' flag here... (open_connection): ... rather than here. Wed Jul 10 22:51:39 2002 Joe Orton * ne_request.c (RETRY_RET): Retry on an NE_SOCK_RESET too. (send_request): Fix to only retry if not on the first request on a connection (close_not_retried test). Sun Jul 7 20:49:09 2002 Joe Orton * ne_socket.h: Add NE_SOCK_RESET return value; improve comments. * ne_socket.c (read_raw, write_raw): Return NE_SOCK_RESET if an ECONNRESET error is received when reading or writing. Sat Jul 6 13:30:15 2002 Joe Orton * ne_request.c (read_status_line, discard_headers): New functions, split out from send_request. (send_request_body): Move debugging here from send_request. (RETRY_RET): Renamed from CAN_RETRY. (send_request): Simplify: remove complex 100-continue graceful failure logic; use read_status_line, discard_headers, RETRY_RET. Fix to only send request body once (expect_100_once test case). Fix to not return NE_RETRY if reading status-line other than the first fails (fail_eof_continued test case). Fri Jul 5 21:47:49 2002 Joe Orton * ne_request.c (build_request): Fix from previous commit: clear the buffer before building the request. Fri Jul 5 21:00:20 2002 Joe Orton * ne_request.c (build_request): Fold Host header and Request-Line into single ne_buffer_concat call. Don't set req->use_expect100 here. Fold an if/else into an ?:. Optimise to use ne_buffer_append to add 100-continue, user-supplied headers, and trailing EOL, since they all have known lengths. (send_request): Take request data as argument. (ne_begin_request): Call build_request here; pass to send_request. Move Expect100 logic here. Fri Jul 5 17:12:56 2002 Joe Orton * ne_basic.c (ne_read_file): Removed function. Fri Jul 5 17:10:11 2002 Joe Orton * ne_compress.c (process_footer): Take unsigned char buffer. Store calculated CRC in a uLong. (do_inflate, gz_reader): Cast buffers to unsigned char for strict compatibility with zlib interface. Wed Jul 3 19:21:17 2002 Joe Orton * ne_request.c (struct ne_request_s): Use a fixed char array for respbuf field. (ne_request_create, ne_request_destroy): Don't allocate respbuf dynamically. (send_request): Move 'buffer' to appropriate scope. (ne_request_dispatch): Remove 'buffer'; read into respbuf. Tue Jul 2 08:35:05 2002 Joe Orton * ne_request.c (proxy_tunnel): Remove redundant sess->connected assignment. Sun Jun 30 21:04:50 2002 Joe Orton * ne_request.c (ne_begin_request): Only set host->resolved if lookup is successful. Sun Jun 30 18:25:51 2002 Joe Orton * ne_request.c (SOCK_ERR): New macro. (struct ne_request_s): Remove 'forced_close' field. (aborted): Renamed from set_sockerr; also closes connection and prints message in debug log. (send_request_body): Don't use set_sockerr or set forced_close. (read_response_block, read_message_header): Use SOCK_ERR; adjust to use aborted(). (ne_read_response_block, read_response_headers): Don't set forced_close. (CAN_RETRY): New macro. (send_request): Adjust to use CAN_RETRY(); use aborted() to make sure connection is closed in error cases. (ne_begin_request): Don't close connection here in error cases; don't use forced_close. (open_connection): Adjust to use aborted() not set_sockerr(). Sun Jun 30 17:26:41 2002 Joe Orton * ne_session.c (ne_close_connection): Clarify debug messages. Sun Jun 30 14:36:11 2002 Joe Orton * ne_request.c (read_response_block): Fail on chunk size lines which contain no valid chunk size digits. Sun Jun 30 12:35:35 2002 Joe Orton * ne_session.c (ne_negotiate_ssl): Use ne_get_session rather than req->session. * ne_request.c (struct header_handler, struct body_reader, struct ne_request_s): Moved from ne_private.h. Sun Jun 30 12:13:58 2002 Joe Orton Cleanup of response handling: * ne_private.h (struct ne_response): Replace 'is_chunked' field with 'mode' enum. * ne_request.c (te_hdr_handler): Set mode. (connection_hdr_handler): Reset can_persist for 'close'. (clength_hdr_handler): New function. (ne_request_create): Use clength_hdr_handler to parse Content-Length header. (read_response_block, ne_read_response_block): Adapt for 'mode' enum; simplify. (normalize_response_length): Removed function. (ne_begin_request): Fold in normalize_response_length logic. (ne_end_request): Simplify logic. Sun Jun 30 11:08:26 2002 Joe Orton * ne_session.c: Remove X509_NAME workaround in favour of a neon.mak change. Tue Jun 25 23:14:34 2002 Joe Orton * ne_session.c: Undefine X509_NAME if it is defined (by a Windows header). Tue Jun 25 22:51:15 2002 Joe Orton * ne_socket.c: Rename READ_BUFFER to RDBUFSIZ. Tue Jun 25 21:07:13 2002 Joe Orton * ne_private.h (struct host_info): Store port as unsigned int. * ne_session.c (set_hostport, set_hostinfo, ne_session_create): Take port argument as unsigned int. * ne_socket.c (ne_sock_connect): Take port argument as unsigned int. Tue Jun 25 20:59:14 2002 Joe Orton * ne_utils.h [__GNUCC__] (NE_DEBUG): Remove implementation using GNU C extensions. Sun Jun 23 22:47:52 2002 Joe Orton * ne_request.c (set_request_uri): Renamed from ne_set_request_uri; made static. (ne_request_create): Update accordingly. * ne_private.h (ne_set_request_uri): Removed prototype. Sun Jun 23 15:40:57 2002 Joe Orton * ne_request.c (send_request, ne_request_destroy): Free reason_phrase now it is malloc-allocated. Sun Jun 23 14:59:04 2002 Joe Orton Simplify given loss of const qualifier on ne_status.reason_phrase: * ne_props.c (struct propstat): Remove r_phrase field. (end_propstat, free_propset): Use status.reason_phrase not r_phrase field. Sun Jun 23 14:42:22 2002 Joe Orton * ne_207.h (ne_207_end_response, ne_207_end_propstat): Remove status_line parameter from callbacks. * ne_207.c (struct ne_207_parser_s): Remove status_line field. (end_element): Don't store status_line. (handle_error): Drop status_line argument, recreate dummy status line from status object. (end_response, end_propstat): Drop status_line arguments. * ne_props.c (end_propstat, end_response): Drop status_line arguments. Sun Jun 23 14:39:00 2002 Joe Orton * ne_utils.h (ne_status): Remove const qualifier from 'reason_phrase' field. * ne_utils.c (ne_parse_statusline): strdup the reason_phrase on successful return. Sun Jun 23 11:39:24 2002 Joe Orton * ne_compress.c (struct ne_decompress_s): Replace footer union with buffer. (BUF2UINT): New macro. (process_footer): Convert footer to integer in a portable manner, using BUF2UINT. Sun Jun 23 09:05:25 2002 Joe Orton * ne_compress.c (ne_decompress_s): Use unsigned int for 32-bit integers, not uLong (fix for 64-bit platforms). Wed Jun 19 18:46:40 2002 Joe Orton * ne_session.c (ne_session_destroy): Don't leak the proxy hostname. Sun Jun 16 14:09:31 2002 Joe Orton * ne_request.c (read_response_block): Use NE_FMT_SSIZE_T rather than %d, cast field precision argument to int. (ne_pull_request_body): Use ssize_t for store callback return value, use NE_FMT_SSIZE_T rather than %d, cast field precision argument to int. Sun Jun 16 12:15:19 2002 Joe Orton * ne_session.c (ne_negotiate_ssl): Don't leak peer certificate in error cases. Fix spelling mistake in error message. Sun Jun 16 11:23:23 2002 Joe Orton * ne_request.c (open_connection): When SSL negotation fails after doing CONNECT request, use ne_close_connection so that sess->connection is reset to 0, and ne_sock_close isn't called twice for the socket. Wed Jun 12 23:22:20 2002 Joe Orton * ne_props.c (ne_proppatch): Add missing call to ne_lock_using_resource. Mon Jun 10 20:45:27 2002 Joe Orton * ne_auth.c (verify_response): Remove redundant prototype, fix sscanf format string to use signed integer. Mon Jun 10 20:13:57 2002 Joe Orton * ne_compress.c (do_inflate): Continue calling inflate() whilst unconsumed input remains: fix from Justin Erenkrantz . Mon Jun 10 19:53:59 2002 Joe Orton * ne_socket.c (ne_sock_readline): If a complete line is found in the buffer, avoid the memmove() and simply copy the line directly out of the buffer. Sun Jun 9 11:39:20 2002 Joe Orton * ne_redirect.c (post_send): Perform simple relative URI resolution. Tue Jun 4 16:51:54 2002 Joe Orton * ne_uri.c (ne_path_parent): Simplify. Mon Jun 3 17:50:27 2002 Joe Orton * ne_cookies.c (set_cookie_hdl): Avoid free'ing cookie name/value, thanks to Dan Mullen. Mon Jun 3 17:45:33 2002 Joe Orton * ne_string.c (ne_base64): Use size_t for outlen. Mon Jun 3 17:42:34 2002 Joe Orton * ne_utils.h, ne_socket.h [WIN32]: Move ssize_t definition to ne_socket.h. Mon Jun 3 17:27:21 2002 Joe Orton * ne_request.c (read_response_block): Use correct types for passing to/from ne_sock_*. Mon Jun 3 11:32:20 2002 Joe Orton * ne_compress.c (ne_decompress_destroy): Don't fail if response reader callback is never invoked. Sun Jun 2 12:51:35 2002 Joe Orton * ne_socket.c (read_ossl, read_raw): Call readable_{ossl,raw} function here. (ne_sock_read, ne_sock_peek, ne_sock_readline): Remove explicit calls to ops->readable before ops->read. Thu May 30 22:00:07 2002 Joe Orton * ne_socket.c (ne_sock_readline): Optimise to use socket read buffer directly, and use ->read (and ->readable) functions. Tue May 28 17:00:34 2002 Joe Orton * ne_session.c (ne_session_destroy): Don't free proxy.hostport, since it's no longer set. Sun May 26 19:11:46 2002 Joe Orton * ne_xml.c: #error if no expat header is configured; flatten nested #if's, include libxml/xmlversion.h if present. Sun May 26 19:09:04 2002 Joe Orton * ne_utils.c: Include libxml/xmlversion.h if present. Sun May 26 11:55:30 2002 Joe Orton * ne_session.c (set_hostport): Renamed from get_hostport: set host_info field directly; take defaultport argument. (set_hostinfo): Don't use get_hostport. (ne_session_create): Use set_hostinfo and set_hostport; pass in default port correctly for http:/https:. Thu May 23 19:44:44 2002 Joe Orton * ne_xml.c (resolve_nspace): Split out from parse_element. (ne_xml_get_attr): Take parser object, and optional namespace; resolve the namespace if necessary. (parse_element): Use resolve_nspace. * ne_props.c (startelm): Use new ne_xml_get_attr interface. Wed May 22 22:29:05 2002 Joe Orton * ne_dates.c: Renamed HAVE_TM_GMTOFF to HAVE_STRUCT_TM_TM_GMTOFF from use of AC_CHECK_MEMBERS. Tue May 21 21:21:31 2002 Joe Orton * ne_redirect.c (ne_redirect_register): Drop confirm, notify, userdata arguments. (struct redirect): Drop most fields; add a uri structure. (auto_redirect): Removed function. (post_send): Remove functionality which retries a request with a different URI to automatically follow redirects. Qualify the URI if non-absolute. (create): Remove now redundant code. (ne_redirect_location): Return an ne_uri object. Sun May 19 18:53:22 2002 Joe Orton * ne_session.c (ne_set_useragent): Use strcat/malloc/strcpy directly, rather than CONCAT2; allow compiler optimisations. (AGENT): Renamed from NEON_USERAGENT, append space. Sun May 19 17:31:43 2002 Joe Orton Move everything exported by ne_socket.h into ne_*/NE_* namespace; purge inappropriate and unused interfaces. Renaming done by Olof Oberg. * ne_socket.h: (SOCK_FULL): Removed constant. (sock_call_progress, sock_transfer, sock_sendline, sock_send_string, sock_readfile_blocked): Removed functions. (NE_SOCK_ERROR, NE_SOCK_TIMEOUT, NE_SOCK_CLOSED): Renamed constants. (ne_progress, ne_block_reader): Renamed types. (ne_register_progress, ne_sock_init, ne_sock_exit, ne_sock_read, ne_sock_peek, ne_sock_block, ne_sock_fullwrite, ne_sock_readline, ne_sock_connect, ne_sock_accept, ne_sock_fd, ne_sock_error, ne_sock_read_timeout, ne_name_lookup, ne_service_lookup, ne_sock_use_ssl, ne_sock_use_ssl_os): Renamed functions. * ne_private.h, ne_request.c, ne_session.c: Update accordingly. * ne_request.c (build_request): Return the ne_buffer pointer. (send_request): Remove redundant strlen(), use known buffer length. * ne_request.h: Drop ne_block_reader definition. Sun May 19 13:32:12 2002 Joe Orton * ne_request.c (ne_get_session, ne_get_request): Take const request pointer. Sun May 19 13:21:17 2002 Joe Orton * ne_string.c (ne_buffer_ncreate): Renamed from ne_buffer_create_sized. * ne_session.c (check_certificate, provide_client_cert): Update accordingly. * ne_request.c (ne_request_create): Update accordingly. Sun May 19 13:12:14 2002 Joe Orton * ne_string.c (ne_token): Drop quotes parameter. (ne_qtoken): Split out from ne_token. * ne_basic.c (dav_hdr_handler, ne_content_type_handler): Use ne_qtoken. * ne_compress.c (find_token): Removed function. (gz_reader): Compare header value directly against "gzip", remove a stale comment. Sun May 19 09:45:28 2002 Joe Orton * ne_socket.h (sock_fullread): Return ssize_t; takes buflen as size_t. (sock_read, sock_peek): Fix prototypes to match actual definition. * ne_socket.c (write_raw): Return ssize_t. Sat May 18 14:53:45 2002 Joe Orton * ne_string.h (ne_buffer): Remove separate struct ne_buffer_s definition. * ne_string.c (ne_buffer_create_sized): Don't use struct ne_buffer_s. Sun May 12 11:33:02 2002 Joe Orton * ne_string.c (ne_base64): Moved from base64.c. * base64.c, base64.h: Removed files. * Makefile.in: Updated accordingly. * ne_auth.c: Don't include base64.h. Sun May 12 11:26:05 2002 Joe Orton * ne_string.h (ne_utf8_decode, ne_utf8_encode): Removed functions. Sat May 11 15:42:24 2002 Joe Orton As part of patch from Olof Oberg : * ne_request.h (ne_destroy_fn): Renamed from typo'ed ne_destory_fn. * ne_request.c (ne_request_destroy, ne_hook_destroy_request, ne_hook_destroy_session): Update accordingly. * ne_session.c (ne_session_destroy): Update accordingly. Thu May 9 21:44:15 2002 Joe Orton Major improvements to socket layer to incorporate socket read buffering and rewrite sock_readline, and add an abstraction layer to simplify SSL support. Grunt work by Jeff Johnson * ne_socket.c (struct iofns): New type. (struct nsocket_s): Store 'ops' pointer to I/O functions in use for the socket. Add buffer, bufpos, bufavail fields for read buffering. (sock_block, sock_read, sock_peek): Reimplement to add read buffer, simplify to use I/O functions abstraction. (readable_raw, read_raw, write_raw, readable_ossl, read_ossl, write_ossl): Factored out from sock_read/fullwrite, avoiding in-lined ifdefs. (sock_fullwrite): Just use ops->write. (sock_readline): Simplify greatly to exploit read-buffering, return ssize_t. (sock_fullread): Simplify, removing unnecessary local variables, return ssize_t. (create_sock, sock_enable_ssl_os): Set ops pointer. Wed May 8 11:54:48 2002 Joe Orton * ne_socket.c (sock_name_lookup): Avoid casts; use INADDR_NONE. [!INADDR_NONE]: Define to (unsigned long) -1. Wed May 1 22:19:18 2002 Joe Orton * ne_locks.h (ne_lock): Document that ->token and ->owner fields must be malloc-allocated if non-NULL. Wed May 1 22:15:41 2002 Joe Orton * ne_locks.c (get_ltoken_hdr): New function. (ne_lock): Correctly parse Coded-URL from Lock-Token response header. Wed May 1 22:03:08 2002 Joe Orton * ne_redirect.c (post_send): Adjust for ne_uri_parse handling of unspecified port. Wed May 1 22:00:50 2002 Joe Orton * ne_session.c (provide_client_cert): Fail if peer certificate not known when client cert requested. Wed May 1 21:58:35 2002 Joe Orton * ne_session.h (ne_ssl_provide_fn): Adjust callback typedef to return void. Wed May 1 21:52:40 2002 Joe Orton * ne_request.h: Remove NE_SERVERAUTH and NE_AUTHPROXY; fix NE_PROXYAUTH description. Wed May 1 21:32:54 2002 Joe Orton * ne_uri.c (ne_uri_parse): For consistency, port field is 0 if unspecified. Tue Apr 30 10:05:48 2002 Joe Orton * ne_string.c (shave_string): Removed function. Tue Apr 23 21:19:53 2002 Joe Orton * ne_props.c (start_propstat, startelm): Use ne_realloc not realloc (thanks to Jeff Johnson). Tue Apr 23 20:55:56 2002 Joe Orton * ne_xml.c: Include parser.h or libxml/parser.h, depending on which is found. Mon Apr 15 00:37:43 2002 Joe Orton * ne_request.c (build_request, send_request): Simplify logic. Sun Apr 14 16:59:50 2002 Joe Orton * ne_props.c: Remove unused accidental 'propstat' global. (struct propstat): Add r_phrase field. (end_propstat): Dup the reason_phrase string. (free_propset): Free the reason_phrase. Avoid another possible free(NULL) call. Sun Apr 14 12:00:54 2002 Joe Orton * ne_basic.c (ne_content_type_handler): For text/* media types, use default charset of ISO-8859-1. Sat Apr 13 23:11:07 2002 Joe Orton * ne_utils.h: Include trio.h if NEON_TRIO is defined. Sun Apr 7 17:38:14 2002 Joe Orton * ne_request.c (read_response_headers): Don't zero-initialize hdr. Sun Apr 7 17:15:23 2002 Joe Orton * ne_request.c (read_response_headers): Ignore whitespace between header name and colon, simplify logic a little. Sun Apr 7 14:09:07 2002 Joe Orton * ne_session.c (ne_ssl_readable_dname): New function. Sun Apr 7 12:32:25 2002 Joe Orton * ne_string.c (ne_buffer_destroy): Remove redundant check for data pointer being NULL. Wed Apr 3 19:44:59 2002 Joe Orton Optimisation/simplification of header name hashing. * ne_request.c (hash_and_lower): Renamed from hdr_hash; convert string to lower-case in-place too. (lower_string): Removed function. (ne_add_response_header_handler): Use hash_and_lower rather than lower_string. (HH_ITERATE): Change parameter name to 'ch'. Fri Mar 29 23:00:57 2002 Joe Orton * ne_uri.c (ne_uri_parse): Minor optimisation. Mon Mar 25 21:45:36 2002 Joe Orton Pass a lock context around during LOCK processing; search for the correct element in the response body. * ne_locks.c (ne_lock_create): Don't take a path argument. (ne_unlock): Constify lock parameter. (discover_results): Don't parse out href here... (ld_create): do it here instead; renamed from create_private. (lk_startelm): New function. (lk_endelm): Renamed from end_element_lock. (ne_lock): Require a Lock-Token response header; pass lock context to callbacks. Copy lock back out. Mon Mar 25 21:35:42 2002 Joe Orton * ne_session.h (NE_SSL_FAILMASK): New constant. (NE_SSL_*): Shift right one bit. Mon Mar 25 21:21:18 2002 Joe Orton * ne_session.c (ne_close_connection): Return void. Mon Mar 25 20:09:33 2002 Joe Orton * ne_props.c (free_propset): Avoid free(NULL). Mon Mar 11 19:59:04 2002 Joe Orton * ne_locks.c (ne_lock_using_parent): Iterate over the lock list by hand: check for infinite depth locks with cover the parent too (fixing if_covered_child test). Mon Mar 11 19:25:44 2002 Joe Orton * ne_request.c (ne_request_dispatch): Move variable to scope in which is is used. Sun Mar 10 22:04:58 2002 Joe Orton * Makefile.in (NEON_BASEOBJS): Always build ne_compress.o. Sun Mar 10 22:01:54 2002 Joe Orton * ne_compress.c [!NEON_ZLIB] (ne_decompress_reader, ne_decompress_destroy): Add stubs. Sun Mar 10 21:42:11 2002 Joe Orton * ne_locks.c (struct discover_ctx): Store an ne_session pointer. (discover_results): If lock URI is not an absoluteURI, qualify it using the server host/port/scheme from the session. Don't leak the lock object. (create_private): Simplify, use ne_lock_create. Thu Mar 7 20:08:07 2002 Joe Orton * ne_uri.c (ne_uri_defaultport): Fix default port number for https scheme. Wed Mar 6 21:22:23 2002 Joe Orton * ne_locks.c (lk_pre_send): Use an absoluteURI in the If: header. Wed Mar 6 21:15:00 2002 Joe Orton * ne_uri.c (ne_uri_unparse): New function. Tue Mar 5 22:57:00 2002 Joe Orton * ne_uri.c (ne_uri_cmp): Compare hostnames and schemes case-insensitively, and compare empty abspath and "/" as equivalent, as per RFC 2616. Tue Mar 5 20:53:54 2002 Joe Orton * ne_uri.c (ne_uri_defaultport): New function. Mon Mar 4 21:10:29 2002 Joe Orton * ne_uri.h (ne_uri): Renamed from struct uri. * ne_uri.c (ne_path_parent): Renamed from uri_parent. (ne_path_has_trailing_slash): Renamed from uri_has_trailing_slash. (uri_abspath, uri_absolute): Removed. (ne_uri_parse): Renamed from uri_parse, don't take a 'defaults' parameter. (ne_uri_free): Renamed from uri_free. (ne_path_unescape): Renamed from uri_unescape. (ne_path_escape): Renamed from uri_abspath_escape. (ne_uri_cmp): Renamed from uri_cmp. (ne_path_compare): Renamed from uri_compare. (ne_path_childof): Renamed from uri_childof. * ne_basic.c, ne_locks.c, ne_uri.c, ne_redirect.c, ne_session.c, ne_session.h: all callers changed. Mon Mar 4 01:03:23 2002 Joe Orton * ne_request.c (strip_eol): Fix potential segfault. Mon Mar 4 00:38:10 2002 Joe Orton * ne_locks.c (insert_lock): New function. (ne_lockstore_add, submit_lock): use insert_lock. Mon Mar 4 00:33:39 2002 Joe Orton * ne_locks.c (ne_lockstore_remove): Free list item. Mon Mar 4 00:31:08 2002 Joe Orton * ne_locks.c (free_list): Really destroy the lock. (ne_lock_free): Don't free the lock object itself. Mon Mar 4 00:17:18 2002 Joe Orton * ne_request.c (ne_request_destroy): Free accessor hook list. Sun Mar 3 20:35:09 2002 Joe Orton Changes to lock interface; replacing "lock session" with a lock store, which can be registered with an ne_session. Lock objects now store URI as complete URI structure. * ne_locks.h (struct ne_lock): Store URI as complete URI structure. Remove next/prev fields. (ne_lock_store): New type. * ne_locks.c (struct lock_list): New type. (struct ne_lock_store_s): Replaces ne_lock_session_s; store lock_list pointers for stored locks, cursor, and locks to submit. (ne_lock_create): New function. (lk_create): Renamed from create. (lk_pre_send): Renamed from pre_send; adjust for lock list type and to use URI path. (free_list): New function; split out from old 'destroy'. (lk_destroy): Renamed from destroy; use free_list. (ne_lockstore_create, ne_lockstore_destroy, ne_lockstore_first, ne_lockstore_next): New functions. (ne_lockstore_register): Most of old ne_lock_register. (submit_lock): Adjusted for lock_list type. (ne_lockstore_findbyuri): Renamed from ne_lock_find; use full URI structure. (ne_lock_using_resource, ne_lock_using_parent): Adjusted for lock_list/full URI changes. (ne_lock_iterate): Removed function. (ne_lockstore_add, ne_lockstore_remove): Renamed from ne_lock_add, ne_lock_copy; adjusted for lock_list/full URI. (ne_lock_copy): Adjusted for full URI. (ne_lock_create, ne_lock_destroy): New function. (ne_lock, ne_lock_refresh, ne_unlock): Adjusted for full URI. Sun Mar 3 15:23:40 2002 Joe Orton * ne_uri.c (uri_cmp): New function. Sun Mar 3 11:01:30 2002 Joe Orton * ne_session.c (ne_fill_server_uri): New function. Mon Feb 25 21:25:27 2002 Joe Orton * ne_utils.c (version_string): Add zlib version. Mon Feb 25 20:49:07 2002 Joe Orton * (everywhere): Replace use of snprintf, vsnprintf with ne_snprintf, ne_vsnprintf so that trio replacements are used when appropriate. * ne_dates.h: Pick up ne_utils.h for ne_{v,}snprintf defines. Sun Feb 24 11:23:05 2002 Joe Orton * ne_utils.h: Define ne_snprintf, ne_vsnprintf for trio or non-trio builds. Sun Feb 24 11:20:42 2002 Joe Orton * Makefile.in (check-incl): Add target to check that each header file can be included standalone. Sun Feb 24 11:17:54 2002 Joe Orton * ne_xml.h: Add missing sys/types.h include. Sun Feb 24 11:12:22 2002 Joe Orton * ne_utils.h: Remove HTTP_QUOTES, HTTP_WHITESPACE globals. * ne_cookies.c (set_cookie_hdl): Don't use HTTP_QUOTES, HTTP_WHITESPACE globals. Wed Feb 20 19:32:48 2002 Joe Orton * ne_request.c (set_sockerr, ne_set_request_body_fd, send_request): Use ne_set_error rather than accessing session error directly. Tue Feb 19 21:34:59 2002 Joe Orton * ne_utils.c (version_string) [NEON_SOCKS]: Mention SOCKSv5 support. * ne_socket.c (sock_init) [NEON_SOCKS]: Call SOCKSinit. Tue Feb 19 19:21:07 2002 Joe Orton * ne_request.c (open_connection): Remove notify_status call duplicated with ne_negotiate_ssl. Tue Feb 19 19:16:44 2002 Joe Orton * ne_socket.c (sock_get_version): Removed function. Tue Feb 19 19:12:52 2002 Joe Orton * ne_session.c (ne_ssl_provide_ccert): Moved outside ifdef NEON_SSL. [!NEON_SSL] (ne_ssl_load_pem, ne_ssl_load_pkcs12, ne_ssl_keypw_prompt): Added stubs. Sun Feb 17 21:15:34 2002 Joe Orton * ne_session.c (ne_session_create, ne_session_destroy): Only use the SSL context is SSL is being used for the session. Sun Feb 17 20:19:05 2002 Joe Orton Add back client certificate support, much improved. * ne_private.h (struct ne_session_s): Add client cert/key fields, provider, privkey password callbacks. * ne_socket.c (sock_init): Call PKCS12_PBE_add. (sock_enable_ssl_os): Add optional 'appdata' argument. (sock_enable_ssl): Adjust accordingly. * ne_session.c (provide_client_cert, privkey_prompt, ne_ssl_keypw_prompt, ne_ssl_load_pkcs12, ne_ssl_load_pem, ne_ssl_provide_ccert): New functions. (ne_negotiate_ssl): Pass session as appdata to sock_enable_ssl_os. Sun Feb 17 12:32:34 2002 Joe Orton * ne_session.c (make_dname): New function. (check_certificate): Use make_dname. Sun Feb 17 11:29:10 2002 Joe Orton * ne_basic.c (struct get_context): Remove unused 'progress' field, add 'session' field. (get_to_fd, content_range_hdr_handler, clength_hdr_handler): Set session error directly. (clength_hdr_handler): Also fix check for expected range. (everywhere): Initialize session field, don't set session error; use NE_FMT_OFF_T to print off_t's rather than casting to long int. Sat Feb 16 23:24:10 2002 Joe Orton * ne_xml.h (NE_XML_STRIPWS): New element flag. * ne_xml.c (start_element): Clear cdata buffer if not in mixed mode. (char_data): Only strip leading whitespace if NE_XML_STRIPWS is set for the element. Sat Feb 16 14:52:59 2002 Joe Orton * ne_compress.c (enum state): New state NE_Z_AFTER_DATA. (struct ne_decompress_s): Add fields for storing and parsing stream footer; add checksum field for storing current crc. (process_footer): New function. (do_inflate): Compute checksum. Switch to AFTER_DATA state and process footer after reading DEFLATE data. (gz_reader): Fail on trailing content. Handle AFTER_DATA state. (ne_decompress_destroy): Return error if final state was not PASSTHROUGH, or FINISHED. (ne_decompress_reader): Initialize crc. Sat Feb 16 14:26:54 2002 Joe Orton * ne_compress.c (ne_decompress_destroy): Fix potential segfault with use-after-free. Thu Feb 14 16:50:40 2002 Joe Orton * ne_request.c (read_response_headers): Ignore header lines without a ':', rather than failing the request. Tue Feb 12 20:17:49 2002 Joe Orton * ne_request.c (read_response_block): Read chunk size as unsigned using strtoul; check that it fits within an unsigned int (and hence, probably a size_t). Tue Feb 12 20:15:13 2002 Joe Orton * ne_string.h (STRIP_EOL): Removed macro. Mon Feb 11 22:11:03 2002 Joe Orton * ne_session.c (match_hostname): Match fully-qualified hostnames against commonName with leading "*." wildcard. Mon Feb 11 20:47:28 2002 Joe Orton * ne_session.c (match_hostname): New function. (check_certificate): Use it. Sun Feb 10 00:50:49 2002 Joe Orton * ne_request.c (lookup_host): Set error string on lookup failure. Sun Feb 10 00:34:42 2002 Joe Orton * ne_request.c (strip_eol): New function; more efficient STRIP_EOL. (send_request): Use strip_eol. (read_message_header): Use strip_eol, simplify, remove redundant variables. Sat Feb 9 21:02:31 2002 Joe Orton * ne_session.c (ne_set_error): Drop STRIP_EOL call. Sat Feb 9 21:01:01 2002 Joe Orton * ne_session.c (ne_set_error): Take printf-style format string + varargs list. Sat Feb 9 16:15:09 2002 Joe Orton * ne_socket.h (SOCKET_READ_TIMEOUT): Moved to ne_socket.c. * ne_socket.c (struct nsocket_s): Add rdtimeout field. (create_sock): Initialize rdtimeout to SOCKET_READ_TIMEOUT. (sock_read, sock_recv): Use ->rdtimeout field for read timeout. (sock_set_read_timeout): New function. * ne_private.h (struct ne_session_s): Add rdtimeout field. * ne_session.c (ne_set_read_timeout): New function. * ne_request.c (init_socket): New function. (open_connection): Use init_socket. Sat Feb 9 15:11:59 2002 Joe Orton * ne_session.c (ne_session_destroy): Don't leak the server cert. Sat Feb 9 09:59:11 2002 Joe Orton * ne_session.c (check_certificate): Only call verification callback once per certificate; watch for the server cert changing and fail if it does. Wed Feb 6 20:28:27 2002 Joe Orton * ne_session.c (check_certificate): Only call verification callback if failures is non-zero. (ne_ssl_load_ca): Renamed from ne_ssl_add_ca. (ne_ssl_load_default_ca): New function. Wed Feb 6 20:21:29 2002 Joe Orton * ne_socket.c (sock_init): Cache and return result of initialization. Wed Feb 6 01:12:20 2002 Joe Orton * ne_session.c (check_certificate): Ignore cert validity errors from OpenSSL since these are duplicated. Wed Feb 6 01:08:57 2002 Joe Orton * ne_session.c (ne_negotiate_ssl): Fix for invalidating cached SSL_SESSION. Wed Feb 6 01:03:37 2002 Joe Orton * ne_session.c [!NEON_SSL] (STUB): New function. (ne_negotiate_ssl, ne_ssl_add_ca): Implement using STUB. Tue Feb 5 19:56:43 2002 Joe Orton * ne_session.h (ne_ssl_certificate): New type. * ne_session.c (ne_session_create) [NEON_SSL]: Create the SSL_CTX structure. (ne_ssl_get_context): Return the SSL_CTX rather than setting it. (ne_session_destroy): Free the SSL_CTX. (asn1time_to_string): Function moved in from sslcerts.c. (check_certificate): Use OpenSSL's internal validity result. Pass back an ne_ssl_certificate to the verification function; including validity dates. (ne_ssl_add_ca): New function, registers CA certs. Sat Feb 2 14:05:26 2002 Joe Orton * ne_socket.c (sock_enable_ssl_os): Take an optional SSL_SESSION argument. * ne_private.h (struct ne_session_s): Add an SSL_SESSION field. * ne_session.c (ne_negotiate_ssl): Pass stored SSL session to sock_enable_ssl_os, cache session after successful negotiation. (ne_session_destroy): Free cached session. Sat Feb 2 10:45:46 2002 Joe Orton * ne_socket.c, ne_utils.c: Globally replace ENABLE_SSL cpp symbol with NEON_SSL. Sat Feb 2 09:43:27 2002 Joe Orton * ne_session.c (check_certificate): Use 1K on-stack buffer. Sat Feb 2 08:27:08 2002 Joe Orton * ne_private.h (struct host_info): Add 'resolved' flag. (struct ne_session_s): Add scheme field, rename have_proxy to use_proxy, remove proxy_decider. (struct ne_request_s): Remove use_proxy field. * ne_request.c (set_sockerr, ne_set_request_uri, build_request, open_connection): Use session->use_proxy field to determine whether proxy is used. (ne_request_create): Drop use of proxy_decider callback. (lookup_host): Moved here from ne_session.c. (ne_begin_request): Lookup server/proxy hostname if not already resolved. * ne_session.c (ne_session_create): Moved within file; takes scheme, and server hostname, port as arguments. (ne_ssl_enable, ne_session_decide_proxy, ne_session_server): Removed functions. (ne_get_scheme): Simply return scheme field. Fri Feb 1 23:12:38 2002 Joe Orton * ne_request.c (add_fixed_headers): Remove last traces of TLS upgrade support. Thu Jan 31 20:50:12 2002 Joe Orton * ne_private.h (struct ne_session_s): Rename use_secure to use_ssl; removed nssl_context, added SSL_CTX, server cert, verify callback pointers. * ne_request.c (send_request): Remove support for TLS upgrade. (open_connection): Use ne_negotiate_ssl; close socket properly if negotiation fails. * ne_session.c (ne_session_destroy): Free SSL_CTX stored in session. (ne_ssl_set_context, ne_ssl_set_verify, verify_err, getx509field, check_context, ne_negotiate_ssl, ne_ssl_server_cert): New functions. (ne_set_secure_context, ne_set_request_secure_upgrade, ne_set_accept_secure_upgrade): Removed functions. (ne_ssl_enable): Renamed from ne_set_secure. * ne_socket.c (struct nssl_context_s): Removed type. (sock_create_ssl_context, sock_destroy_ssl_context, sock_disable_*, key_prompt_cb, sock_set_key_prompt, sock_set_client_cert): Removed functions. (sock_enable_ssl_os): Renamed from sock_make_secure; take an SSL_CTX pointer, and optionally pass out the SSL structure. (sock_enable_ssl): New function. Wed Jan 30 19:47:42 2002 Joe Orton * ne_string.c (ne_buffer_concat, ne_buffer_zappend, ne_buffer_append, ne_buffer_grow): Don't return success value, presume universe ends at OOM. Sat Jan 26 10:57:42 2002 Joe Orton * ne_compress.c: Renamed enum state constants to have prefix NE_Z_, to avoid conflict with Windows headers (Branko ibej). Mon Jan 14 20:26:31 2002 Joe Orton * ne_string.c (ne_concat): Removed function - it didn't work, and it wasn't used. Mon Jan 14 02:09:38 2002 Joe Orton * ne_basic.c (ne_content_type_handler): Parse charset parameter. Sun Jan 13 14:29:00 2002 Joe Orton * ne_basic.c (ne_content_type_handler): Remove trailing '/' from parsed type, fix search for parms separator (Greg Stein). Sun Jan 13 12:07:51 2002 Joe Orton * ne_207.c (ne_simple_request): Drop unused Content-Type handling. Thu Jan 10 00:39:17 2002 Joe Orton * ne_request.c (hdr_hash): Mark as inline. Tue Jan 8 22:03:42 2002 Joe Orton * ne_locks.c (add_timeout_header): New function. (ne_lock, ne_lock_refresh): Send a Timeout header if lock->timeout is set. Mon Jan 7 21:48:38 2002 Joe Orton * ne_locks.c (parse_timeout): Fix parsing lock timeout (Arun Garg). Mon Dec 17 22:46:36 2001 Joe Orton * ne_private.h (struct ne_session_s): Make expect100_works a plain integer (rather than a bitfield). Sun Dec 9 14:04:27 2001 Joe Orton * ne_string.c (ne_buffer_grow, ne_buffer_create_sized): Don't zero-fill new memory. (ne_buffer_concat): Zero terminate the string as _grow doesn't do it. Sun Dec 9 13:31:55 2001 Joe Orton * ne_string.c (ne_buffer_zappend): Minor optimisation; implement using ne_buffer_append. Sun Dec 9 13:18:35 2001 Joe Orton * ne_string.c (ne_buffer_concat): Optimise to use time O(n) [n == total string length). Sun Dec 9 11:57:56 2001 Joe Orton * Makefile.in (NEON_DAVOBJS): Remove ne_acl.o. Sat Dec 8 01:11:30 2001 Joe Orton * ne_request.c (ne_pull_request_body): Use NE_FMT_SIZE_T in debugging message; cast size_t to int to avoid GCC warning for field size parameter. (set_body_size): Use NE_FMT_SIZE_T. * ne_xml.c (ne_xml_parse): Similarly. Mon Dec 3 19:56:07 2001 Joe Orton * ne_session.c (ne_session_destroy): Return void. Sat Dec 1 18:37:43 2001 Joe Orton * ne_auth.c (ah_create): Reset attempt counter here... (ah_post_send): ...rather than here. Tue Nov 27 21:26:01 2001 Joe Orton * ne_request.c (send_with_progress): Actually call the callback; fix for correct sock_fullwrite return codes. Tue Nov 27 20:20:40 2001 Joe Orton * ne_private.h (VERSION_PRE11): Define macro; as ne_version_pre_http11. * ne_session.c (ne_version_pre_http11): Use VERSION_PRE11. * ne_request.c (add_fixed_headers, build_request, ne_end_request): Use VERSION_PRE11. Sun Nov 18 19:32:56 2001 Joe Orton * ne_locks.c (discover_results): Check status is 2xx before invoking callback; pass NULL lock and non-NULL status pointer in failure cases. (create_private): Initialize lock to some "value unspecified" defaults. Sun Nov 18 19:25:10 2001 Joe Orton * ne_auth.c (auth_session): Rename 'tries' field to 'attempt'. (get_credentials, ah_pre_send, ah_post_send): Increment attempt counter only when requesting credentials; reset it to zero when no auth failure is signaled. Sun Nov 18 15:49:00 2001 Joe Orton * ne_auth.h (ne_request_auth): Pass username and password as buffers of size NE_ABUFSIZ to callback. Add 'attempt' argument. * ne_auth.c (auth_session): Store username in buffer. (get_credentials, basic_challenge, digest_challenge): Updated for callback prototype changes. (ah_post_send): Request credentials, and retry authentication until callback returns non-zero. Mon Nov 12 20:57:56 2001 Joe Orton * ne_basic.c (get_to_fd): Really cope with short writes (thanks to rado ). Sun Nov 4 15:09:03 2001 Joe Orton * ne_props.h: Define NE_ELM_PROPS_UNUSED for picking element ids for use with the propfind XML parser. Sat Nov 3 19:06:04 2001 Joe Orton * ne_props.c (NSPACE): New macro. (set_body, pnamecmp, startelm, free_propset): Handle property having NULL nspace element in propfind code. Sun Oct 28 22:04:49 2001 Joe Orton * ne_xml.c (parse_element): Prevent false matches of found prefix "abcde" against stored prefix "abcdeFGH". Compare case-sensitively. Fri Oct 26 20:28:03 2001 Joe Orton * ne_request.c (send_request): Fix case where persistent connection times out, and improve error handling. Thu Oct 25 20:42:24 2001 Joe Orton * ne_props.c (ne_proppatch): Really handle properties with a NULL namespace correctly; use the "D:" prefix for elements in the "DAV:" namespace; allow properties to have no namespace. Tue Oct 16 08:54:46 2001 Joe Orton * ne_xml.c (parse_element): Fail the parse if a namespace prefix definition is given with an empty value. Tue Oct 16 08:52:40 2001 Joe Orton * ne_props.h, ne_207.h: Move ne_propname definition into ne_props.h. Tue Oct 16 08:49:42 2001 Joe Orton * ne_props.c (ne_proppatch): Handle properties with a NULL nspace field correctly. Sun Oct 7 19:31:06 2001 Joe Orton * ne_acl.c (ne_acl_set) [USE_DAV_LOCKS]: Notify use of resource to locking code. Sun Oct 7 17:45:01 2001 Joe Orton * ne_acl.c, ne_acl.h: New files, contributed by Arun Garg . * Makefile.in: Add ne_acl.* to build. Sun Oct 7 16:10:05 2001 Joe Orton * ne_private (struct ne_session_s): Add 'reqcount' field. * ne_request.c (send_request): Refactor slightly; don't loop, but return NE_RETRY when appropriate. Increment reqcount. (ne_begin_request): Loop if send_request returns NE_RETRY. (open_connection): Reset reqcount field. Tue Oct 2 21:11:39 2001 Joe Orton * ne_dates.c (GMTOFF): New macro. (ne_iso8601_parse, ne_rfc1123_parse, ne_rfc1036_parse, ne_asctime_parse): Use new macro, fix up date handling on some platforms. Sat Sep 29 14:20:47 2001 Joe Orton * ne_compress.c (gz_reader): Fix tests 4 and 7: don't try to inflate after reading header if no bytes are left in the buffer. Sat Sep 29 14:04:11 2001 Joe Orton * ne_compress.c: Fix API; return an opaque object which must be destroyed later. (ne_decompress_reader): Renamed from ne_gzip_response_body_reader. Doesn't need the session object passed in any more. (ne_decompress_destroy): Merge of co_destroy, co_post_end. Sat Sep 29 13:50:43 2001 Joe Orton * ne_request.c (ne_get_session): New function. Sat Sep 29 12:52:31 2001 Joe Orton * ne_compress.c (parse_header): Bail if flags are set to something unexpected. Sat Sep 29 11:15:30 2001 Joe Orton * ne_compress.c, ne_compress.h: New files. * Makefile.in: Add deps for ne_compress. Thu Sep 27 09:05:24 2001 Joe Orton * ne_redirect.c: Adapted for new hooks interface. * ne_cookies.c: Adapted for new hooks interface. (ne_cookie_register): New function. Thu Sep 27 09:01:03 2001 Joe Orton * ne_auth.c, ne_locks.c: Adapted for new hooks interface. Store pointer to per-request object in the per-session object. Thu Sep 27 08:48:16 2001 Joe Orton Re-write hooks interface to register callbacks individually rather than as a block. Inspired by the Apache 2.0/APR hooks interface. * ne_private.h (struct hook): Store a callback, userdata, id. (struct hook_request): Removed. (struct ne_session_s): Store hooks lists for create_req, pre_send, post_send, destroy_req, destroy_sess, accessor. (struct ne_request_s): Store accessor hooks list. * ne_request.c (ne_add_hooks): Removed. (ne_hook_create_request, ne_hook_pre_send, ne_hook_post_send, ne_hook_destroy_request, ne_hook_destroy_session, ne_hook_session_accessor, ne_hook_request_accessor, ne_null_accessor, call_access, add_hook): New functions. (ne_request_create, ne_request_destroy, build_request, ne_end_request): Adapt for new interface. * ne_session.c (destroy_hooks): New function. (ne_session_destroy): Use it to destroy hooks lists appropriately. Tue Sep 25 07:46:32 2001 Joe Orton * ne_xml.c: Only decode UTF-8 for parsers other than libxml 1.x. Tue Sep 25 07:33:09 2001 Mo DeJong * src/ne_socket.c: Include instead of . (sock_init): Only use signal() to ignore SIGPIPE if both HAVE_SIGNAL and HAVE_SIGPIPE are defined. Tue Sep 25 07:09:53 2001 Mo DeJong * ne_socket.c (sock_init): Declare local variables before invoking any instructions since that is not valid C code. Sun Sep 23 10:30:54 2001 Joe Orton * ne_auth.c (struct auth_challenge): Make members const. (clean_session): Free the realm string. (basic_challenge, digest_challenge): strdup the realm string. (request_digest): opaque is no longer stored quoted. (tokenize): New function. (verify_response, auth_challenge): Rejig to use tokenize(). Sat Sep 22 20:17:00 2001 Joe Orton * ne_string.c (ne_shave): Fix possible memory corruption when result should be the empty string. Thu Sep 20 21:27:57 2001 Joe Orton * ne_request.c (ne_pull_request_body): Add debugging dump of body blocks. Thu Sep 20 21:23:43 2001 Joe Orton * ne_private.h: Remove obsolete 'if_locks' member from struct ne_request_s. Tue Sep 18 23:35:30 2001 Joe Orton * ne_basic.c (ne_get_range): Handle write errors too. Tue Sep 18 22:14:49 2001 Joe Orton * ne_xml.h (ne_xml_validate_cb): Take userdata parameter. * ne_xml.c (find_handler): Pass validate callback the handler's userdata. * ne_207.c, ne_props.c, ne_locks.c: All users changed. Tue Sep 18 21:49:14 2001 Joe Orton * ne_locks.c (ne_lock_refresh): New function. Tue Sep 18 21:17:29 2001 Joe Orton * ne_basic.c (copy_or_move): Take a depth parameter, add depth header, for COPY requests. (ne_copy): Take depth parameter, pass through. (ne_move): Adjusted accordingly. Mon Sep 17 23:29:58 2001 Joe Orton * ne_utils.c (ne_debug_init): Set debug stream to be unbuffered if setvbuf() is available. Mon Aug 27 00:36:37 2001 Joe Orton * ne_207.c (start_element, end_element): Remember when context is valid for a , and only invoke callback then. Sun Aug 26 22:30:39 2001 Joe Orton * ne_basic.c (ne_get_range): Better error handling. Cope with Apache's 416 problem. Sun Aug 26 18:58:47 2001 Joe Orton * ne_auth.c: Store unquoted challenge parameters in session object, prevent having to unquote/free them >1 times. Sun Aug 26 18:57:51 2001 Joe Orton * ne_socket.c (sock_init): Do nothing on any calls after first. Sun Aug 26 12:45:04 2001 Joe Orton * ne_basic.c (server_hdr_handler): Remove function. (ne_options): Don't add server_hdr_handler. Tue Jul 17 11:25:06 2001 Joe Orton * ne_socket.c (sock_init): Set signal dispostion for SIGPIPE to ignore. Sat Jun 30 12:11:44 2001 Joe Orton * ne_utils.c (ne_supports_ssl): New function. Tue Jun 19 21:57:49 2001 Joe Orton * ne_dates.c (ne_iso8601_parse): Fix month off-by-one bug, use separate vars for offsets. (ne_rfc1036_parse): Fix Y2K bug, parsing problem. Tue Jun 19 21:57:42 2001 Joe Orton * ne_dates.c (ne_iso8601_parse): New function. Sun Jun 10 15:39:40 2001 Joe Orton * ne_request.c (send_with_progress): New function. (send_request_body): Use send_with_progress to trigger progress callbacks if necessary. Sat Jun 9 15:42:33 2001 Joe Orton * ne_string.h: Bring back NE_ASC2HEX/HEX2ASC. * ne_md5.c: Use them. Sat Jun 9 15:42:08 2001 Joe Orton * ne_xml.h: Include ne_defs.h. Fri Jun 8 23:02:49 2001 Joe Orton * ne_socket.h, ne_socket.c: Update for includes (Mo DeJong). Fri Jun 8 21:34:00 2001 Joe Orton * ne_basic.c (dav_hdr_handler): Use ne_token. Sat Jun 2 14:37:07 2001 Joe Orton * ne_private.h: Renamed from http_private.h. Sat Jun 2 14:35:23 2001 Joe Orton * ne_auth.c, ne_auth.h: Renamed from http_auth.c, ne_auth.h. Sat Jun 2 14:35:02 2001 Joe Orton * ne_cookies.c, ne_cookies.h: Renamed from http_cookies.c, http_cookies.h. Sat Jun 2 14:34:51 2001 Joe Orton * ne_dates.c, ne_dates.h: Renamed from dates.c, dates.h Sat Jun 2 14:22:49 2001 Joe Orton * ne_redirect.c, ne_redirect.h: Renamed from http_redirect.c, http_redirec.h. Big rename... s/http_/ne_g/ Sat Jun 2 12:54:51 2001 Joe Orton * ne_md5.c (md5_process_block): Fix for word alignment issue on Sparc from Kai Sommerfeld. Wed May 30 23:15:31 2001 Joe Orton * ne_basic.c (ne_put, ne_get, ne_put_if_unmodified, ne_get_range, ne_post): Take an integer fd rather than FILE * stream. (get_to_fd): Write to fd rather than stream. Wed May 30 23:08:55 2001 Joe Orton * ne_i18n.h, ne_i18n.c: Renamed from neon_i18n.h, neon_i18n.c. * *.c: All changed accordingly. Wed May 30 23:02:47 2001 Joe Orton * ne_defs.h: Renamed from neon_defs.h. * *.h: All changed accordingly. Wed May 30 22:58:57 2001 Joe Orton * ne_md5.c, ne_md5.h: Renamed from md5.c, neon_md5.h Wed May 30 22:55:19 2001 Joe Orton * ne_utils.h: In-line ne_debug for GCC which can cope with varargs preprocessor macros. Wed May 30 00:43:05 2001 Joe Orton * http_auth.c (ah_use_body): Removed function. (digest_body): New function. (request_digest): Use ne_pull_request_body to find the MD5 digest of the request body, when necessary. Wed May 30 00:30:52 2001 Joe Orton * http_redirect.c: Store Request-URI, session pointer, and method string in redirect object. Avoid looking inside ne_request/ne_session internals. Wed May 30 00:04:30 2001 Joe Orton * ne_request.c: Re-implement request body handling in terms of a callback which provides the request body blocks on demand. Remove 'use_body' hook, in favour of the hooks calling ne_pull_request_body when necessary. (ne_pull_request_body, body_fd_send, body_string_send): New functions. (send_request_body): Re-implemented using ne_pull_request_body. (run_set_body_hooks): Removed function. (ne_set_request_body_fd): Replacement for ne_set_request_body_stream, using a raw fd rather than a FILE *. Tue May 29 22:39:39 2001 Joe Orton * dav_basic.h, dav_basic.h: Removed. Tue May 29 22:38:54 2001 Joe Orton * ne_207.c (ne_simple_request, etc): Copied in from dav_basic.c. Tue May 29 22:12:23 2001 Joe Orton * ne_locks.c, ne_locks.h, ne_props.c, ne_props.h, ne_207.c, ne_207.h: Big rename. dav_* -> ne_*, and so on. Tue May 29 22:06:24 2001 Joe Orton * ne_basic.c (ne_add_depth_header): Moved from dav_basic.c. Tue May 29 21:55:30 2001 Joe Orton * ne_props.c, ne_props.h: Renamed from dav_props.c, dav_props.h. Tue May 29 21:43:15 2001 Joe Orton * ne_207.c, ne_207.h: Renamed from dav_207.c, dav_207.h. Tue May 29 21:22:25 2001 Joe Orton * ne_locks.c, ne_locks.h: Renamed from dav_locks.c, dav_locks.h. Tue May 29 21:21:44 2001 Joe Orton * ne_socket.c (sock_fullwrite): Cast return value of SSL_write to size_t to prevent comparison of signed with unsigned. Tue May 29 21:05:27 2001 Joe Orton * ne_basic.c [!NEON_NODAV]: Move ne_copy, ne_mkcol, ne_move, ne_delete in here. Tue May 29 20:12:50 2001 Joe Orton * ne_uri.c, ne_uri.h: Renamed from uri.c, uri.h. Tue May 29 19:17:09 2001 Joe Orton * ne_socket.c, ne_socket.h: Renamed from socket.c, nsocket.h. Tue May 29 18:58:51 2001 Joe Orton * ne_basic.c (ne_mkcol, ne_copy, ne_move, ne_delete): Renamed from dav_*. Tue May 29 17:58:09 2001 Joe Orton * ne_basic.c (copy_or_move, dav_copy, dav_move, dav_delete, dav_mkcol): Copied in from dav_basic.c. Tue May 29 17:55:33 2001 Joe Orton * ne_basic.c, ne_basic.h: Renamed from http_basic.c, http_basic.h. Tue May 29 17:47:50 2001 Joe Orton * http_auth.c (ah_create, ah_pre_send): Add the response body handler in pre_send, and only if qop=auth-int. Wed May 16 20:54:51 2001 Joe Orton * ne_request.c (ne_get_request_headers): Removed function. Sat May 12 18:48:46 2001 Joe Orton * ne_request.c (read_message_header, read_response_headers): Use a fixed-size char * buffer argument rather than an ne_buffer. Append directly to it when header-folding. Mon May 7 10:42:38 2001 Joe Orton * ne_string.c (ne_token): Use an optimized search (strchr) if quotes is NULL. Mon May 7 01:33:48 2001 Joe Orton * http_auth.c (basic_challenge, get_cnonce): Updated for ne_base64 change. Mon May 7 01:32:22 2001 Joe Orton * base64.c (ne_base64): Take length parameter. [BASE64_TEST] (main): Remove function, obsoleted by test code. Wed May 2 12:06:59 2001 Joe Orton * ne_string.c, ne_string.h (ne_token, ne_shave): New functions, destined to replace split_string, shave_string, etc. * ne_string.c [SPLIT_STRING_TEST, PAIR_STRING_TEST] (main): Remove tests, functions are obsolete. Tue May 1 22:14:14 2001 Joe Orton * dates.c (ne_httpdate_parse): Moved from ne_utils.c. Tue May 1 21:55:45 2001 Joe Orton * ne_utils.c, ne_utils.h: Renamed from http_utils.c, http_utils.h. Big rename. http_* -> ne_*. neon_* -> ne_*. DEBUG() -> NE_DEBUG(). DEBUG_* -> NE_DBG_*. Tue May 1 21:35:10 2001 Joe Orton * ne_request.c: Updated for ne_buffer changes. Tue May 1 21:28:58 2001 Joe Orton * ne_string.h (ne_buffer_size): Implement as macro. * ne_string.c (ne_buffer_size): Remove function. Tue May 1 21:23:47 2001 Joe Orton * ne_string.c, ne_string.h: Make ne_buffer a transparent type, and no longer be an implicit pointer type. (ne_buffer_*): All changed. (ne_buffer_data, NE_BUFFER_CAST): Removed. Tue May 1 21:17:40 2001 Joe Orton * ne_string.c, ne_string.h: Renamed sbuffer -> ne_buffer. Implicit pointer removed ne_buffer type. Tue May 1 21:12:15 2001 Joe Orton * ne_string.c, ne_string.h: Renamed from string_utils.c, string_utils.h (CVS copy'n'delete). Tue May 1 20:49:46 2001 Joe Orton * md5.c (ASC2HEX, HEX2ASC): Moved here from string_utils.h. * string_utils.h: As above. Tue May 1 20:47:20 2001 Joe Orton * http_request.c, http_request.h: Removed files. * ne_request.c, ne_request.h: Copied from old http_request.[ch]. Renamed http_* -> ne_*. Tue May 1 20:43:11 2001 Joe Orton * hip_xml.c renamed to ne_xml.c, hip_xml.h renamed to ne_xml.h: CVS repository copy'n'delete. Tue May 1 20:41:03 2001 Joe Orton * hip_xml.c, hip_xml.h: Big rename. hip_xml_* -> ne_xml_*. Tue May 1 20:37:13 2001 Joe Orton * http_basic.c, http_basic.h: Big rename. http_* -> ne_*. Tue May 1 19:59:01 2001 Joe Orton * ne_session.c: Renamed http_* to ne_*. Tue May 1 19:55:47 2001 Joe Orton * ne_alloc.h (NE_FREE): Renamed from HTTP_FREE() in http_utils.h Tue May 1 19:54:42 2001 Joe Orton * socket.c (sock_make_secure): Set SSL_MODE_AUTO_RETRY when available. Mon Apr 30 00:36:34 2001 Joe Orton * ne_session.[ch]: New files, split down from http_request.[ch]. Sun Apr 29 15:02:23 2001 Joe Orton * uri.c [URITEST] (main): Remove, obsoleted by new test suite. Sun Apr 29 15:01:30 2001 Joe Orton * uri.c (uri_has_trailing_slash): Return false if uri is "". Sun Apr 29 13:53:41 2001 Joe Orton * dates.c (ne_asctime_parse, ne_rfc1123_date, ne_rfc1036_parse): Set tm_isdst to -1 in struct tm. Sun Apr 29 13:28:26 2001 Joe Orton * http_utils.c (http_parse_statusline): Skip leading whitespace. (Johan Lindh). (http_parse_statusline): Ensure status-code is not more than three digits. Sun Apr 29 13:26:47 2001 Joe Orton * http_request.c (build_request): Don't add "Content-Length: 0" header if no body: Squid 2.3-STABLE1 doesn't like this. Sun Apr 29 13:25:16 2001 Joe Orton * http_auth.c (everywhere): Renamed md5_* -> ne_md5_*. Sun Apr 29 13:24:12 2001 Joe Orton * md5.c: Renamed md5_* -> ne_md5_*. (ne_ascii_to_md5, ne_md5_to_ascii): Moved from string_utils.c. Thu Apr 26 22:39:05 2001 Joe Orton * uri.c (uri_parse): A zero-length URI is invalid. Wed Apr 25 23:11:51 2001 Joe Orton * dav_props.c (startelm): Check for xml:lang attribute and store as prop->lang. (dav_propset_lang): New function. (free_propset): Free lang. Wed Apr 25 23:08:52 2001 Joe Orton * hip_xml.c (hip_xml_get_attr): New function. Sun Apr 22 21:48:06 2001 Joe Orton * uri.c (uri_parse): Skip a userinfo@ segment if present (Johan Lindh ). Wed Apr 18 13:29:46 2001 Joe Orton * dav_locks.c (dav_lock_copy): Allow owner to be NULL. Tue Apr 17 22:57:50 2001 Joe Orton * ne_alloc.h, dav_locks.h: Add C++ inclusion safety. Tue Apr 17 22:56:50 2001 Joe Orton * uri.c (uri_parse): Correctly handle URIs with no scheme or hostport segments (i.e. just a path). Tue Apr 10 00:29:25 2001 Joe Orton * socket.c [HAVE_SOCKS_H]: Include socks.h for SOCKSv5 support. Wed Apr 4 21:41:47 2001 Joe Orton * http_utils.h [WIN32]: Define ssize_t (Kai). Tue Apr 3 21:03:28 2001 Joe Orton * dav_locks.c (dav_lock_discover): Cope with below API change. Tue Apr 3 20:43:50 2001 Joe Orton * dav_props.c (propfind): Register the flat element handler here, to pick up *any* properties and store them as 'flat' if they are not handled by a handler further down the stack. (make_elms, free_elms, dav_propfind_set_flat, dav_propfind_set_complex): Removed functions. (dav_propfind_named): Take the list of property names, and call set_body here. (dav_propfind_set_private): New function. Tue Apr 3 09:33:09 2001 Joe Orton * http_auth.h: Added C++ inclusion safety. (Kai Sommerfeld) Mon Apr 2 02:39:18 2001 Joe Orton * hip_xml.c (sax_error): Add parse error callback for libxml. Mon Apr 2 02:23:06 2001 Joe Orton * http_redirect.c (post_send): Clean up and fix logic. Only check for confirmation for same-server redirects. Mon Apr 2 02:13:48 2001 Joe Orton * http_redirect.c (http_redirect_location): New function. (destroy): Removed function. (create): Free location. (post_send): Only call notify callback for followed redirects. Mon Apr 2 01:55:27 2001 Joe Orton * http_request.c (http_set_request_uri): Allow using the '*' URI even when using a proxy server. Mon Apr 2 01:32:06 2001 Joe Orton * http_redirect.c (post_send): Give up on trying to follow a redirect to another server. Return HTTP_REDIRECT on such a redirect. * http_redirect.c (post_send): Fix leaks of URI object (Kai Sommerfeld). Mon Apr 2 01:08:33 2001 Joe Orton * http_request.c (read_response_headers): Don't read more than 100 response headers. Mon Apr 2 00:54:43 2001 Joe Orton * http_request.c (http_request_dispatch): Remove mapping of auth status codes to return values, the hook does it now. Mon Apr 2 00:53:20 2001 Joe Orton * http_request.c (http_set_request_uri): New function, split out from http_request_create. (http_request_create): Use it. Mon Apr 2 00:51:23 2001 Joe Orton * http_auth.c (http_set_proxy_auth, http_set_server_auth): Add failure codes. (ah_post_send): Return failure code if authentication fails. Mon Apr 2 00:19:17 2001 Joe Orton * http_utils.c: Pick up xmlversion.h from libxml2. (neon_version_string): Include libxml2 version string if defined. Sun Apr 1 21:40:00 2001 Joe Orton * http_basic.c (http_get_range): Fix total length calculation. (Johan Lindh ). (clength_hdr_handler): Use range->total. Sun Apr 1 21:26:09 2001 Joe Orton * hip_xml.c: Add expat2 support (Sam TH ). Sun Apr 1 21:07:19 2001 Joe Orton * string_utils.h (CONCAT2, CONCAT3, CONCAT4): Use ne_malloc. Sun Apr 1 20:59:09 2001 Joe Orton * dav_props.c (propfind, dav_proppatch): As below. Sun Apr 1 20:32:29 2001 Joe Orton * http_basic.c (http_post): Changed as per http_set_request_body_buffer change. * dav_locks.c (dav_lock): Likewise. Sun Apr 1 20:31:06 2001 Joe Orton * http_request.c (http_set_request_body_buffer): Pass in size parameter too. (send_request_body): Use sized rather than NUL-terminated buffer. Sun Apr 1 20:12:51 2001 Joe Orton * http_private.h: Added 'body_callback' request body type, and body_cb, body_ud fields to http_req. * http_request.c (http_set_request_body_provider): New function. (set_body_size): New function, factored out from old http_set_request_body_*. (http_set_request_body_stream, http_set_request_body_buffer): Use it. Sun Apr 1 19:56:17 2001 Joe Orton * dav_props.c: Replaced 'uri' and 'depth' fields in propfind handler object with an 'http_req' pointer. (dav_propfind_create): Create the request object here, and set the depth header. (propfind): Changed accordingly. (dav_propfind_destroy): Destroy request object too. * dav_props.c (dav_propfind_get_request): New function. Fri Mar 30 16:50:51 2001 Joe Orton * hip_xml.c (start_element): Quote attributes in collect (Kai Sommerfeld). Fri Mar 30 16:36:08 2001 Joe Orton * http_basic.c (http_put_if_unmodified): Changed as below. Thu Mar 22 14:05:52 2001 Joe Orton * http_utils.c (http_dateparse): Changed as below. * http_auth.c (get_conce, basic_challenge): Likewise. Thu Mar 22 14:04:54 2001 Joe Orton * dates.c (ne_rfc1123_date, ne_rfc1123_date, ne_asctime_parse, ne_rfc1036_parse): Added ne_ prefix. Thu Mar 22 14:03:12 2001 Joe Orton * base64.c (ne_base64): Renamed from base64. Tue Mar 20 20:34:44 2001 Joe Orton * dav_props.c (make_elms): Don't request UTF-8 decoding of property values. Tue Mar 20 20:33:39 2001 Joe Orton * string_utils.c (ne_utf8_decode): New function. Mon Mar 19 22:08:45 2001 Joe Orton * http_basic.c (get_callback): Removed function. (http_get, http_read_file, http_post): Use callbacks directly rather than indirectly through get_callback. Mon Mar 19 21:55:19 2001 Joe Orton * http_request.c (notify_status, http_set_status, http_set_progress): New functions: request status and progress callbacks. (open_connection, lookup_host): Use notify_status to trigger status callbacks, and register socket progress callbacks. Mon Mar 19 21:53:07 2001 Joe Orton * socket.c (sock_register_notify): Removed function. (sock_connect_u): Renamed to sock_connect. (sock_register_progress): Per-socket progress callbacks rather than global ones. (sock_call_progress): Take socket argument. (all callers changed). Mon Mar 19 21:52:50 2001 Joe Orton * socket.c (sock_get_version): New function. Mon Mar 19 13:59:21 2001 Joe Orton * dav_props.c (propfind): Destroy the handler. Mon Mar 19 13:36:55 2001 Joe Orton * dav_props.c (dav_propnames): New function. Wed Mar 14 22:42:12 2001 Joe Orton * http_request.h (http_begin_request, http_end_request, http_read_response_block): New functions. (http_request_dispatch): Reimplemented using new caller-pulls interface. Wed Mar 14 22:20:38 2001 Joe Orton * http_auth.c (ah_post_send): If authentication fails (i.e. bad credentials), clean the session details. Wed Mar 14 20:46:55 2001 Joe Orton * http_auth.c: Retry the request simply if it has not been tried before with authentication details, otherwise, fail on 40[17]. Wed Mar 14 20:12:52 2001 Joe Orton * http_request.c (open_connection): Make sure to close the connection, and return HTTP_CONNECT if the SSL negotiation fails. Tue Mar 6 18:37:43 2001 Joe Orton * ne_alloc.c (ne_strndup): Allocate n+1 bytes not 'n' (Kai Sommerfeld). Mon Mar 5 01:05:31 2001 Joe Orton * http_request.c: Moved local sbuffer variables of http_request_dispatch into http_req members 'reqbuf' and 'respbuf'. (build_request): Return a const char * of the request. (send_request): Call build_request directly, use req->respbuf. (http_request_dispatch): Don't call build_request. Removed 'goto' exception handling (hoorah). (http_request_create, http_request_destroy): Create and destroy reqbuf and respbuf here. Mon Mar 5 00:43:40 2001 Joe Orton * http_request.c (http_set_request_body_stream): Set req->body_size and Content-Length header here: return success value. (http_set_request_body_buffer): Likewise (but no return value). (get_request_bodysize): Removed function. (build_request): Add Content-Length: 0 header if no request body. Mon Mar 5 00:27:24 2001 Joe Orton * http_auth.c (http_forget_auth): New function. Mon Mar 5 00:25:15 2001 Joe Orton * http_request.c (http_request_hook_private): Renamed from http_get_hook_private. (http_session_hook_private): New function. * dav_locks.c (dav_lock_using_resource, dav_lock_using_parent): Renamed simiarly. Sun Mar 4 23:12:12 2001 Joe Orton * http_auth.c: Moved per-request state into struct auth_request. (request_digest): Take struct auth_request argument. (free_auth): New function. (http_add_hooks): Pass free_auth as cleanup function for auth session. Sun Mar 4 23:08:46 2001 Joe Orton * http_redirect.c (auto_redirect): Auto-redirect OPTIONS requests. (free_redirect): New function. (http_redirect_register): Pass cleanup function. Sun Mar 4 23:07:01 2001 Joe Orton * dav_locks.c (dav_lock_unregister): Removed function. (free_locks): New function. (dav_lock_register): Pass free_locks as cleanup function for hooks. Sun Mar 4 22:54:57 2001 Joe Orton * http_request.h (http_add_hooks): Added fourth argument to register a cleanup function for the cookie. Sun Mar 4 19:53:03 2001 Joe Orton * http_auth.c (request_digest): Use an sbuffer to create the header value. Sun Mar 4 19:44:18 2001 Joe Orton * http_auth.c: Remove namespace protection for private functions. s/http_auth/auth/g. Sun Mar 4 19:39:13 2001 Joe Orton * http_auth.c (ah_pre_send): Increase attempt counter here, ... (ah_post_send): instead of here. Sun Mar 4 18:40:03 2001 Joe Orton * http_request.c (http_request_dispatch): Simplify post_send hook invocation: run them until one doesn't return HTTP_OK. Don't run pre_send hooks here. Loop while a hook returns HTTP_RETRY. (build_request): Run pre_send hooks here. * http_request.c (read_response_body): Call normalize_response_length here. Sun Mar 4 18:12:26 2001 Joe Orton Re-implemented HTTP authentication using generic hooks interface. * http_auth.c: Added http_auth.h. (http_auth_init, http_auth_set_creds_cb, http_auth_new_request, http_auth_request_header): Removed functions, merged into new hooks code. (ah_create, ah_post_send, ah_pre_send, ah_use_body, ah_destroy): New functions. (auth_body_reader, http_set_server_auth, http_set_proxy_auth): Moved over from http_request.c and redone for hooks interface. * http_request.c (http_set_server_auth, http_set_proxy_auth, give_creds, auth_body_reader): Moved to http_auth.c. (http_accept_always): Renamed from always_accept_response and made public. (http_request_create, build_request, http_request_dispatch): Removed authentication code. Tue Feb 27 19:49:42 2001 Joe Orton * dav_props.c (set_body): Remove UTF-8 encoding again. Mon Feb 26 22:38:41 2001 Joe Orton Patch from Kai Sommerfeld to remove URI escaping from inside neon. * dav_207.c (end_element): Don't unescape href elements. * http_request.c (http_request_create): Don't escape Request-URI. * dav_basic.c (copy_or_move): Don't escape destination URI. Mon Feb 26 21:44:56 2001 Joe Orton * dav_props.c (set_body): UTF-8 encode the property name and value. (make_elms): Request UTF-8 decoding of property values. Mon Feb 26 21:40:14 2001 Joe Orton * hip_xml.c: Do perform UTF-8 decoding when using libxml. (char_data): Fix UTF-8 decoding bug where the byte after a multi-byte encoded sequence would be skipped. Sun Feb 25 20:04:05 2001 Joe Orton * string_utils.c (ne_utf8_encode): New function. Sun Feb 25 19:52:01 2001 Joe Orton * ne_alloc.c (ne_realloc): New function. Sun Feb 25 17:00:32 2001 Joe Orton * Makefile.in (all): Rename NEON_IS_BUNDLED to NEON_BUILD_BUNDLED. Sun Feb 25 16:52:43 2001 Joe Orton * Makefile.in (all): Build according to NEON_IS_BUNDLED. Fri Feb 23 23:38:10 2001 Joe Orton * Makefile.in: Fix deps: neon_config.h has gone. Fri Feb 23 22:57:47 2001 Joe Orton * dav_props.c (dav_simple_propfind): Support a NULL 'props' argument to do an allprop request, as per the advertising literature. Register a catch-all handler in this case. Fri Feb 23 22:16:42 2001 Joe Orton * http_request.c (http_session_destroy): Free up hooks list. Thu Feb 22 21:54:36 2001 Joe Orton * http_request.h (http_add_hooks): Make request_hooks 'const'. Thu Feb 15 08:36:56 2001 Joe Orton * http_request.c (read_response_body): Accept SOCK_CLOSED as end-of-response if we don't have a Content-Length (and not chunked). (Kai Sommerfeld). Thu Feb 15 08:36:23 2001 Joe Orton * http_request.c (add_fixed_headers): Don't add the Host header here. (http_request_dispatch): Add it here instead. * http_request.c (set_hostinfo): Dup the hostname. (http_session_destroy): Free the hostname. (Kai Sommerfeld). Thu Feb 15 08:35:49 2001 Joe Orton * http_private.h: Make hostname in struct host_info char *. (Kai Sommerfeld). Thu Feb 15 08:08:50 2001 Joe Orton * http_redirect.h: Add C++ header-inclusion safety macros (Kai Sommerfeld ). Wed Feb 14 23:37:57 2001 Joe Orton * http_request.c (read_response_body): Use a size_t for readlen, as read_response_block requires. Wed Feb 14 23:25:44 2001 Joe Orton * http_auth.c (request_digest): Fix incorrect signed-ness of buffer. Wed Feb 14 23:22:13 2001 Joe Orton * uri.h, string_utils.h: Comment-out tokens after #endif. Sun Feb 4 14:36:11 2001 Joe Orton * http_redirect.c (post_send): Prototype change. Sun Feb 4 14:31:42 2001 Joe Orton * socket.c: Added key_prompt, key_userdata, key_file to nssl_context. (sock_set_key_prompt, key_prompt_cb): New functions. (sock_make_secure): Set ctx->key_file to private key filename. Sun Feb 4 13:31:44 2001 Joe Orton * http_request.h: Make http_status argument of post_send a const pointer. Sun Feb 4 10:38:12 2001 Joe Orton * http_request.c (set_sockerr): Only use the socket error if it is NULL, else print generic "something went wrong"-type error message. Sun Feb 4 10:29:37 2001 Joe Orton * socket.c (sock_set_client_cert): Call SSL_CTX_check_private_key to ensure that the cert and private key match. Sun Feb 4 10:28:02 2001 Joe Orton * socket.c (sock_make_secure): In error cases after SSL_connect succeeds, call SSL_shutdown and assign sock->ssl = NULL before returning. Sat Feb 3 18:33:56 2001 Joe Orton * socket.c (sock_close): Call SSL_shutdown before close()'ing the fd. Sat Feb 3 18:30:48 2001 Joe Orton * socket.c: Store an default SSL_CTX in nsocket, to be used when no nssl_context is supplied. (create_socket): Create default SSL_CTX (sock_close): Free it here. (sock_make_secure): Use it here. Sat Feb 3 15:52:15 2001 Joe Orton * socket.c (sock_set_client_cert): New function. Sat Feb 3 15:48:51 2001 Joe Orton * socket.c: Rejig of nssl_context handling. An nssl_context is now really a wrapper for an SSL_CTX. (sock_create_ssl_context): Create the SSL_CTX here. (sock_disable_tlsv1, sock_disable_sslv2, sock_disable_sslv3): Set the SSL_CTX option directly. (sock_make_secure): Create an SSL_CTX if no nssl_context is supplied, otherwise use SSL_CTX from nssl_context. Sun Jan 28 13:52:03 2001 Joe Orton * http_utils.c (neon_version_minimum): New function. Sun Jan 28 10:37:28 2001 Joe Orton * neon_config.h.in: Removed file. * http_request.c, http_utils.c: Don't include neon_config.h. Sat Jan 27 22:52:37 2001 Joe Orton * socket.c: Use closesocket() as NEON_CLOSE (Markus Fleck ). Sat Jan 27 22:35:16 2001 Joe Orton * hip_xml.c: Add 'char_data' as libxml cdataBlock handler. Tue Jan 23 23:17:00 2001 Joe Orton * neon_config.h.in: Renamed from neon_config.h. Define NEON_VERSION_MAJOR and NEON_VERSION_MINOR too: all picked up from the NEON_VERSIONS macro. Sun Jan 21 22:07:34 2001 Joe Orton * string_utils.c (ne_concat): New function. Thu Jan 18 22:25:34 2001 Joe Orton * ne_alloc.h: Added ne_oom_callback. * ne_alloc.c: Added DO_MALLOC macro to do the malloc and oom callback test. (ne_malloc): Use DO_MALLOC. (ne_strdup, ne_calloc, ne_strndup): Reimplement using DO_MALLOC rather than calling ne_malloc(). Tue Jan 16 20:16:35 2001 Joe Orton * neon_config.h: Bumped version to 0.10.1. Tue Jan 16 20:14:40 2001 Joe Orton * http_request.c (http_session_create): Default expect-100 support to OFF. Mon Jan 15 22:59:33 2001 Joe Orton * neon_config.h: Bumped version to 0.10.0. Mon Jan 15 22:58:04 2001 Joe Orton * dav_basic.c (dav_simple_request): Use dav_207_ignore_unknown. Sun Jan 14 22:52:31 2001 Joe Orton * dav_props.c (propfind): Call dav_207_ignore_unknown. Sun Jan 14 22:49:06 2001 Joe Orton * dav_207.c: Don't handle unknown elements in normal handler. (ignore_cc, dav_207_ignore_unknown): New functions, for ignoring any unknown elements in the parse. Sun Jan 14 21:53:00 2001 Joe Orton * hip_xml.c: Renamed 'handlers' back to top_handlers. (push_handler): Now, p->root->handlers points to BASE of stack, p->top_handlers points to TOP of stack. (hip_xml_destroy): Changed to start from new BASE of stack. Sun Jan 14 10:50:09 2001 Joe Orton * http_request.c (http_session_server): Do perform the DNS lookup if we have a proxy_decider function, since that means we MIGHT need to know the IP address of the origin server. (http_request_create): Pass the real scheme back to the proxy decider callback. Wed Jan 10 22:43:16 2001 Joe Orton * Makefile.in: Rename OBJ_EXT to NEON_OBJEXT. Remove NEON_INTERFACE_VERSION, use NEON_LINK_FLAGS instead. Wed Jan 10 22:02:02 2001 Joe Orton * dav_locks.c (create_private): New function. (dav_lock_discover): Switch to using new dav_propfind_set_complex API. Wed Jan 10 21:59:36 2001 Joe Orton * dav_props.h (dav_propfind_set_complex): Switch the 'sizeof_private' argument for a callback 'creator': the return value of this callback is used as the 'private' field for the current resource. Mon Jan 8 22:09:55 2001 Joe Orton * dav_locks.h (dav_lock_result): Re-order arguments. Make lock object const. * dav_locks.c (dav_lock_copy): New function. (discover_results): Set lock->uri given href for current results. Free lock object after passing to results. Sun Jan 7 21:55:14 2001 Joe Orton * dav_locks.c (dav_lock): Destroy XML parser after use. Remove handling of Lock-Token header: it wasn't used and it leaked. Sun Jan 7 19:58:29 2001 Joe Orton * dav_props.c (free_propset): Free the property values, and the result set URI too. Sun Jan 7 16:58:19 2001 Joe Orton * http_request.c (read_response_block): Fix handling of SOCK_CLOSED from sock_read as end-of-connection. Sat Jan 6 15:02:57 2001 Joe Orton * hip_xml.c (struct hip_xml_parser): Renamed 'top_handlers' to 'handlers' in hip_xml_parser. (push_handler): New function. (hip_xml_push_handler, hip_xml_push_mixed_handler): Use push_handler. * hip_xml.c (find_handler): Begin the search for a new handler from the handler of the current (parent) element, and work up the stack. Sat Jan 6 11:15:17 2001 Joe Orton * hip_xml.c (find_handler): Display error message for unknown XML element as 'elmname (in nspace)' rather than 'nspace:elmname' since the latter produces confusing errors like 'DAV::displayname'. Wed Jan 3 21:34:44 2001 Joe Orton * Makefile.in: Hard-code top_builddir as '..' (possibly wrong, but true for all neon apps so far). Remove INCLUDES, now unused. Add top_srcdir. Fri Dec 22 22:51:27 2000 Joe Orton * dav_props.c: Added 'has_props' field to propfind_handler struct. (set_body): Only add leading 'prop' element if has_props is not set. Set has_props. Don't add trailing element here. (dav_propfind_named): ... add it here instead. (dav_propfind_set_complex, dav_propfind_set_flat): New set_body interface. Fri Dec 22 21:10:39 2000 Joe Orton * socket.c (sock_transfer): Don't use NEON_READ here, this is for reading from a non-socket fd. Wed Dec 20 00:19:34 2000 Joe Orton * neon_config.h: Bumped version to 0.9.1. Wed Dec 20 00:19:09 2000 Joe Orton * dav_props.c (free_propset): Don't free the private structure, make this the caller's responsibility. Wed Dec 20 00:12:36 2000 Joe Orton * dav_props.c (end_propstat): Rename propstat argument to 'pstat_v' to kill warnings. Tue Dec 19 23:42:39 2000 Joe Orton * dav_props.c (start_response): Zero-out the private structure on creation. Tue Dec 19 22:54:06 2000 Joe Orton * http_request.c (read_response_block): Rename local variable 'socket' to 'sock'. Tue Dec 19 22:52:56 2000 Joe Orton * http_request.h: Rename argument from 'stat' in post_send definition. Tue Dec 19 22:52:32 2000 Joe Orton * http_utils.h: Add 'const' to char * argument. Tue Dec 19 22:19:28 2000 Joe Orton * neon_config.h: Bumped version to 0.9.0. Tue Dec 19 22:12:19 2000 Joe Orton * Makefile.in: New file. Tue Dec 19 22:07:50 2000 Joe Orton * Makefile.incl: Removed file. Tue Dec 19 22:06:06 2000 Joe Orton * dav_locks.c (dav_lock_discover): New callback-based lock discovery interface. Re-implemented using new propfind interface. Tue Dec 19 21:22:43 2000 Joe Orton * dav_props.h: Replace old dav_propfind_* interface with better one. (dav_simple_propfind): Renamed from dav_get_props. (dav_propfind_current_private, dav_propfind_set_complex, dav_propfind_set_flat): New functions. (dav_propfind_get_current_resource): Removed function. (dav_propfind_named, dav_propfind_allprop): Change second argument to be the results callback. * dav_props.c: Replace implementatino of old interface with new one. (dav_simple_propfind): Re-implemented on top of new all-singing all-dancing dav_propfind_* interface. Sun Dec 17 18:24:50 2000 Joe Orton * dav_props.c: Add dav_get_props, and all its auxiliaries. Sun Dec 17 15:43:55 2000 Joe Orton * dav_props.c (propfind): Destroy the request after calling http_get_status. Sun Dec 17 18:04:58 2000 Joe Orton * hip_xml.c (find_handler): Allow using NULL as name and nspace in HIP_ELM_unknown elements. Sun Dec 17 18:03:03 2000 Joe Orton * dav_207.c (check_context): Don't handle the unknown element when it is a child of the prop element, this prevents handling allprop responses. Thu Dec 14 21:48:06 2000 Joe Orton * neon_config.h: Bumped version to 0.8.0. Thu Dec 14 21:43:31 2000 Joe Orton * dav_basic.c, dav_locks.c, dav_props.c (everywhere): Changed to new response-status interface, and _class->klass change. Thu Dec 14 21:37:38 2000 Joe Orton * http_request.c (http_get_status): Add new response-status interface. Thu Dec 14 21:30:25 2000 Joe Orton * http_basic.c (everywhere): Use new status interface. Thu Dec 14 21:25:03 2000 Joe Orton * http_private.h: Made http_status pointer in http_req a declared object. * http_request.h: Removed passing status pointer to http_request_dispatch. * http_request.c (everywhere): Removed passing extra http_status * to auxiliaries, use req->status instead. Renamed '_class' to 'klass' everywhere. Thu Dec 14 21:15:54 2000 Joe Orton * http_utils.h: Renamed '_class' member of http_status to 'klass'. (http_parse_statusline): Change accordingly. Wed Dec 13 23:00:23 2000 Joe Orton * socket.c: Changes for pre-BONE BeOS (David Reid ). Wed Dec 13 21:29:36 2000 Joe Orton * uri.c (ESCAPE): Explicitly cast the character to const unsigned int. (uri_abspath_escape): Make 'pnt' a normal const char *. Wed Dec 13 21:17:31 2000 Joe Orton * http_request.c: Remove netinet/in.h include, add limits.h include. (Peter Boos) (read_response_block): Make readlen a size_t (David Reid). Wed Dec 13 21:08:08 2000 Joe Orton * ne_alloc.h [WIN32]: Include stdlib.h. (Peter Boos) Wed Dec 13 20:54:27 2000 Joe Orton Patches from Peter Boos and David Reid for Win32 and BeOS changes respectively: * socket.c: Add NEON_READ, NEON_WRITE, NEON_CLOSE macros to use send/recv/closesocket for BeOS, send/recv/close for Win32, write/read/close otherwise. Include WinSock2.h in Windows. Add arpa/inet.h check. (sock_read, sock_write): Use the NEON_ macros. (sock_connect, sock_close): Use NEON_CLOSE. (sock_init): Winsock initialization. (sock_exit) Winsock cleanup. (sock_fullwrite): Use size_t rather than ssize_t for 'sent'. (sock_connect, sock_connect_u): Make 'port' parameter an unsigned short int. Wed Dec 13 20:42:18 2000 Joe Orton * http_basic.c (clength_hdr_handler): Use an off_t for len, to avoid comparison with size_t. Wed Dec 13 20:38:59 2000 Joe Orton * hip_xml.c (char_data): Use an 'int' for wslen, avoid comparison between size_t (which is signed) and int (which [is|might be?] unsigned). Wed Dec 13 20:29:12 2000 Joe Orton * nsocket.h [WIN32]: Use Windows headers rather than Unixy ones. (sock_exit): New function. Wed Dec 13 20:21:22 2000 Joe Orton * string_utils.c, string_utils.h, uri.h: Includes change (Peter Boos). Wed Dec 13 20:20:09 2000 Joe Orton * http_auth.c (http_auth_response_body): Don't make inline. Includes change. (both by Peter Boos). Wed Dec 13 20:18:38 2000 Joe Orton * uri.c (uri_unescape): Cast strtol return to (char). Includes change as below (both by Peter Boos). Wed Dec 13 20:07:38 2000 Joe Orton * base64.c, dates.c, dates.h, dav_207.c, dav_207.h, dav_basic.h, dav_locks.h, hip_xml.h, http_auth.h, http_basic.h, http_cookies.c, http_redirect.c, http_redirect.h, http_request.h, http_utils.c, md5.c, ne_alloc.c: Use #include "..." rather than #include <...> for neon headers. (Peter Boos ). Thu Dec 7 21:45:02 2000 Joe Orton * socket.c (sock_read): Return zero immediately if a zero count parameter is passed, following SUSv2 semantics. Thu Dec 7 21:41:36 2000 Joe Orton * nsocket.h (sock_readfile_blocked): Define an interface, allow taking -1 as the length parameter. Only return SOCK_CLOSED if length == -1 is NOT passed. Sun Nov 26 09:46:53 2000 Joe Orton * nsocket.h: Fix use of 'socket' in function prototypes. Sun Nov 19 00:29:48 2000 Joe Orton * nsocket.h: Increase read timeout to 120 seconds. Sun Nov 5 14:42:46 2000 Joe Orton * dav_locks.c: Fix element id's (fixes segfault when using locks). Thu Oct 26 22:28:17 2000 Joe Orton * socket.c (sock_peek): Return SOCK_CLOSED if recv() returns zero. Thu Oct 26 22:24:14 2000 Joe Orton * socket.c (sock_block): Return "got data" if SSL_pending indicates data pending. Otherwise select on socket as normal. Thu Oct 26 22:15:14 2000 Joe Orton * socket.c (sock_readline, sock_peek): Check whether SSL connection has been closed if SSL_peek returns 0 (thanks to Jeff Costlow ). Thu Oct 14 19:57:31 2000 Joe Orton * Makefile.incl: Fix spurius backslash at line 69 (thanks to Dirk Bergstrom ). Sat Oct 14 19:51:44 2000 Joe Orton * dav_basic.c (copy_or_move): Use http_get_scheme rather than hard-coding "http". 2000-10-02 Joe Orton * http_request.c (http_get_scheme): New function. Tue Oct 10 19:56:42 2000 Joe Orton * neon_config.h: Bumped version to 0.7.5. Sat Oct 7 19:26:58 2000 Joe Orton * neon_config.h: Bumped version to 0.7.4. Sat Oct 7 19:19:37 2000 Joe Orton * http_auth.c (request_digest): Quote algorithm and qop parameters in digest header. Sat Oct 7 19:15:29 2000 Joe Orton * socket.c (sock_connect_u): Don't leak the fd if connect fails (David Sloat). Sat Sep 16 16:49:57 2000 Joe Orton * hip_xml.h: Add 'HIP_ELM_UNUSED', defining lowest element ID which should be used. * hip_xml.c, hip_xml.h (hip_xml_push_handler, hip_xml_push_mixed_handler): Renamed from hip_xml_add_handler / hip_xml_add_mixed_handler to reflect stack-like usage of handlers. 'handlers' field of hip_xml_parser renamed to top_handler for same reason (globally search'n'replaced). * hip_xml.h: Documentation update. Thu Sep 14 22:37:33 2000 Joe Orton * http_auth.c (request_digest): Quote qop= value, fixes IIS5 interop. Thu Sep 14 00:40:04 2000 Joe Orton * socket.c (sock_connect_u): If connect() fails, close the socket before returning: thanks to David Sloat . Tue Sep 12 20:08:40 2000 Joe Orton * http_request.c (read_response_headers): Remove redundant tolower(). Tue Sep 12 00:41:39 2000 Joe Orton * neon_config.h: Bumped version to 0.7.3. Mon Sep 11 15:31:13 2000 Joe Orton * http_request.c, http_auth.c: Include snprintf.h if HAVE_SNPRINTF_H is defined. Fri Sep 8 10:46:53 2000 Joe Orton * neon_config.h: Bumped version to 0.7.2. Fri Sep 8 10:44:42 2000 Joe Orton * socket.c (sock_block): Return immediately if this is an SSL socket. Thu Sep 7 00:31:12 2000 Joe Orton * hip_xml.h: Correct order of hip_xml_validate_cb arguments in prototype (thanks to Greg Stein). Thu Sep 7 00:27:29 2000 Joe Orton * dav_props.c (propfind): Don't destroy the handler after use. (dav_propfind_destroy): New function. Thu Sep 7 00:08:45 2000 Joe Orton * Makefile.incl: Added targets for ne_alloc.o, string_utils.o, uri.o, base64.o. Tue Aug 15 21:53:53 2000 Joe Orton * neon_config.h: Bumped version to 0.7.1. Tue Aug 15 21:16:34 2000 Joe Orton * http_request.c (http_request_create): Only add authentication response body callbacks if a supply-credentials callback has been set for the session. (http_request_dispatch): Similarly for response header callbacks. Mon Aug 14 09:28:38 2000 Joe Orton * neon_config.h: Bumped version to 0.7.0. Mon Aug 14 09:23:54 2000 Joe Orton * string_utils.h (SBUFFER_CAST): New macro. Mon Aug 14 09:13:05 2000 Joe Orton * http_private.h: Use a hash table for storing response header handlers. Added response header 'catchers', which are passed ALL response headers. * http_request.c (http_add_response_header_handler): Place the handler in the correct hash bucket. (hdr_hash): New function. (http_add_response_header_catcher): New function. (http_request_destroy): Destroy the header catchers, and iterate over the hash table to destroy the handlers. (read_response_headers): Optimisation: hash and search for ':' in a single loop. Remove another local variable. Iterate through catchers too. Sun Aug 13 15:57:35 2000 Joe Orton * neon_config.h: Bumped version to 0.6.1. Sun Aug 13 15:50:42 2000 Joe Orton * http_request.c (send_request): Only go through the loop at most twice. Sun Aug 13 15:49:52 2000 Joe Orton * http_redirect.c (destroy): Don't free the redirect structure. Sat Aug 12 17:10:32 2000 Joe Orton * neon_config.h: Bumped version to 0.6.0. Sat Aug 12 16:48:47 2000 Joe Orton * http_request.c (http_session_decide_proxy): New function. (http_request_create): Call proxy "decider callback" to determine whether to use the proxy server for a given request or not. Sat Aug 12 16:39:10 2000 Joe Orton * Makefile.incl: Updated for http_private.h and http_redirect.[ch]. Sat Aug 12 16:36:49 2000 Joe Orton * http_request.c: Removed data structure definitions. * http_private.h: New file, contains data structure definitions. Interface NOT exported. Sat Aug 12 16:31:32 2000 Joe Orton * http_redirect.c (destroy): No return value. Sat Aug 12 16:04:02 2000 Joe Orton * http_redirect.[ch]: First cut at HTTP redirect handling. Sat Aug 12 11:05:13 2000 Joe Orton * neon_config.h: Bumped version to 0.5.1. Sat Aug 12 02:04:15 2000 Joe Orton * dav_locks.c (dav_lock_using_resource, dav_lock_using_parent): Prevent segfault if locking is not in use. Fri Aug 11 17:19:06 2000 Joe Orton * neon_config.h: Bumped version to 0.5.0. Fri Aug 11 16:31:23 2000 Joe Orton * http_request.c (read_message_header): Take a buffer for storing continuation lines. (read_response_headers): No need to strip EOL since read_message_header does this already. Use one less variable. Fri Aug 4 22:12:04 2000 Joe Orton * http_request.c (send_request): Don't retry sending the request more than once. Wed Aug 2 11:08:31 2000 Joe Orton * ne_alloc.[ch]: Renamed from xalloc.[ch]. Wed Aug 2 02:15:32 2000 Joe Orton * socket.c (sock_transfer): Return SOCK_CLOSED, or set sock->error appropriately on read failure. Tue Aug 1 13:04:27 2000 Joe Orton * socket.c, nsocket.h (sock_progress, sock_call_progress, sock_transfer, sock_readfile_blocked): Use 'off_t' not 'size_t' as file size type. Fri Jul 28 13:32:37 2000 Joe Orton * neon_config.h: Bumped version to 0.4.2. Fri Jul 28 13:31:38 2000 Joe Orton * http_request.c (send_request): Fix sending request body after getting 100-continue response. Fri Jul 28 11:26:47 2000 Joe Orton * neon_config.h: Bumped version to 0.4.1. Fri Jul 28 10:32:34 2000 Joe Orton * neon_config.h: Bumped version to 0.4.0. Fri Jul 28 10:28:21 2000 Joe Orton * http_basic.[ch] (http_post): New function, from Sander Alberink . Thu Jul 27 18:55:49 2000 Joe Orton * http_utils.c (neon_debug): No conditional compilation for function body: compile it all regardless of whether debugging is enabled or not, to allow applications to be debugged regardless of whether debugging is compiled into the library or not. Thu Jul 27 16:59:26 2000 Joe Orton * http_basic.c (clength_hdr_handler): Cast off_t to long int for printing. Tue Jul 25 18:14:15 2000 Joe Orton * http_request.c (read_message_header): Iterate over header handler list before placing zero-terminator at ':': if a handler has a NULL name field, pass it the entire header value. Tue Jul 25 18:00:49 2000 Joe Orton * http_request.c (http_get_request_headers): New function. Mon Jul 24 16:55:29 2000 Joe Orton * neon_config.h: Bumped version to 0.3.9. Mon Jul 24 16:54:33 2000 Joe Orton * http_basic.h: Use 'off_t' in http_content_range. * http_basic.c (http_get_range): Cast range values to (long int) to prevent compiler warnings. Thu Jul 20 20:03:30 2000 Joe Orton * http_request.[ch], socket.c, http_basic.c: Include nsocket.h not socket.h. Thu Jul 20 20:02:20 2000 Joe Orton * http_utils.c (version_string): Indicate which XML parser is supported. Thu Jul 20 20:01:12 2000 Joe Orton * nsocket.h: Renamed from socket.h. Thu Jul 20 15:02:35 2000 Joe Orton * http_utils.c, socket.c, http_request.c: SSL_ENABLE renamaed to ENABLE_SSL. Thu Jul 20 12:20:13 2000 Joe Orton * md5.c, http_auth.h: Include neon_md5.h. Thu Jul 20 12:19:23 2000 Joe Orton * neon_md5.h: Renamed from md5.h. Wed Jul 19 22:33:46 2000 Joe Orton * dav_basic.c (dav_simple_request): Don't leak ctype.value. Wed Jul 19 22:32:03 2000 Joe Orton * dav_207.c (check_context): Accept unknown elements. Wed Jul 19 22:31:10 2000 Joe Orton * dav_locks.c (dav_lock_iterate): Allow passing func as NULL. Wed Jul 19 22:26:13 2000 Joe Orton * socket.h (SOCKET_READ_TIMEOUT): Increase to 60. Wed Jul 19 22:25:51 2000 Joe Orton * dav_locks.h: Include http_request.h. Mon Jul 17 11:41:16 2000 Joe Orton * dates.c (asctime_parse, rfc1036_parse): Actually pass the string to sscanf (thanks to lclint). (rfc1123_date): Check for gmtime() returning NULL. Mon Jul 17 09:16:43 2000 Joe Orton * neon_config.h: Bumped version to 0.3.1. Mon Jul 17 09:07:58 2000 Joe Orton * dav_locks.c: Include limits.h: thanks to Paul D'Anna. Sun Jul 16 18:47:15 2000 Joe Orton * neon_config.h: Bumped version to 0.3.0. Sun Jul 16 16:44:25 2000 Joe Orton * neon_i18n.c (neon_i18n_init) [ENABLE_NLS && NEON_IS_LIBRARY]: New compilation conditions. Sun Jul 16 16:41:12 2000 Joe Orton * neon_i18n.c: New file. Sun Jul 16 16:15:02 2000 Joe Orton * string_utils.c (sbuffer_*): Change to assert postcondition (buf->used == strlen(buf->data) + 1). (sbuffer_append): Fix brokenness. Sun Jul 16 16:11:05 2000 Joe Orton * socket.c (sock_transfer): Increase sum length written correctly. Sun Jul 16 16:10:23 2000 Joe Orton * http_request.c (http_get_hook_private): New function. Sun Jul 16 16:07:11 2000 Joe Orton * hip_xml.c (find_handler): Call validate_cb for any handler which recognizes the element. Allow return codes HIP_XML_{VALID,INVALID,DECLINE} from validate_cb. If DECLINE is returned, continue searching handlers until one returns (IN)VALID. (start_element): Don't call validate_cb. * hip_xml.c (start_element, end_element): In collect mode, don't print namespace prefix if present. Sun Jul 16 15:30:19 2000 Joe Orton * dav_locks.[ch]: New file, code mainly taken from cadaver and adapted for neon HTTP request/response handling. Sun Jul 16 15:28:25 2000 Joe Orton * dav_basic.c (copy_or_move, dav_move, dav_copy): Pass overwrite as parameter. Sun Jul 16 15:26:24 2000 Joe Orton * uri.c (uri_compare): Fixed to only return equal if *shorter* string has no trailing slash. Sat Jul 15 20:14:07 2000 Joe Orton * dav_207.c (dav_207_get_current_response, dav_207_get_current_propstat): New functions. * dav_props.c (dav_propfind_get_current_resource): Implement using dav_207_get_current_response. Sat Jul 15 17:36:37 2000 Joe Orton * xalloc.c (xcalloc): New function. Sat Jul 15 14:11:14 2000 Joe Orton * http_utils.[ch] and elsewhere: Replace 'class' field of http_status with '_class' to be C++-safe. (patch from Tom Bednarz). Thu Jul 6 18:48:52 2000 Joe Orton * dav_basic.c (copy_or_move): Escape the destination URI. Thu Jul 6 18:45:51 2000 Joe Orton * dav_props.c (end_response): Added description parameter. Thu Jul 6 18:43:14 2000 Joe Orton * dav_207.[ch] (end_element): Fix handling of responsedescription. Add "description" parameter to dav_207_end_response callback, and pass the contents of responsedescription. * dav_basic.c (handle_error, end_response, end_propstat): Pass description and add to error string when present. Tue Jul 4 11:43:03 2000 Joe Orton * dav_basic.c, dav_props.c, http_basic.c: Use http_{add,print}_request_header rather than http_get_request_header. Tue Jul 4 11:41:00 2000 Joe Orton * http_request.[ch] (http_add_request_header, http_print_request_header): New functions. (http_get_request_header): Removed function. Mon Jul 3 21:50:40 2000 Joe Orton * http_request.c: Add basic support for TLS upgrade (RFC2817). (http_set_request_secure_upgrade, http_set_accept_secure_upgrade): New functions. (send_request): If upgrade is requested, and a 101 response is received, negotiate the TLS connection. (add_fixed_headers): Add Upgrade header if necessary. Mon Jul 3 21:46:00 2000 Joe Orton * http_request.c (send_request): Don't go into an infinite loop. (read_message_header): Simplyify checking for end-of-line. Tue Jun 13 00:29:42 2000 Joe Orton * http_request.c (http_session_proxy, http_session_server): Allow calling >1 time per session, to switch servers. (send_request): Only retry sending request once. Mon Jun 12 21:50:41 2000 Joe Orton * http_request.c (http_add_hooks): New function. Mon Jun 12 21:37:24 2000 Joe Orton * http_cookies.[ch]: Added basic cookies support. Mon Jun 12 21:33:33 2000 Joe Orton * socket.c (sock_create_ssl_context, sock_destroy_ssl_context, sock_disable_tlsv1, sock_disable_sslv2, sock_disable_sslv3, sock_make_secure): Added nssl_context handling. Mon Jun 12 21:29:52 2000 Joe Orton * http_request.c (http_request_dispatch, http_request_create, http_request_destroy, http_set_request_body_buffer, http_set_request_body_stream): Added hook support. Mon Jun 12 21:04:00 2000 Joe Orton * http_request.c (http_set_secure): Store an nssl_context. (open_connection): Give the nssl_context. Sun Jun 11 16:37:52 2000 Joe Orton * sslcerts.c: Import of SSL support from mutt, relicensed under the LGPL for use in neon by the author, Tommi Komulainen . Sun Jun 11 11:30:16 2000 Joe Orton * http_request.c (set_sockerr): Updated to use sock_get_error. Sun Jun 11 11:29:29 2000 Joe Orton * uri.c (uri_parse): Allow scheme to be omitted. Fri Jun 9 20:39:24 2000 Joe Orton * socket.c (sock_get_error): New function. (sock_*): Set sock->error and SOCK_ERROR on error. Mon May 29 16:32:46 2000 Joe Orton * uri.c (uri_abspath_escape): Allocate the exact amount of memory needed. Mon May 29 15:53:33 2000 Joe Orton * dav_basic.c (dav_simple_request): Correct invalid XML logic. Mon May 29 15:52:08 2000 Joe Orton * socket.c (create_sock, sock_accept, sock_get_fd): New functions. (sock_connect_u): Use create_sock. Sun May 28 21:00:37 2000 Joe Orton * http_utils.c (neon_version_string): New function. Sun May 28 19:36:45 2000 Joe Orton * socket.c (sock_connect_u): Zero out allocated nsocket object. Thu May 25 01:27:04 2000 Joe Orton * *.h: Include other neon headers with . Thu May 25 01:02:12 2000 Joe Orton * dav_props.c: Include stdlib.h for 'free'. Wed May 24 20:15:08 2000 Joe Orton * http_request.c (read_message_header): Return HTTP_RETRY if more headers to read, HTTP_OK on end-of-headers. (read_response_headers): Changed accordingly. Wed May 24 19:56:29 2000 Joe Orton * http_request.c (send_request_body): Return a SOCK_* code. (send_request): Re-send request if socket has been closed (due to persistent connection timeout). Wed May 24 19:00:01 2000 Joe Orton * hip_xml.c (find_element): Fix unknown element handling. Tue May 23 19:12:26 2000 Joe Orton * dav_props.c (propfind): Destroy the request body sbuffer after use. Tue May 23 15:43:42 2000 Joe Orton * socket.c (sock_make_secure) [SSL_ENABLE]: Conditionally compile SSL code. [!SSL_ENABLE]: Return failure. (sock_close) [SSL_ENABLE]: Conditionally compile SSL code. Tue May 23 15:37:53 2000 Joe Orton * http_request.c (http_session_create): Renamed from http_session_init. (http_session_destroy): Renamed frmo http_session_finish. Sun May 21 23:50:58 2000 Joe Orton * http_request.c (lookup_host): Use sock_name_lookup. Sun May 21 23:40:39 2000 Joe Orton * http_request.c (http_request_create): Allow passing NULL uri (internal use only). (http_set_secure): New function. (read_response_block, read_message_headers): Redone for new socket API. (build_request): Moved http_auth_new_request calls here (from http_request_dispatch). (send_request): Always call open_connection before sending the request. (read_message_header, read_response_headers): Looser check for empty line. (normalize_response_length): Set response body length to zero on 2xx class response whilst in CONNECT, if no other response body length is given. (http_request_dispatch): Don't close the connection on a HTTP/1.0 2xx class response after a CONNECT request. (proxy_tunnel): New function. (open_connection): Use an SSL connection where appropriate. Use proxy_tunnel for tunnelling through a proxy. Sun May 21 01:35:40 2000 Joe Orton * src/socket.c: Added 'nsocket' ADT for handling sockets. (sock_*): All changed to take 'nsocket *' argument rather than integer file descriptor. Added 'sock_secure_details' to sock_status enum. (sock_make_secure, sock_init): New function. (sock_peek): Renamed from sock_recv. (send_file_*, recv_file_*): Removed functions. (sock_name_lookup): Renamed from host_lookup. (sock_service_lookup): Renamed from get_tcp_port. (sock_block, sock_read, sock_fullwrite, sock_peek, sock_readline): Added SSL support. (sock_transfer): Use sock_fullwrite and sock_read. Sun May 21 01:25:03 2000 Joe Orton * http_request.c (http_request_destroy): Free header handlers and body readers. Sun May 21 01:24:30 2000 Joe Orton * dav_props.h: Removed obsolte got_property callback type. Sun May 21 01:23:59 2000 Joe Orton * dav_props.c (propfind): Free handler object after use. Sun May 21 01:23:12 2000 Joe Orton * dav_207.c (dav_207_destroy): Don't try to free the 'response' field. Sat May 20 21:45:32 2000 Joe Orton * http_request.c: Changed 'te' enum of struct http_response to 'is_chunked' boolean. Sun May 14 01:00:42 2000 Joe Orton * dav_props.c (propfind): Return error on parse error. Sun May 14 00:40:50 2000 Joe Orton * neon_config.h (NEON_VERSION): Bumped to 0.2.0. Sat May 13 23:31:28 2000 Joe Orton * neon_defs.h (BEGIN_NEON_DECLS, END_NEON_DECLS): Added C++ safety macros. * *.h: Surround with C++ safety macros. Sat May 13 22:36:06 2000 Joe Orton * hip_xml.c (hip_xml_destroy): Free handlers. Sat May 13 21:12:14 2000 Joe Orton * hip_xml.c (hip_xml_valid): Reversed return value. Sat May 13 21:11:17 2000 Joe Orton * http_utils.c: Renamed http_debug_mask to neon_debug_mask, similarly neon_debug_stream. (neon_debug_init): Renamed from http_debug_init. Sat May 13 19:24:40 2000 Joe Orton * http_utils.c: Initialize http_debug_mask to zero. (http_debug_init): New function. * http_utils.h: Fixed #ifdef DEBUGGING. Only define relevant DEBUG_* constants. Sat May 13 19:23:34 2000 Joe Orton * neon_config.h: New file. * http_request.c: Include neon_config.h for NEON_VERSION. Sat May 13 18:28:05 2000 Joe Orton * dav_props.c (dav_propfind_create): Create a hip_xml_parser, a 207 parser, register start+end response handlers with 207 layer. (propfind): Fix allprop (Michael Sobolev). * dav_basic.c (dav_simple_request): Create and destroy hip_xml_parser and 207 parser appropriately. Sat May 13 18:24:49 2000 Joe Orton * dav_207.c: Now takes an externally-declared hip_xml parser pointer. (dav_207_create, dav_207_destroy): New functions. (dav_207_init, dav_207_init_with_handler, dav_207_parse, dav_207_error, dav_207_finish): Removed functions. Sat May 13 17:32:45 2000 Joe Orton * hip_xml.[ch]: Rewritten to use opaque hip_xml_parser pointer. struct hip_xml_handler and struct hip_xml_state removed from external interface. struct hip_xml_elm * passed to startelm_cb and endelm_cb. (hip_xml_add_handler, hip_xml_valid, hip_xml_create, hip_xml_destroy, hip_xml_set_error, hip_xml_get_error): New functions. (hip_xml_init, hip_xml_destroy): Removed functions. Sat May 13 13:43:56 2000 Joe Orton * neon.h: Removed. Sat May 13 13:42:20 2000 Joe Orton * string_utils.h: Don't include config.h. (CONCAT*): Don't use xmalloc, use malloc and abort manually. Sat May 13 13:32:46 2000 Joe Orton * http_utils.h, dates.h, http_basic.h: Don't include config.h Sat May 13 13:31:37 2000 Joe Orton * hip_xml.[ch], dav_207.c: Use HIP_ERR_SIZE for size of parser error string. Sat May 13 13:30:40 2000 Joe Orton * Makefile.incl: Use obj_ext for object file extension. Thu May 11 18:21:53 2000 Joe Orton * neon.h: Bumped version to 0.1.1. Thu May 11 18:16:08 2000 Joe Orton * http_basic.c (get_to_fd): Fix short writes. Wed May 10 19:22:01 2000 Joe Orton * neon.h: Bumped version to 0.1.0. Wed May 10 17:46:48 2000 Joe Orton * uri.c (uri_parse, uri_free): New functions. Wed May 10 17:43:37 2000 Joe Orton * http_basic.c (get_to_fd, http_get): Set error appropriately if fwrite() fails. Wed May 10 14:25:38 2000 Joe Orton * http_utils.c (http_debug): New function. Wed May 10 14:25:08 2000 Joe Orton * http_basic.c (get_callback): Call sock_call_progress. Wed May 10 14:24:20 2000 Joe Orton * socket.c (sock_call_progress): New function. (many places): Use it. Wed May 10 14:22:48 2000 Joe Orton * uri.c (uri_has_trailing_slash): Moved from being inline. Tue May 9 23:34:25 2000 Joe Orton * dav_props.c: Use handler as userdata for 207 callbacks, unified handler and context structures. (start_prop, end_prop, start_propelm, end_propelm): Removed functions. (dav_propfind_get_current_resource): New function. Tue May 9 23:29:44 2000 Joe Orton * xalloc.[ch]: New files. Tue May 9 23:05:47 2000 Joe Orton * dav_207.[ch]: Removed property and property element callbacks. Tue May 9 23:01:00 2000 Joe Orton * dav_207.c: Use separate name/namespace for element names. (dav_207_init_with_handler): New function. (end_element): Unescape URI in href element. Tue May 9 19:54:07 2000 Joe Orton * dav_props.c (dav_propfind_allprop, dav_propfind_named, propfind, start_response, end_response, start_prop, end_prop, start_propelm, end_propelm): New functions; PROPFIND support. Tue May 9 19:45:17 2000 Joe Orton * http_request.c (build_request): Renamed from make_request. Tue May 9 19:36:01 2000 Joe Orton * socket.[ch]: Added sock_block_reader. Tue May 9 15:52:56 2000 Joe Orton * uri.c (uri_childof): Return false when parent is the same length as child. Sun May 7 15:07:49 2000 Joe Orton * dav_207.c: Separated element namespace/names. Tue May 2 16:40:59 2000 Joe Orton * hip_xml.[ch]: Added HIP_XML_UTF8DECODE flag. Tue May 2 16:16:57 2000 Joe Orton * hip_xml.[ch]: Separate element name and namespace. Mon May 1 00:21:24 2000 Joe Orton * dav_207.c (dav_accept_207): Moved function from dav_basic.c. * dav_basic.c (dav_accept_207, dav_parse_xml_block): Removed functions. Sun Apr 30 22:47:47 2000 Joe Orton * dav_props.[ch]: Renamed dav_proppatch_item to dav_proppatch_operation. Sun Apr 30 22:45:04 2000 Joe Orton * hip_xml.c (start_element): Clearer error message. Sun Apr 30 19:12:07 2000 Joe Orton * http_basic.c (http_content_type_handler, dav_hdr_handler): New functions. (http_options): Handle DAV header. Sun Apr 30 18:08:53 2000 Joe Orton * dav_props.c (dav_proppatch): New function. Sun Apr 30 18:05:55 2000 Joe Orton * dav_basic.c (handle_error): New function. (end_response, end_propstat): Use it. (dav_simple_request): Don't return the 207 error string if we get all 2xx class status elements. Sun Apr 30 16:56:41 2000 Joe Orton * dav_basic.c (dav_add_depth_header): New function. Sun Apr 30 14:49:06 2000 Joe Orton * dav_207.c (start_element): Unknown element is only a property if the parent is DAV:propstat. Sun Apr 30 14:43:28 2000 Joe Orton * dav_basic.c (end_response, end_propstat): Only write error line if we have status information and the status is not a 424. Sun Apr 30 14:28:23 2000 Joe Orton * dav_basic.h: Added DAV_DEPTH_*. Sun Apr 30 12:47:50 2000 Joe Orton * dav_207.c (check_context): Allow (and ignore) unknown elements anywhere other than as the root. Sun Apr 30 12:35:39 2000 Joe Orton * string_utils.h (ASC2HEX, HEX2ASC): New macros. Sun Apr 30 12:34:37 2000 Joe Orton * http_auth.c [STANDALONE]: Removed. (everywhere): Switch to using md5_to_ascii rather than md5_hexify. Sun Apr 30 12:32:35 2000 Joe Orton * http_request.c (read_response_block): Fixed to return errors properly and block length to parameter. (read_response_body): Changed accordingly. Sun Apr 30 12:29:45 2000 Joe Orton * hip_xml.c (friendly_name): New function, was PRETTY_NAME macro. (start_element, end_element): Fix COLLECT handling. (hip_xml_parse): Only write parse error if the document has not already been marked invalid. Sun Apr 30 12:28:36 2000 Joe Orton * dav_basic.c (dav_simple_request): Rewritten for new 207 interface. (start_response, end_response, end_propstat): New functions. Sun Apr 30 12:27:52 2000 Joe Orton * dav_207.c (dav_207_error): Return the parser error. Sat Apr 29 14:46:48 2000 Joe Orton * socket.c (sock_register_progress, sock_register_notify): New functions. (everywhere): Use progress + notify callbacks rather than fe_*. Sat Apr 29 14:15:23 2000 Joe Orton * string_utils.c (md5_to_ascii, ascii_to_md5): New functions. Sat Apr 29 13:55:39 2000 Joe Orton * hip_xml.c (hip_xml_init): abort() on out-of-memory. Sat Apr 29 12:56:11 2000 Joe Orton * neon_i18n.h: New file. Sat Apr 29 12:55:24 2000 Joe Orton * dav_207.[ch]: Re-implemented with sensible interface. Fri Apr 28 14:56:01 2000 Joe Orton * http_auth.c (http_auth_request_header): Renamed from http_auth_request. * http_request.c (make_request): As above. Thu Apr 13 11:52:14 2000 Joe Orton * http_basic.c (http_put): Switched URI and stream arguments. Thu Apr 13 09:51:21 2000 Joe Orton * http_request.c: Added user_agent field to session structure. (http_set_useragent): New function. (add_fixed_headers): Only set user-agent if sess->user_agent is set. Thu Apr 13 09:49:32 2000 Joe Orton * http_request.c (lookup_host): New function, split from set_hostinfo. (set_hostinfo): Doesn't perform DNS lookup. (http_session_server): Don't do a DNS lookup if we have a proxy. Wed Apr 12 22:32:21 2000 Joe Orton * http_request.c (http_request_dispatch, http_request_create): Store auth header values in local variables rather than request structure. (http_request_create): Don't leak everything on error. Handle http_auth_challenge return value. Wed Apr 12 22:30:06 2000 Joe Orton * http_basic.c (http_options): Pass server capabilites object, parse Server header to detect Apache/1.3.6 and before, indicating broken 100-continue support. (server_hdr_handler): New function. Mon Apr 10 17:42:07 2000 Joe Orton * socket.c: Use 'int' for return values. Mon Apr 10 17:41:40 2000 Joe Orton * http_auth.c (is_in_domain): Dummy implementation. Mon Apr 10 17:40:21 2000 Joe Orton * http_request.c: Handle read() returning 0 when it shouldn't. i18n'ized error messages. Mon Apr 10 14:45:09 2000 Joe Orton * dates.[ch], md5.[ch], base64.[ch]: Imported date handling utilities, MD5 checksum functions, and text->base64 converter. Mon Apr 10 14:44:08 2000 Joe Orton * Makefile.incl: Dependancies updated for socket.[ch]. Mon Apr 10 14:43:36 2000 Joe Orton * dav_207.c: Replaced malloc() calls with xmalloc() calls. Mon Apr 10 14:42:35 2000 Joe Orton * http_auth.c, uri.c, string_utils.h: Replaced malloc() calls with xmalloc() calls. Mon Apr 10 14:41:40 2000 Joe Orton * socket.[ch]: Imported socket handling utilities. Mon Apr 10 14:36:03 2000 Joe Orton * string_utils.h (CONCAT*): Use xmalloc. Mon Apr 10 13:52:17 2000 Joe Orton * http_request.c (set_sockerr): Added handling for socket errors. Sat Apr 8 13:49:07 2000 Joe Orton * string_utils.[ch]: Imported string utilites. Sat Apr 8 00:26:06 2000 Joe Orton * http_request.c (http_set_persist, http_set_expect100): New functions. Sat Apr 8 00:25:37 2000 Joe Orton * http_basic.c (http_options): New function. Fri Apr 7 13:01:35 2000 Joe Orton * neon.h: New file. Fri Apr 7 12:59:40 2000 Joe Orton * http_request.c (normalize_response_length, read_response_body): New functions. (http_add_response_body_reader): Take a callback to determine whether the body reader wants to read the response body. Fri Apr 7 11:46:41 2000 Joe Orton * http_request.c (http_set_server_auth, http_set_proxy_auth): New functions. (give_creds): Use supplied callbacks for authentication. (get_request_bodysize): Send Content-Length: 0 if no entity-body is being sent with a request. (te_hdr_handler, connection_hdr_handler): New functions. (make_request): Don't use Expect: 100-continue if server is not HTTP/1.1 compliant. (read_message_header): Only read until HTTP_MAXIMUM_HEADER_LENGTH bytes of header have been read. (read_response_headers): No hard-coded header handling. (http_request_create): Set req->method_is_head here. Thu Apr 6 14:39:28 2000 Joe Orton * hip_xml.c [HIP_XML_DECODE_UTF8] (decode_utf8_double): New function. (char_data) [HIP_XML_DECODE_UTF8]: Decode UTF-8. Tue Mar 28 13:54:51 2000 Joe Orton * Makefile.incl: Imported makefile fragment. Tue Mar 28 13:54:09 2000 Joe Orton * http_request.[ch] (http_get_error): New function. Thu Mar 23 18:48:42 2000 Joe Orton * hip_xml.[ch]: Imported generic XML parsing layer. * dav_207.[ch]: Imported generic WebDAV 207 response handling. * dav_basic.[ch]: Imported/implemented DAV response handling and basic Class 1 namespace methods. Thu Mar 23 18:46:14 2000 Joe Orton * http_request.c (add_hooks, run_hooks, http_add_destroy_hook): Adding hooks support. (add_fixed_headers): Send TE token in Connection header. Only send Keep-Alive header & token to pre-1.1 origin servers (i.e., not proxies). Thu Mar 23 12:49:01 2000 Joe Orton * http_auth.[ch], uri.[ch]: Imported HTTP authentication and URI handling modules. Thu Mar 23 12:47:05 2000 Joe Orton * http_utils.c: Imported HTTP utility functions. Thu Mar 23 12:44:38 2000 Joe Orton * http_request.[ch]: Implemented modular HTTP request handling. * http_basic.[ch]: Implemented basic HTTP methods GET, PUT, and PUT with If-Unmodified. davix-R_0_5_0/deps/libneon/src/Makefile.in000066400000000000000000000162161257152637300205100ustar00rootroot00000000000000# # neon source directory Makefile # # Use the NEON_NORMAL_BUILD or NEON_LIBTOOL_BUILD autoconf # macros to set up this Makefile correctly. # SHELL = @SHELL@ # Installation paths prefix = @prefix@ exec_prefix = @exec_prefix@ libdir = @libdir@ # Build paths VPATH = @srcdir@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # Toolchain settings. CC = @CC@ AR = @AR@ RANLIB = @RANLIB@ LIBTOOL = @LIBTOOL@ # Flags CPPFLAGS = @DEFS@ @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ NEON_LINK_FLAGS = @NEON_LINK_FLAGS@ # Note: don't substitute @LIBS@ in here; during a bundled # build of this directory, @LIBS@ may include -lneon. LIBS = @NEON_LIBS@ @NEON_LTLIBS@ COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) LT_COMPILE = $(LIBTOOL) --quiet --mode=compile $(COMPILE) LINK = $(LIBTOOL) --quiet --mode=link $(CC) -no-undefined $(LDFLAGS) NEON_BASEOBJS = ne_request.@NEON_OBJEXT@ ne_session.@NEON_OBJEXT@ \ ne_basic.@NEON_OBJEXT@ ne_string.@NEON_OBJEXT@ \ ne_uri.@NEON_OBJEXT@ ne_dates.@NEON_OBJEXT@ \ ne_alloc.@NEON_OBJEXT@ ne_md5.@NEON_OBJEXT@ \ ne_utils.@NEON_OBJEXT@ ne_socket.@NEON_OBJEXT@ \ ne_auth.@NEON_OBJEXT@ ne_redirect.@NEON_OBJEXT@ \ ne_compress.@NEON_OBJEXT@ ne_i18n.@NEON_OBJEXT@ \ ne_pkcs11.@NEON_OBJEXT@ ne_socks.@NEON_OBJEXT@ \ ne_ntlm.@NEON_OBJEXT@ NEON_DAVOBJS = $(NEON_BASEOBJS) \ ne_207.@NEON_OBJEXT@ ne_xml.@NEON_OBJEXT@ \ ne_props.@NEON_OBJEXT@ ne_locks.@NEON_OBJEXT@ \ ne_xmlreq.@NEON_OBJEXT@ OBJECTS = @NEONOBJS@ @NEON_EXTRAOBJS@ .SUFFIXES: .SUFFIXES: .c .lo .o NEON_TARGET = @NEON_TARGET@ # Thanks to gettext for this neat trick. all: all-@NEON_BUILD_BUNDLED@ all-yes: $(NEON_TARGET) all-no: @echo "Bundled neon build not being used." .c.lo: $(LT_COMPILE) -c $< -o $@ .c.o: $(COMPILE) -c $< -o $@ libneon.la: $(OBJECTS) $(LINK) -rpath $(libdir) $(NEON_LINK_FLAGS) -o $@ $(OBJECTS) $(LIBS) libneon.a: $(OBJECTS) @rm -f $@ $(AR) cru $@ $(OBJECTS) $(RANLIB) $@ clean: rm -f $(NEON_TARGET) *.o *.lo *.bbg *.bb *.gc* rm -rf .libs c++.c: find . -name ne_\*.h -print | sed 's/.*/#include "&"/;/ne_priv/d' > $@ echo "int main(void) {}" >> $@ check-c++: c++.c c++ -I. c++.c check-incl: @for f in ne_*.h; do \ echo Checking $$f...; \ echo "#include \"$$f\"" > checkincl.c; \ $(COMPILE) -c checkincl.c -o checkincl.o || exit 1; done # Update generated dependencies below; requires cc -MM as in gcc. update-deps: for f in `echo $(OBJECTS) | sed 's/\\.@NEON_OBJEXT@/.c/g;s/ne_openssl.c//;s/ne_gnutls.c//;s/ne_pkcs11.c//;s/ne_stubssl.c//'`; do \ $(CC) $(CPPFLAGS) -MM -c $$f; \ done | sed 's, \.\./, $$(top_builddir)/,g;s, /[^ ]*.h,,g;/^ .$$/d;s/\.o: /.@NEON''_OBJEXT@: /' > new-deps sed '/[-]--CUT---/q' Makefile.in > Makefile.new cat Makefile.new new-deps > Makefile.in rm new-deps Makefile.new ne_openssl.@NEON_OBJEXT@: ne_openssl.c $(top_builddir)/config.h ne_ssl.h ne_defs.h ne_string.h \ ne_alloc.h ne_session.h ne_uri.h ne_socket.h ne_internal.h ne_private.h \ ne_request.h ne_utils.h ne_pkcs11.h ne_privssl.h ne_stubssl.@NEON_OBJEXT@: ne_stubssl.c $(top_builddir)/config.h ne_ssl.h ne_defs.h ne_session.h \ ne_uri.h ne_socket.h ne_pkcs11.@NEON_OBJEXT@: ne_pkcs11.c $(top_builddir)/config.h ne_pkcs11.h ne_defs.h ne_session.h \ ne_ssl.h ne_uri.h ne_socket.h ne_internal.h ne_privssl.h \ ne_alloc.h ne_private.h ne_request.h ne_utils.h ne_string.h ne_gnutls.@NEON_OBJEXT@: ne_gnutls.c $(top_builddir)/config.h ne_ssl.h ne_defs.h \ ne_string.h ne_alloc.h ne_session.h ne_uri.h ne_socket.h ne_internal.h \ ne_private.h ne_request.h ne_utils.h ne_privssl.h #### ---CUT--- DO NOT REMOVE THIS LINE. Generated dependencies follow. #### ne_request.@NEON_OBJEXT@: ne_request.c $(top_builddir)/config.h ne_internal.h ne_defs.h ne_alloc.h \ ne_request.h ne_utils.h ne_string.h ne_session.h ne_ssl.h ne_uri.h \ ne_socket.h ne_private.h ne_session.@NEON_OBJEXT@: ne_session.c $(top_builddir)/config.h ne_session.h ne_ssl.h ne_defs.h \ ne_uri.h ne_socket.h ne_alloc.h ne_utils.h ne_internal.h ne_string.h \ ne_dates.h ne_private.h ne_request.h ne_basic.@NEON_OBJEXT@: ne_basic.c $(top_builddir)/config.h ne_request.h ne_utils.h ne_defs.h \ ne_string.h ne_alloc.h ne_session.h ne_ssl.h ne_uri.h ne_socket.h \ ne_basic.h ne_207.h ne_xml.h ne_locks.h ne_dates.h ne_internal.h ne_string.@NEON_OBJEXT@: ne_string.c $(top_builddir)/config.h ne_alloc.h ne_defs.h ne_string.h ne_uri.@NEON_OBJEXT@: ne_uri.c $(top_builddir)/config.h ne_string.h ne_defs.h ne_alloc.h ne_uri.h ne_dates.@NEON_OBJEXT@: ne_dates.c $(top_builddir)/config.h ne_alloc.h ne_defs.h ne_dates.h \ ne_string.h ne_alloc.@NEON_OBJEXT@: ne_alloc.c $(top_builddir)/config.h ne_alloc.h ne_defs.h ne_md5.@NEON_OBJEXT@: ne_md5.c $(top_builddir)/config.h ne_md5.h ne_defs.h ne_string.h ne_alloc.h ne_utils.@NEON_OBJEXT@: ne_utils.c $(top_builddir)/config.h ne_utils.h ne_defs.h ne_string.h \ ne_alloc.h ne_dates.h ne_socket.@NEON_OBJEXT@: ne_socket.c $(top_builddir)/config.h ne_privssl.h ne_ssl.h ne_defs.h \ ne_socket.h ne_internal.h ne_utils.h ne_string.h ne_alloc.h ne_sspi.h ne_auth.@NEON_OBJEXT@: ne_auth.c $(top_builddir)/config.h ne_md5.h ne_defs.h ne_dates.h \ ne_request.h ne_utils.h ne_string.h ne_alloc.h ne_session.h ne_ssl.h \ ne_uri.h ne_socket.h ne_auth.h ne_internal.h ne_redirect.@NEON_OBJEXT@: ne_redirect.c $(top_builddir)/config.h ne_session.h ne_ssl.h ne_defs.h \ ne_uri.h ne_socket.h ne_request.h ne_utils.h ne_string.h ne_alloc.h \ ne_redirect.h ne_internal.h ne_compress.@NEON_OBJEXT@: ne_compress.c $(top_builddir)/config.h ne_request.h ne_utils.h \ ne_defs.h ne_string.h ne_alloc.h ne_session.h ne_ssl.h ne_uri.h \ ne_socket.h ne_compress.h ne_internal.h ne_i18n.@NEON_OBJEXT@: ne_i18n.c $(top_builddir)/config.h ne_i18n.h ne_defs.h ne_socks.@NEON_OBJEXT@: ne_socks.c $(top_builddir)/config.h ne_internal.h ne_defs.h ne_string.h \ ne_alloc.h ne_socket.h ne_ssl.h ne_utils.h ne_207.@NEON_OBJEXT@: ne_207.c $(top_builddir)/config.h ne_alloc.h ne_defs.h ne_utils.h ne_xml.h \ ne_207.h ne_request.h ne_string.h ne_session.h ne_ssl.h ne_uri.h \ ne_socket.h ne_basic.h ne_internal.h ne_xml.@NEON_OBJEXT@: ne_xml.c $(top_builddir)/config.h ne_internal.h ne_defs.h ne_alloc.h \ ne_xml.h ne_utils.h ne_string.h ne_props.@NEON_OBJEXT@: ne_props.c $(top_builddir)/config.h ne_alloc.h ne_defs.h ne_xml.h \ ne_props.h ne_request.h ne_utils.h ne_string.h ne_session.h ne_ssl.h \ ne_uri.h ne_socket.h ne_207.h ne_basic.h ne_locks.h ne_internal.h ne_locks.@NEON_OBJEXT@: ne_locks.c $(top_builddir)/config.h ne_alloc.h ne_defs.h ne_request.h \ ne_utils.h ne_string.h ne_session.h ne_ssl.h ne_uri.h ne_socket.h \ ne_xml.h ne_locks.h ne_basic.h ne_props.h ne_207.h ne_internal.h \ ne_xmlreq.h ne_xmlreq.@NEON_OBJEXT@: ne_xmlreq.c $(top_builddir)/config.h ne_internal.h ne_defs.h ne_xmlreq.h \ ne_request.h ne_utils.h ne_string.h ne_alloc.h ne_session.h ne_ssl.h \ ne_uri.h ne_socket.h ne_xml.h ne_basic.h ne_oldacl.@NEON_OBJEXT@: ne_oldacl.c $(top_builddir)/config.h ne_request.h ne_utils.h ne_defs.h \ ne_string.h ne_alloc.h ne_session.h ne_ssl.h ne_uri.h ne_socket.h \ ne_locks.h ne_acl.h ne_xml.h ne_acl3744.@NEON_OBJEXT@: ne_acl3744.c $(top_builddir)/config.h ne_request.h ne_utils.h ne_defs.h \ ne_string.h ne_alloc.h ne_session.h ne_ssl.h ne_uri.h ne_socket.h \ ne_locks.h ne_acl.h ne_xml.h davix-R_0_5_0/deps/libneon/src/README000066400000000000000000000007201257152637300173140ustar00rootroot00000000000000 This is the source directory of the 'neon' HTTP/WebDAV client library, which can be bundled inside other packages. For the complete neon package, see: http://www.webdav.org/neon/ This source directory may be distributed and/or modified under the terms of the GNU Library General Public License, as given in COPYING.LIB. Please send questions, bug reports, feature requests, etc, regarding the neon library, to the mailing list at: neon@lists.manyfish.co.uk davix-R_0_5_0/deps/libneon/src/davix_logger_c.h000066400000000000000000000044651257152637300215730ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_LOGGER_C_H #define DAVIX_LOGGER_C_H // log level #define DAVIX_LOG_CRITICAL 1 #define DAVIX_LOG_WARNING 2 #define DAVIX_LOG_VERBOSE 3 #define DAVIX_LOG_DEBUG 4 #define DAVIX_LOG_TRACE 5 #define DAVIX_LOG_ALL 6 // log scope #define DAVIX_LOG_FILE (1<<0) #define DAVIX_LOG_POSIX (1<<1) #define DAVIX_LOG_XML (1<<2) #define DAVIX_LOG_SSL (1<<3) #define DAVIX_LOG_HEADER (1<<4) #define DAVIX_LOG_BODY (1<<5) #define DAVIX_LOG_CHAIN (1<<6) #define DAVIX_LOG_CORE (1<<7) #define DAVIX_LOG_GRID (1<<8) #define DAVIX_LOG_SOCKET (1<<9) #define DAVIX_LOG_LOCKS (1<<10) #define DAVIX_LOG_HTTP (1<<11) #define DAVIX_LOG_SCOPE_NEON (1<<29) #define DAVIX_LOG_SCOPE_ALL (~(0) ^ DAVIX_LOG_BODY) /* set the davix log mask */ /* everything that is not coverred by the mask is dropped */ void davix_set_log_level(int log_mask); /* get current log mask */ int davix_get_log_level(); void davix_vlogger2(int log_mask, int log_level, const char* msg, va_list args); int davix_get_log_scope(); /* @brief setup a log handler redirect the davix log output to the function f_handler setting up a log handler disable the std output log @param fhandler : log handler callback @param userdata : callback userdata */ void davix_set_log_handler( void (*fhandler)(void* userdata, int mgs_level, const char* msg), void* userdata); #endif /* DAVIX_LOGGER_C_H */ davix-R_0_5_0/deps/libneon/src/memleak.h000066400000000000000000000041001257152637300202140ustar00rootroot00000000000000/* Memory leak wrappers Copyright (C) 2003, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* WARNING: THIS IS AN INTERNAL NEON INTERFACE AND MUST NOT BE USED * from NEON APPLICATIONS. */ /* This file contains an alternate interface to the memory allocation * wrappers in ne_alloc.c, which perform simple leak detection. It * MUST NOT BE INSTALLED, or used from neon applications. */ #ifndef MEMLEAK_H #define MEMLEAK_H #include #define ne_malloc(s) ne_malloc_ml(s, __FILE__, __LINE__) #define ne_calloc(s) ne_calloc_ml(s, __FILE__, __LINE__) #define ne_realloc(p, s) ne_realloc_ml(p, s, __FILE__, __LINE__) #define ne_strdup(s) ne_strdup_ml(s, __FILE__, __LINE__) #define ne_strndup(s, n) ne_strndup_ml(s, n, __FILE__, __LINE__) #define ne_free ne_free_ml /* Prototypes of allocation functions: */ void *ne_malloc_ml(size_t size, const char *file, int line); void *ne_calloc_ml(size_t size, const char *file, int line); void *ne_realloc_ml(void *ptr, size_t s, const char *file, int line); char *ne_strdup_ml(const char *s, const char *file, int line); char *ne_strndup_ml(const char *s, size_t n, const char *file, int line); void ne_free_ml(void *ptr); /* Dump the list of currently allocated blocks to 'f'. */ void ne_alloc_dump(FILE *f); /* Current number of bytes in allocated but not free'd. */ extern size_t ne_alloc_used; #endif /* MEMLEAK_H */ davix-R_0_5_0/deps/libneon/src/ne_207.c000066400000000000000000000247151257152637300176040ustar00rootroot00000000000000/* WebDAV 207 multi-status response handling Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Generic handling for WebDAV 207 Multi-Status responses. */ #include "config.h" #ifdef HAVE_STDLIB_H #include #endif #include "ne_alloc.h" #include "ne_utils.h" #include "ne_xml.h" #include "ne_207.h" #include "ne_uri.h" #include "ne_basic.h" #include "ne_internal.h" struct ne_207_parser_s { ne_207_start_response *start_response; ne_207_end_response *end_response; ne_207_start_propstat *start_propstat; ne_207_end_propstat *end_propstat; ne_xml_parser *parser; void *userdata; ne_uri base; ne_buffer *cdata; /* remember whether we are in a response: the validation * doesn't encapsulate this since we only count as being * "in a response" when we've seen the href element. */ int in_response; /* current position */ void *response, *propstat; /* caching */ ne_status status; char *description, *href; }; #define ELM_multistatus 1 #define ELM_response 2 #define ELM_responsedescription 3 #define ELM_href 4 #define ELM_prop (NE_207_STATE_PROP) #define ELM_status 6 #define ELM_propstat 7 static const struct ne_xml_idmap map207[] = { { "DAV:", "multistatus", ELM_multistatus }, { "DAV:", "response", ELM_response }, { "DAV:", "responsedescription", ELM_responsedescription }, { "DAV:", "href", ELM_href }, { "DAV:", "propstat", ELM_propstat }, { "DAV:", "prop", ELM_prop }, { "DAV:", "status", ELM_status } }; /* Set the callbacks for the parser */ void ne_207_set_response_handlers(ne_207_parser *p, ne_207_start_response *start, ne_207_end_response *end) { p->start_response = start; p->end_response = end; } void ne_207_set_propstat_handlers(ne_207_parser *p, ne_207_start_propstat *start, ne_207_end_propstat *end) { p->start_propstat = start; p->end_propstat = end; } void *ne_207_get_current_response(ne_207_parser *p) { return p->response; } void *ne_207_get_current_propstat(ne_207_parser *p) { return p->propstat; } /* return non-zero if (child, parent) is an interesting element */ static int can_handle(int parent, int child) { return (parent == 0 && child == ELM_multistatus) || (parent == ELM_multistatus && child == ELM_response) || (parent == ELM_response && (child == ELM_href || child == ELM_status || child == ELM_propstat || child == ELM_responsedescription)) || (parent == ELM_propstat && (child == ELM_prop || child == ELM_status || child == ELM_responsedescription)); } static int cdata_207(void *userdata, int state, const char *buf, size_t len) { ne_207_parser *p = userdata; if ((state == ELM_href || state == ELM_responsedescription || state == ELM_status) && p->cdata->used + len < 2048) ne_buffer_append(p->cdata, buf, len); return 0; } static int start_element(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { ne_207_parser *p = userdata; int state = ne_xml_mapid(map207, NE_XML_MAPLEN(map207), nspace, name); if (!can_handle(parent, state)) return NE_XML_DECLINE; /* if not in a response, ignore everything. */ if (!p->in_response && state != ELM_response && state != ELM_multistatus && state != ELM_href) return NE_XML_DECLINE; if (state == ELM_propstat && p->start_propstat) { p->propstat = p->start_propstat(p->userdata, p->response); if (p->propstat == NULL) { return NE_XML_ABORT; } } ne_buffer_clear(p->cdata); return state; } #define GIVE_STATUS(p) ((p)->status.reason_phrase?&(p)->status:NULL) #define HAVE_CDATA(p) ((p)->cdata->used > 1) static int end_element(void *userdata, int state, const char *nspace, const char *name) { ne_207_parser *p = userdata; const char *cdata = ne_shave(p->cdata->data, "\r\n\t "); switch (state) { case ELM_responsedescription: if (HAVE_CDATA(p)) { if (p->description) ne_free(p->description); p->description = ne_strdup(cdata); } break; case ELM_href: /* Now we have the href, begin the response */ if (p->start_response && HAVE_CDATA(p)) { ne_uri ref, resolved; if (ne_uri_parse(cdata, &ref) == 0) { ne_uri_resolve(&p->base, &ref, &resolved); p->response = p->start_response(p->userdata, &resolved); p->in_response = 1; ne_uri_free(&resolved); } ne_uri_free(&ref); } break; case ELM_status: if (HAVE_CDATA(p)) { if (p->status.reason_phrase) ne_free(p->status.reason_phrase); if (ne_parse_statusline(cdata, &p->status)) { char buf[500]; NE_DEBUG(NE_DBG_HTTP, "Status line: %s", cdata); ne_snprintf(buf, 500, _("Invalid HTTP status line in status element " "at line %d of response:\nStatus line was: %s"), ne_xml_currentline(p->parser), cdata); ne_xml_set_error(p->parser, buf); return -1; } else { NE_DEBUG(NE_DBG_XML, "Decoded status line: %s", cdata); } } break; case ELM_propstat: if (p->end_propstat) p->end_propstat(p->userdata, p->propstat, GIVE_STATUS(p), p->description); p->propstat = NULL; if (p->description) ne_free(p->description); if (p->status.reason_phrase) ne_free(p->status.reason_phrase); p->description = p->status.reason_phrase = NULL; break; case ELM_response: if (!p->in_response) break; if (p->end_response) p->end_response(p->userdata, p->response, GIVE_STATUS(p), p->description); p->response = NULL; p->in_response = 0; if (p->description) ne_free(p->description); if (p->status.reason_phrase) ne_free(p->status.reason_phrase); p->description = p->status.reason_phrase = NULL; break; } return 0; } ne_207_parser *ne_207_create(ne_xml_parser *parser, const ne_uri *base, void *userdata) { ne_207_parser *p = ne_calloc(sizeof *p); p->parser = parser; p->userdata = userdata; p->cdata = ne_buffer_create(); ne_uri_copy(&p->base, base); /* Add handler for the standard 207 elements */ ne_xml_push_handler(parser, start_element, cdata_207, end_element, p); return p; } void ne_207_destroy(ne_207_parser *p) { if (p->status.reason_phrase) ne_free(p->status.reason_phrase); ne_buffer_destroy(p->cdata); ne_uri_free(&p->base); ne_free(p); } int ne_accept_207(void *userdata, ne_request *req, const ne_status *status) { return (status->code == 207); } /* Handling of 207 errors: we keep a string buffer, and append * messages to it as they come down. * * Note, 424 means it would have worked but something else went wrong. * We will have had the error for "something else", so we display * that, and skip 424 errors. */ /* This is passed as userdata to the 207 code. */ struct context { char *href; ne_buffer *buf; unsigned int is_error; }; static void *start_response(void *userdata, const ne_uri *uri) { struct context *ctx = userdata; if (ctx->href) ne_free(ctx->href); ctx->href = ne_uri_unparse(uri); return NULL; } static void handle_error(struct context *ctx, const ne_status *status, const char *description) { if (status && status->klass != 2 && status->code != 424) { char buf[50]; ctx->is_error = 1; sprintf(buf, "%d", status->code); ne_buffer_concat(ctx->buf, ctx->href, ": ", buf, " ", status->reason_phrase, "\n", NULL); if (description != NULL) { /* TODO: these can be multi-line. Would be good to * word-wrap this at col 80. */ ne_buffer_concat(ctx->buf, " -> ", description, "\n", NULL); } } } static void end_response(void *userdata, void *response, const ne_status *status, const char *description) { struct context *ctx = userdata; handle_error(ctx, status, description); } static void end_propstat(void *userdata, void *propstat, const ne_status *status, const char *description) { struct context *ctx = userdata; handle_error(ctx, status, description); } /* Dispatch a DAV request and handle a 207 error response appropriately */ /* TODO: hook up Content-Type parsing; passing charset to XML parser */ int ne_simple_request(ne_session *sess, ne_request *req) { int ret; struct context ctx = {0}; ne_207_parser *p207; ne_xml_parser *p = ne_xml_create(); ne_uri base = {0}; /* Mock up a base URI; it should really be retrieved from the * request object. */ ne_fill_server_uri(sess, &base); base.path = ne_strdup("/"); p207 = ne_207_create(p, &base, &ctx); ne_uri_free(&base); /* The error string is progressively written into the * ne_buffer by the element callbacks */ ctx.buf = ne_buffer_create(); ne_207_set_response_handlers(p207, start_response, end_response); ne_207_set_propstat_handlers(p207, NULL, end_propstat); ne_add_response_body_reader(req, ne_accept_207, ne_xml_parse_v, p); ret = ne_request_dispatch(req); if (ret == NE_OK) { if (ne_get_status(req)->code == 207) { if (ne_xml_failed(p)) { /* The parse was invalid */ ne_set_error(sess, "%s", ne_xml_get_error(p)); ret = NE_ERROR; } else if (ctx.is_error) { /* If we've actually got any error information * from the 207, then set that as the error */ ne_set_error(sess, "%s", ctx.buf->data); ret = NE_ERROR; } } else if (ne_get_status(req)->klass != 2) { ret = NE_ERROR; } } ne_207_destroy(p207); ne_xml_destroy(p); ne_buffer_destroy(ctx.buf); if (ctx.href) ne_free(ctx.href); ne_request_destroy(req); return ret; } davix-R_0_5_0/deps/libneon/src/ne_207.h000066400000000000000000000105021257152637300175760ustar00rootroot00000000000000/* WebDAV 207 multi-status response handling Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_207_H #define NE_207_H #include "ne_xml.h" #include "ne_request.h" /* for ne_request */ #include "ne_uri.h" /* for ne_uri */ NE_BEGIN_DECLS /* The defined state integer for the '{DAV:}prop' element. */ #define NE_207_STATE_PROP (50) /* This interface reserves the state integers 'x' where 0 < x < 100 */ #define NE_207_STATE_TOP (100) /* Handling of 207 multistatus XML documents. A "multistatus" * document is made up of a set of responses, each concerned with a * particular resource. Each response may have an associated result * status and failure description. A response is made up of a set of * propstats, each of which again may have an associated result status * and failure description. */ /* Start and end response callbacks trigger at the start and end of * each "response" within the multistatus body. 'uri' gives the URI * of the resource which is subject of this response. The return * value of a 'start_response' callback is passed as the 'response' * parameter to the corresponding 'end_response' parameter. */ typedef void *ne_207_start_response(void *userdata, const ne_uri *uri); typedef void ne_207_end_response(void *userdata, void *response, const ne_status *status, const char *description); /* Similarly, start and end callbacks for each propstat within the * response. The return value of the 'start_response' callback for * the response in which this propstat is contains is passed as the * 'response' parameter. The return value of each 'start_propstat' is * passed as the 'propstat' parameter' to the corresponding * 'end_propstat' callback. If the start_propstat callback returns * NULL, parsing is aborted (the XML parser error must be set by the * callback). */ typedef void *ne_207_start_propstat(void *userdata, void *response); typedef void ne_207_end_propstat(void *userdata, void *propstat, const ne_status *status, const char *description); typedef struct ne_207_parser_s ne_207_parser; /* Create 207 parser an add the handlers the the given parser's * handler stack. URI references in the 207 response will be resolved * relative to the base URI 'base'. */ ne_207_parser *ne_207_create(ne_xml_parser *parser, const ne_uri *base, void *userdata); /* Register response handling callbacks. */ void ne_207_set_response_handlers(ne_207_parser *p, ne_207_start_response *start, ne_207_end_response *end); /* Register propstat handling callbacks. */ void ne_207_set_propstat_handlers(ne_207_parser *p, ne_207_start_propstat *start, ne_207_end_propstat *end); /* Destroy the parser */ void ne_207_destroy(ne_207_parser *p); /* An acceptance function which only accepts 207 responses */ int ne_accept_207(void *userdata, ne_request *req, const ne_status *status); void *ne_207_get_current_propstat(ne_207_parser *p); void *ne_207_get_current_response(ne_207_parser *p); /* Dispatch request 'req', returning: * NE_ERROR: for a dispatch error, or a non-2xx response, or a * 207 response which contained a non-2xx propstat * NE_OK: for a 2xx response or a 207 response which contained * only 2xx-class propstats. * The request object is destroyed in both cases. */ int ne_simple_request(ne_session *sess, ne_request *req); NE_END_DECLS #endif /* NE_207_H */ davix-R_0_5_0/deps/libneon/src/ne_acl.h000066400000000000000000000026571257152637300200410ustar00rootroot00000000000000/* Access control Copyright (C) 2001-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * DEPRECATED ACL Interface. See ne_acl3744.h for replacement API. */ #ifndef NE_ACL_H #define NE_ACL_H #include "ne_session.h" NE_BEGIN_DECLS typedef struct { enum { ne_acl_href, ne_acl_property, ne_acl_all } apply; enum { ne_acl_grant, ne_acl_deny } type; char *principal; int read; int read_acl; int write; int write_acl; int read_cuprivset; } ne_acl_entry; /* Set the ACL for the given resource to the list of ACL entries. */ int ne_acl_set(ne_session *sess, const char *uri, const ne_acl_entry entries[], int numentries); NE_END_DECLS #endif /* NE_ACL_H */ davix-R_0_5_0/deps/libneon/src/ne_acl3744.c000066400000000000000000000120611257152637300203440ustar00rootroot00000000000000/* Access control Copyright (C) 2001-2006, 2008, Joe Orton Copyright (C) 2001, Arun Garg Copyright (C) 2007 Henrik Holst This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Contributed by Arun Garg */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include "ne_request.h" #include "ne_locks.h" #include "ne_alloc.h" #include "ne_string.h" #include "ne_acl3744.h" #include "ne_uri.h" #include "ne_xml.h" /* for NE_XML_MEDIA_TYPE */ #define EOL "\r\n" static ne_buffer *acl_body(const ne_acl_entry *right, int count) { ne_buffer *body = ne_buffer_create(); int m; ne_buffer_zappend(body, "" EOL "" EOL); for (m = 0; m < count; m++) { const char *type; type = (right[m].type == ne_acl_grant ? "grant" : "deny"); ne_buffer_concat(body, "" EOL "", NULL); switch (right[m].target) { case ne_acl_all: ne_buffer_czappend(body, "" EOL); break; case ne_acl_authenticated: ne_buffer_czappend(body, "" EOL); break; case ne_acl_unauthenticated: ne_buffer_czappend(body, "" EOL); break; case ne_acl_self: ne_buffer_czappend(body, "" EOL); break; case ne_acl_property: ne_buffer_concat(body, "<", right[m].tname, "/>" EOL, NULL); break; case ne_acl_href: ne_buffer_concat(body, "", right[m].tname, "" EOL, NULL); break; } ne_buffer_concat(body, "" EOL "<", type, ">" EOL, NULL); if ((right[m].privileges & NE_ACL_READ) == NE_ACL_READ) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_WRITE) == NE_ACL_WRITE) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_WRITE_PROPERTIES) == NE_ACL_WRITE_PROPERTIES) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_WRITE_CONTENT) == NE_ACL_WRITE_CONTENT) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_UNLOCK) == NE_ACL_UNLOCK) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_READ_ACL) == NE_ACL_READ_ACL) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_READ_CUPRIVSET) == NE_ACL_READ_CUPRIVSET) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_WRITE_ACL) == NE_ACL_WRITE_ACL) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_BIND) == NE_ACL_BIND) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_UNBIND) == NE_ACL_UNBIND) ne_buffer_concat(body, "" "" "" EOL, NULL); if ((right[m].privileges & NE_ACL_ALL) == NE_ACL_ALL) ne_buffer_concat(body, "" "" "" EOL, NULL); ne_buffer_concat(body, "" EOL, NULL); ne_buffer_czappend(body, "" EOL); } ne_buffer_czappend(body, "" EOL); return body; } int ne_acl3744_set(ne_session *sess, const char *uri, const ne_acl_entry *entries, int numentries) { int ret; ne_request *req = ne_request_create(sess, "ACL", uri); ne_buffer *body = acl_body(entries, numentries); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, uri, 0); #endif ne_set_request_body_buffer(req, body->data, ne_buffer_size(body)); ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); ret = ne_request_dispatch(req); ne_buffer_destroy(body); if (ret == NE_OK && ne_get_status(req)->code == 207) { ret = NE_ERROR; } ne_request_destroy(req); return ret; } davix-R_0_5_0/deps/libneon/src/ne_acl3744.h000066400000000000000000000052571257152637300203620ustar00rootroot00000000000000/* Access control Copyright (C) 2001-2007, Joe Orton Copyright (C) 2001, Arun Garg Copyright (C) 2007 Henrik Holst This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_ACL3744_H #define NE_ACL3744_H #include "ne_session.h" NE_BEGIN_DECLS #define NE_ACL_READ (0x0001) #define NE_ACL_WRITE (0x0002) #define NE_ACL_WRITE_PROPERTIES (0x0004) #define NE_ACL_WRITE_CONTENT (0x0008) #define NE_ACL_UNLOCK (0x0010) #define NE_ACL_READ_ACL (0x0020) #define NE_ACL_READ_CUPRIVSET (0x0040) #define NE_ACL_WRITE_ACL (0x0080) #define NE_ACL_BIND (0x0100) #define NE_ACL_UNBIND (0x0200) #define NE_ACL_ALL (0x0400) enum ne_acl_target { ne_acl_href, ne_acl_property, ne_acl_all, ne_acl_authenticated, ne_acl_unauthenticated, ne_acl_self }; enum ne_acl_optype { ne_acl_grant, ne_acl_deny }; /* A simplified representation of an Access Control Element (ACE): */ typedef struct { /* Identify the principal(s) to which this ACE applies: */ enum ne_acl_target target; /* Whether to grant or deny access: */ enum ne_acl_optype type; /* If target == ne_acl_href, tname must be non-NULL and give the * principal URL. If target == ne_acl_property, tname must be * non-NULL and be a property name, including an XML namespace * definition, if appropriate (the default namespace being * "DAV:"). This restricts access as described at: * http://tools.ietf.org/html/rfc3744#section-5.5.1 */ char *tname; /* The set of privileges to be restricted; a bit mask of one or * more of the NE_ACL_* constants defined above: */ unsigned int privileges; } ne_acl_entry; /* Set the ACL for the given resource to the list of ACL entries. */ int ne_acl3744_set(ne_session *sess, const char *path, const ne_acl_entry entries[], int numentries); NE_END_DECLS #endif /* NE_ACL3744_H */ davix-R_0_5_0/deps/libneon/src/ne_alloc.c000066400000000000000000000110031257152637300203500ustar00rootroot00000000000000/* Replacement memory allocation handling etc. Copyright (C) 1999-2005, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include "ne_alloc.h" static ne_oom_callback_fn oom; void ne_oom_callback(ne_oom_callback_fn callback) { oom = callback; } #ifndef NEON_MEMLEAK #define DO_MALLOC(ptr, len) do { \ ptr = malloc((len)); \ if (!ptr) { \ if (oom != NULL) \ oom(); \ abort(); \ } \ } while(0); void *ne_malloc(size_t len) { void *ptr; DO_MALLOC(ptr, len); return ptr; } void *ne_calloc(size_t len) { void *ptr; DO_MALLOC(ptr, len); return memset(ptr, 0, len); } void *ne_realloc(void *ptr, size_t len) { void *ret = realloc(ptr, len); if (!ret) { if (oom) oom(); abort(); } return ret; } #ifdef WIN32 /* Implemented only to ensure free is bound to the correct DLL. */ void ne_free(void *ptr) { free(ptr); } #endif char *ne_strdup(const char *s) { char *ret; DO_MALLOC(ret, strlen(s) + 1); return strcpy(ret, s); } char *ne_strndup(const char *s, size_t n) { char *new; DO_MALLOC(new, n+1); new[n] = '\0'; memcpy(new, s, n); return new; } #else /* NEON_MEMLEAK */ #include /* Memory-leak detection implementation: ne_malloc and friends are * #defined to ne_malloc_ml etc by memleak.h, which is conditionally * included by config.h. */ /* memory allocated be ne_*alloc, but not freed. */ size_t ne_alloc_used = 0; static struct block { void *ptr; size_t len; const char *file; int line; struct block *next; } *blocks = NULL; void ne_alloc_dump(FILE *f) { struct block *b; for (b = blocks; b != NULL; b = b->next) fprintf(f, "%" NE_FMT_SIZE_T "b@%s:%d%s", b->len, b->file, b->line, b->next?", ":""); } static void *tracking_malloc(size_t len, const char *file, int line) { void *ptr = malloc((len)); struct block *block; if (!ptr) { if (oom) oom(); abort(); } block = malloc(sizeof *block); if (block != NULL) { block->ptr = ptr; block->len = len; block->file = file; block->line = line; block->next = blocks; blocks = block; ne_alloc_used += len; } return ptr; } void *ne_malloc_ml(size_t size, const char *file, int line) { return tracking_malloc(size, file, line); } void *ne_calloc_ml(size_t size, const char *file, int line) { return memset(tracking_malloc(size, file, line), 0, size); } void *ne_realloc_ml(void *ptr, size_t s, const char *file, int line) { void *ret; struct block *b; if (ptr == NULL) return tracking_malloc(s, file, line); ret = realloc(ptr, s); if (!ret) { if (oom) oom(); abort(); } for (b = blocks; b != NULL; b = b->next) { if (b->ptr == ptr) { ne_alloc_used += s - b->len; b->ptr = ret; b->len = s; break; } } assert(b != NULL); return ret; } char *ne_strdup_ml(const char *s, const char *file, int line) { return strcpy(tracking_malloc(strlen(s) + 1, file, line), s); } char *ne_strndup_ml(const char *s, size_t n, const char *file, int line) { char *ret = tracking_malloc(n + 1, file, line); ret[n] = '\0'; return memcpy(ret, s, n); } void ne_free_ml(void *ptr) { struct block *b, *last = NULL; for (b = blocks; b != NULL; last = b, b = b->next) { if (b->ptr == ptr) { ne_alloc_used -= b->len; if (last) last->next = b->next; else blocks = b->next; free(b); break; } } free(ptr); } #endif /* NEON_MEMLEAK */ davix-R_0_5_0/deps/libneon/src/ne_alloc.h000066400000000000000000000035301257152637300203630ustar00rootroot00000000000000/* Replacement memory allocation handling etc. Copyright (C) 1999-2005, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_ALLOC_H #define NE_ALLOC_H #include #ifndef WIN32 #include #endif #include "ne_defs.h" NE_BEGIN_DECLS typedef void (*ne_oom_callback_fn)(void); /* Set callback which is called if malloc() returns NULL. */ void ne_oom_callback(ne_oom_callback_fn callback); #ifndef NEON_MEMLEAK /* Replacements for standard C library memory allocation functions, * which never return NULL. If the C library malloc() returns NULL, * neon will abort(); calling an OOM callback beforehand if one is * registered. The C library will only ever return NULL if the * operating system does not use optimistic memory allocation. */ void *ne_malloc(size_t size) ne_attribute_malloc; void *ne_calloc(size_t size) ne_attribute_malloc; void *ne_realloc(void *ptr, size_t s); char *ne_strdup(const char *s) ne_attribute_malloc; char *ne_strndup(const char *s, size_t n) ne_attribute_malloc; #ifdef WIN32 void ne_free(void *ptr); #else #define ne_free free #endif #endif NE_END_DECLS #endif /* NE_ALLOC_H */ davix-R_0_5_0/deps/libneon/src/ne_auth.c000066400000000000000000001457321257152637300202400ustar00rootroot00000000000000/* HTTP Authentication routines Copyright (C) 1999-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_UNISTD_H #include /* for getpid() */ #endif #ifdef WIN32 #include /* for GetCurrentThreadId() etc */ #endif #ifdef HAVE_OPENSSL #include #elif defined(HAVE_GNUTLS) #include #if LIBGNUTLS_VERSION_NUMBER < 0x020b00 #include #else #include #endif #endif #include #include #include "ne_md5.h" #include "ne_dates.h" #include "ne_request.h" #include "ne_auth.h" #include "ne_string.h" #include "ne_utils.h" #include "ne_alloc.h" #include "ne_uri.h" #include "ne_internal.h" #ifdef HAVE_GSSAPI #ifdef HAVE_GSSAPI_GSSAPI_H #include #ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H #include #endif #else #include #endif #endif #ifdef HAVE_SSPI #include "ne_sspi.h" #endif #ifdef HAVE_NTLM #include "ne_ntlm.h" #endif #define HOOK_SERVER_ID "http://webdav.org/neon/hooks/server-auth" #define HOOK_PROXY_ID "http://webdav.org/neon/hooks/proxy-auth" typedef enum { auth_alg_md5, auth_alg_md5_sess, auth_alg_unknown } auth_algorithm; /* Selected method of qop which the client is using */ typedef enum { auth_qop_none, auth_qop_auth } auth_qop; /* A callback/userdata pair registered by the application for * a particular set of protocols. */ struct auth_handler { unsigned protomask; ne_auth_creds creds; void *userdata; int attempt; /* number of invocations of this callback for * current request. */ struct auth_handler *next; }; /* A challenge */ struct auth_challenge { const struct auth_protocol *protocol; struct auth_handler *handler; const char *realm, *nonce, *opaque, *domain; unsigned int stale; /* if stale=true */ unsigned int got_qop; /* we were given a qop directive */ unsigned int qop_auth; /* "auth" token in qop attrib */ auth_algorithm alg; struct auth_challenge *next; }; static const struct auth_class { const char *id, *req_hdr, *resp_hdr, *resp_info_hdr; int status_code; /* Response status-code to trap. */ int fail_code; /* NE_* request to fail with. */ const char *error_noauth; /* Error message template use when * giving up authentication attempts. */ } ah_server_class = { HOOK_SERVER_ID, "Authorization", "WWW-Authenticate", "Authentication-Info", 401, NE_AUTH, N_("Could not authenticate to server: %s") }, ah_proxy_class = { HOOK_PROXY_ID, "Proxy-Authorization", "Proxy-Authenticate", "Proxy-Authentication-Info", 407, NE_PROXYAUTH, N_("Could not authenticate to proxy server: %s") }; /* Authentication session state. */ typedef struct { ne_session *sess; /* Which context will auth challenges be accepted? */ enum { AUTH_ANY, /* ignore nothing. */ AUTH_CONNECT, /* only in response to a CONNECT request. */ AUTH_NOTCONNECT /* only in non-CONNECT responsees */ } context; /* Protocol type for server/proxy auth. */ const struct auth_class *spec; /* The protocol used for this authentication session */ const struct auth_protocol *protocol; struct auth_handler *handlers; /*** Session details ***/ /* The username and password we are using to authenticate with */ char username[NE_ABUFSIZ]; /* This used for Basic auth */ char *basic; #ifdef HAVE_GSSAPI /* for the GSSAPI/Negotiate scheme: */ char *gssapi_token; gss_ctx_id_t gssctx; gss_name_t gssname; gss_OID gssmech; #endif #ifdef HAVE_SSPI /* This is used for SSPI (Negotiate/NTLM) auth */ char *sspi_token; void *sspi_context; #endif #ifdef HAVE_NTLM /* This is used for NTLM auth */ ne_ntlm_context *ntlm_context; #endif /* These all used for Digest auth */ char *realm; char *nonce; char *cnonce; char *opaque; char **domains; /* list of paths given as domain. */ size_t ndomains; /* size of domains array */ auth_qop qop; auth_algorithm alg; unsigned int nonce_count; /* The ASCII representation of the session's H(A1) value */ char h_a1[33]; /* Temporary store for half of the Request-Digest * (an optimisation - used in the response-digest calculation) */ struct ne_md5_ctx *stored_rdig; } auth_session; struct auth_request { /*** Per-request details. ***/ ne_request *request; /* the request object. */ /* The method and URI we are using for the current request */ const char *uri; const char *method; int attempt; /* number of times this request has been retries due * to auth challenges. */ }; /* Used if this protocol takes an unquoted non-name/value-pair * parameter in the challenge. */ #define AUTH_FLAG_OPAQUE_PARAM (0x0001) /* Used if this Authentication-Info may be sent for non-40[17] * response for this protocol. */ #define AUTH_FLAG_VERIFY_NON40x (0x0002) /* Used for broken the connection-based auth schemes. */ #define AUTH_FLAG_CONN_AUTH (0x0004) struct auth_protocol { unsigned id; /* public NE_AUTH_* id. */ int strength; /* protocol strength for sort order. */ const char *name; /* protocol name. */ /* Parse the authentication challenge; returns zero on success, or * non-zero if this challenge be handled. 'attempt' is the number * of times the request has been resent due to auth challenges. * On failure, challenge_error() should be used to append an error * message to the error buffer 'errmsg'. */ int (*challenge)(auth_session *sess, int attempt, struct auth_challenge *chall, ne_buffer **errmsg); /* Return the string to send in the -Authenticate request header: * (ne_malloc-allocated, NUL-terminated string) */ char *(*response)(auth_session *sess, struct auth_request *req); /* Parse a Authentication-Info response; returns NE_* error code * on failure; on failure, the session error string must be * set. */ int (*verify)(struct auth_request *req, auth_session *sess, const char *value); int flags; /* AUTH_FLAG_* flags */ }; /* Helper function to append an error to the buffer during challenge * handling. Pass printf-style string. *errmsg may be NULL and is * allocated if necessary. errmsg must be non-NULL. */ static void challenge_error(ne_buffer **errmsg, const char *fmt, ...) ne_attribute((format(printf, 2, 3))); /* Free the domains array, precondition sess->ndomains > 0. */ static void free_domains(auth_session *sess) { do { ne_free(sess->domains[sess->ndomains - 1]); } while (--sess->ndomains); ne_free(sess->domains); sess->domains = NULL; } static void clean_session(auth_session *sess) { if (sess->basic) ne_free(sess->basic); if (sess->nonce) ne_free(sess->nonce); if (sess->cnonce) ne_free(sess->cnonce); if (sess->opaque) ne_free(sess->opaque); if (sess->realm) ne_free(sess->realm); sess->realm = sess->basic = sess->cnonce = sess->nonce = sess->opaque = NULL; if (sess->stored_rdig) { ne_md5_destroy_ctx(sess->stored_rdig); sess->stored_rdig = NULL; } if (sess->ndomains) free_domains(sess); #ifdef HAVE_GSSAPI { unsigned int major; if (sess->gssctx != GSS_C_NO_CONTEXT) gss_delete_sec_context(&major, &sess->gssctx, GSS_C_NO_BUFFER); } if (sess->gssapi_token) ne_free(sess->gssapi_token); sess->gssapi_token = NULL; #endif #ifdef HAVE_SSPI if (sess->sspi_token) ne_free(sess->sspi_token); sess->sspi_token = NULL; ne_sspi_destroy_context(sess->sspi_context); sess->sspi_context = NULL; #endif #ifdef HAVE_NTLM if (sess->ntlm_context) { ne__ntlm_destroy_context(sess->ntlm_context); sess->ntlm_context = NULL; } #endif sess->protocol = NULL; } /* Returns client nonce string. */ static char *get_cnonce(void) { char ret[33]; unsigned char data[256]; struct ne_md5_ctx *hash; hash = ne_md5_create_ctx(); #ifdef HAVE_GNUTLS if (1) { #if LIBGNUTLS_VERSION_NUMBER < 0x020b00 gcry_create_nonce(data, sizeof data); #else gnutls_rnd(GNUTLS_RND_NONCE, data, sizeof data); #endif ne_md5_process_bytes(data, sizeof data, hash); } else #elif defined(HAVE_OPENSSL) if (RAND_status() == 1 && RAND_pseudo_bytes(data, sizeof data) >= 0) { ne_md5_process_bytes(data, sizeof data, hash); } else #endif /* HAVE_OPENSSL */ { /* Fallback sources of random data: all bad, but no good sources * are available. */ /* Uninitialized stack data; yes, happy valgrinders, this is * supposed to be here. */ ne_md5_process_bytes(data, sizeof data, hash); { #ifdef HAVE_GETTIMEOFDAY struct timeval tv; if (gettimeofday(&tv, NULL) == 0) ne_md5_process_bytes(&tv, sizeof tv, hash); #else /* HAVE_GETTIMEOFDAY */ time_t t = time(NULL); ne_md5_process_bytes(&t, sizeof t, hash); #endif } { #ifdef WIN32 DWORD pid = GetCurrentThreadId(); #else pid_t pid = getpid(); #endif ne_md5_process_bytes(&pid, sizeof pid, hash); } } ne_md5_finish_ascii(hash, ret); ne_md5_destroy_ctx(hash); return ne_strdup(ret); } /* Callback to retrieve user credentials for given session on given * attempt (pre request) for given challenge. Password is written to * pwbuf (of size NE_ABUFSIZ. On error, challenge_error() is used * with errmsg. */ static int get_credentials(auth_session *sess, ne_buffer **errmsg, int attempt, struct auth_challenge *chall, char *pwbuf) { if (chall->handler->creds(chall->handler->userdata, sess->realm, chall->handler->attempt++, sess->username, pwbuf) == 0) { return 0; } else { challenge_error(errmsg, _("rejected %s challenge"), chall->protocol->name); return -1; } } /* Examine a Basic auth challenge. * Returns 0 if an valid challenge, else non-zero. */ static int basic_challenge(auth_session *sess, int attempt, struct auth_challenge *parms, ne_buffer **errmsg) { char *tmp, password[NE_ABUFSIZ]; /* Verify challenge... must have a realm */ if (parms->realm == NULL) { challenge_error(errmsg, _("missing realm in Basic challenge")); return -1; } clean_session(sess); sess->realm = ne_strdup(parms->realm); if (get_credentials(sess, errmsg, attempt, parms, password)) { /* Failed to get credentials */ return -1; } tmp = ne_concat(sess->username, ":", password, NULL); sess->basic = ne_base64((unsigned char *)tmp, strlen(tmp)); ne_free(tmp); /* Paranoia. */ memset(password, 0, sizeof password); return 0; } /* Add Basic authentication credentials to a request */ static char *request_basic(auth_session *sess, struct auth_request *req) { return ne_concat("Basic ", sess->basic, "\r\n", NULL); } #ifdef HAVE_GSSAPI /* Add GSSAPI authentication credentials to a request */ static char *request_negotiate(auth_session *sess, struct auth_request *req) { if (sess->gssapi_token) return ne_concat("Negotiate ", sess->gssapi_token, "\r\n", NULL); else return NULL; } /* Create an GSSAPI name for server HOSTNAME; returns non-zero on * error. */ static void get_gss_name(gss_name_t *server, const char *hostname) { unsigned int major, minor; gss_buffer_desc token; token.value = ne_concat("HTTP@", hostname, NULL); token.length = strlen(token.value); major = gss_import_name(&minor, &token, GSS_C_NT_HOSTBASED_SERVICE, server); ne_free(token.value); if (GSS_ERROR(major)) { NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: gss_import_name failed."); *server = GSS_C_NO_NAME; } } /* Append GSSAPI error(s) for STATUS of type TYPE to BUF; prepending * ": " to each error if *FLAG is non-zero, setting *FLAG after an * error has been appended. */ static void make_gss_error(ne_buffer *buf, int *flag, unsigned int status, int type) { unsigned int major, minor; unsigned int context = 0; do { gss_buffer_desc msg; major = gss_display_status(&minor, status, type, GSS_C_NO_OID, &context, &msg); if (major == GSS_S_COMPLETE && msg.length) { if ((*flag)++) ne_buffer_append(buf, ": ", 2); ne_buffer_append(buf, msg.value, msg.length); } if (msg.length) gss_release_buffer(&minor, &msg); } while (context); } /* Continue a GSS-API Negotiate exchange, using input TOKEN if * non-NULL. Returns non-zero on error, in which case *errmsg is * guaranteed to be non-NULL (i.e. an error message is set). */ static int continue_negotiate(auth_session *sess, const char *token, ne_buffer **errmsg) { unsigned int major, minor; gss_buffer_desc input = GSS_C_EMPTY_BUFFER; gss_buffer_desc output = GSS_C_EMPTY_BUFFER; unsigned char *bintoken = NULL; int ret; if (token) { input.length = ne_unbase64(token, &bintoken); if (input.length == 0) { challenge_error(errmsg, _("invalid Negotiate token")); return -1; } input.value = bintoken; NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Continuation token [%s]", token); } else if (sess->gssctx != GSS_C_NO_CONTEXT) { NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Reset incomplete context."); gss_delete_sec_context(&minor, &sess->gssctx, GSS_C_NO_BUFFER); } major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &sess->gssctx, sess->gssname, sess->gssmech, GSS_C_MUTUAL_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &input, &sess->gssmech, &output, NULL, NULL); /* done with the input token. */ if (bintoken) ne_free(bintoken); if (GSS_ERROR(major)) { int flag = 0; challenge_error(errmsg, _("GSSAPI authentication error: ")); make_gss_error(*errmsg, &flag, major, GSS_C_GSS_CODE); make_gss_error(*errmsg, &flag, minor, GSS_C_MECH_CODE); return -1; } if (major == GSS_S_CONTINUE_NEEDED || major == GSS_S_COMPLETE) { NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: init_sec_context OK. (major=%d)", major); ret = 0; } else { challenge_error(errmsg, _("GSSAPI failure (code %u)"), major); ret = -1; } if (major != GSS_S_CONTINUE_NEEDED) { /* context no longer needed: destroy it */ gss_delete_sec_context(&minor, &sess->gssctx, GSS_C_NO_BUFFER); } if (output.length) { sess->gssapi_token = ne_base64(output.value, output.length); NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Output token: [%s]", sess->gssapi_token); gss_release_buffer(&minor, &output); } else { NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: No output token."); } return ret; } /* Process a Negotiate challange CHALL in session SESS; returns zero * if challenge is accepted. */ static int negotiate_challenge(auth_session *sess, int attempt, struct auth_challenge *chall, ne_buffer **errmsg) { const char *token = chall->opaque; /* Respect an initial challenge - which must have no input token, * or a continuation - which must have an input token. */ if (attempt == 0 || token) { return continue_negotiate(sess, token, errmsg); } else { challenge_error(errmsg, _("ignoring empty Negotiate continuation")); return -1; } } /* Verify the header HDR in a Negotiate response. */ static int verify_negotiate_response(struct auth_request *req, auth_session *sess, const char *hdr) { char *duphdr = ne_strdup(hdr); char *sep, *ptr = strchr(duphdr, ' '); int ret; ne_buffer *errmsg = NULL; if (!ptr || strncmp(hdr, "Negotiate", ptr - duphdr) != 0) { ne_set_error(sess->sess, _("Negotiate response verification failed: " "invalid response header token")); ne_free(duphdr); return NE_ERROR; } ptr++; if (strlen(ptr) == 0) { NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: No token in Negotiate response!"); ne_free(duphdr); return NE_OK; } if ((sep = strchr(ptr, ',')) != NULL) *sep = '\0'; if ((sep = strchr(ptr, ' ')) != NULL) *sep = '\0'; NE_DEBUG(NE_DBG_HTTPAUTH, "gssapi: Negotiate response token [%s]", ptr); ret = continue_negotiate(sess, ptr, &errmsg); if (ret) { ne_set_error(sess->sess, _("Negotiate response verification failure: %s"), errmsg->data); } if (errmsg) ne_buffer_destroy(errmsg); ne_free(duphdr); return ret ? NE_ERROR : NE_OK; } #endif #ifdef HAVE_SSPI static char *request_sspi(auth_session *sess, struct auth_request *request) { if (sess->sspi_token) return ne_concat(sess->protocol->name, " ", sess->sspi_token, "\r\n", NULL); else return NULL; } static int continue_sspi(auth_session *sess, int ntlm, const char *hdr) { int status; char *response = NULL; NE_DEBUG(NE_DBG_HTTPAUTH, "auth: SSPI challenge."); if (!sess->sspi_context) { ne_uri uri = {0}; ne_fill_server_uri(sess->sess, &uri); status = ne_sspi_create_context(&sess->sspi_context, uri.host, ntlm); ne_uri_free(&uri); if (status) { return status; } } status = ne_sspi_authenticate(sess->sspi_context, hdr, &response); if (status) { return status; } if (response && *response) { sess->sspi_token = response; NE_DEBUG(NE_DBG_HTTPAUTH, "auth: SSPI challenge [%s]", sess->sspi_token); } return 0; } static int sspi_challenge(auth_session *sess, int attempt, struct auth_challenge *parms, ne_buffer **errmsg) { int ntlm = ne_strcasecmp(parms->protocol->name, "NTLM") == 0; return continue_sspi(sess, ntlm, parms->opaque); } static int verify_sspi(struct auth_request *req, auth_session *sess, const char *hdr) { int ntlm = ne_strncasecmp(hdr, "NTLM ", 5) == 0; char *ptr = strchr(hdr, ' '); if (!ptr) { ne_set_error(sess->sess, _("SSPI response verification failed: " "invalid response header token")); return NE_ERROR; } while(*ptr == ' ') ptr++; if (*ptr == '\0') { NE_DEBUG(NE_DBG_HTTPAUTH, "auth: No token in SSPI response!"); return NE_OK; } return continue_sspi(sess, ntlm, ptr); } #endif /* Parse the "domain" challenge parameter and set the domains array up * in the session appropriately. */ static int parse_domain(auth_session *sess, const char *domain) { char *cp = ne_strdup(domain), *p = cp; ne_uri base; int invalid = 0; memset(&base, 0, sizeof base); ne_fill_server_uri(sess->sess, &base); do { char *token = ne_token(&p, ' '); ne_uri rel, absolute; if (ne_uri_parse(token, &rel) == 0) { /* Resolve relative to the Request-URI. */ base.path = "/"; ne_uri_resolve(&base, &rel, &absolute); /* Compare against the resolved path to check this URI has * the same (scheme, host, port) components; ignore it * otherwise: */ base.path = absolute.path; if (absolute.path && ne_uri_cmp(&absolute, &base) == 0) { sess->domains = ne_realloc(sess->domains, ++sess->ndomains * sizeof(*sess->domains)); sess->domains[sess->ndomains - 1] = absolute.path; NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Using domain %s from %s", absolute.path, token); absolute.path = NULL; } else { NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Ignoring domain %s", token); } ne_uri_free(&absolute); } else { invalid = 1; } ne_uri_free(&rel); } while (p && !invalid); if (invalid && sess->ndomains) { free_domains(sess); } ne_free(cp); base.path = NULL; ne_uri_free(&base); return invalid; } #ifdef HAVE_NTLM static char *request_ntlm(auth_session *sess, struct auth_request *request) { char *token = ne__ntlm_getRequestToken(sess->ntlm_context); if (token) { char *req = ne_concat(sess->protocol->name, " ", token, "\r\n", NULL); ne_free(token); return req; } else { return NULL; } } static int ntlm_challenge(auth_session *sess, int attempt, struct auth_challenge *parms, ne_buffer **errmsg) { int status; NE_DEBUG(NE_DBG_HTTPAUTH, "auth: NTLM challenge."); if (!parms->opaque && (!sess->ntlm_context || (attempt > 1))) { char password[NE_ABUFSIZ]; if (get_credentials(sess, errmsg, attempt, parms, password)) { /* Failed to get credentials */ return -1; } if (sess->ntlm_context) { ne__ntlm_destroy_context(sess->ntlm_context); sess->ntlm_context = NULL; } sess->ntlm_context = ne__ntlm_create_context(sess->username, password); } status = ne__ntlm_authenticate(sess->ntlm_context, parms->opaque); if (status) { return status; } return 0; } #endif /* HAVE_NTLM */ /* Examine a digest challenge: return 0 if it is a valid Digest challenge, * else non-zero. */ static int digest_challenge(auth_session *sess, int attempt, struct auth_challenge *parms, ne_buffer **errmsg) { char password[NE_ABUFSIZ]; if (parms->alg == auth_alg_unknown) { challenge_error(errmsg, _("unknown algorithm in Digest challenge")); return -1; } else if (parms->alg == auth_alg_md5_sess && !parms->qop_auth) { challenge_error(errmsg, _("incompatible algorithm in Digest challenge")); return -1; } else if (parms->realm == NULL || parms->nonce == NULL) { challenge_error(errmsg, _("missing parameter in Digest challenge")); return -1; } else if (parms->stale && sess->realm == NULL) { challenge_error(errmsg, _("initial Digest challenge was stale")); return -1; } else if (parms->stale && (sess->alg != parms->alg || strcmp(sess->realm, parms->realm))) { /* With stale=true the realm and algorithm cannot change since these * require re-hashing H(A1) which defeats the point. */ challenge_error(errmsg, _("stale Digest challenge with new algorithm or realm")); return -1; } if (!parms->stale) { /* Non-stale challenge: clear session and request credentials. */ clean_session(sess); /* The domain paramater must be parsed after the session is * cleaned; ignore domain for proxy auth. */ if (parms->domain && sess->spec == &ah_server_class && parse_domain(sess, parms->domain)) { challenge_error(errmsg, _("could not parse domain in Digest challenge")); return -1; } sess->realm = ne_strdup(parms->realm); sess->alg = parms->alg; sess->cnonce = get_cnonce(); if (get_credentials(sess, errmsg, attempt, parms, password)) { /* Failed to get credentials */ return -1; } } else { /* Stale challenge: accept a new nonce or opaque. */ if (sess->nonce) ne_free(sess->nonce); if (sess->opaque && parms->opaque) ne_free(sess->opaque); } sess->nonce = ne_strdup(parms->nonce); if (parms->opaque) { sess->opaque = ne_strdup(parms->opaque); } if (parms->got_qop) { /* What type of qop are we to apply to the message? */ NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Got qop, using 2617-style."); sess->nonce_count = 0; sess->qop = auth_qop_auth; } else { /* No qop at all/ */ sess->qop = auth_qop_none; } if (!parms->stale) { struct ne_md5_ctx *tmp; /* Calculate H(A1). * tmp = H(unq(username-value) ":" unq(realm-value) ":" passwd) */ tmp = ne_md5_create_ctx(); ne_md5_process_bytes(sess->username, strlen(sess->username), tmp); ne_md5_process_bytes(":", 1, tmp); ne_md5_process_bytes(sess->realm, strlen(sess->realm), tmp); ne_md5_process_bytes(":", 1, tmp); ne_md5_process_bytes(password, strlen(password), tmp); memset(password, 0, sizeof password); /* done with that. */ if (sess->alg == auth_alg_md5_sess) { struct ne_md5_ctx *a1; char tmp_md5_ascii[33]; /* Now we calculate the SESSION H(A1) * A1 = H(...above...) ":" unq(nonce-value) ":" unq(cnonce-value) */ ne_md5_finish_ascii(tmp, tmp_md5_ascii); a1 = ne_md5_create_ctx(); ne_md5_process_bytes(tmp_md5_ascii, 32, a1); ne_md5_process_bytes(":", 1, a1); ne_md5_process_bytes(sess->nonce, strlen(sess->nonce), a1); ne_md5_process_bytes(":", 1, a1); ne_md5_process_bytes(sess->cnonce, strlen(sess->cnonce), a1); ne_md5_finish_ascii(a1, sess->h_a1); ne_md5_destroy_ctx(a1); NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Session H(A1) is [%s]", sess->h_a1); } else { ne_md5_finish_ascii(tmp, sess->h_a1); NE_DEBUG(NE_DBG_HTTPAUTH, "auth: H(A1) is [%s]", sess->h_a1); } ne_md5_destroy_ctx(tmp); } NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Accepting digest challenge."); return 0; } /* Returns non-zero if given Request-URI is inside the authentication * domain defined for the session. */ static int inside_domain(auth_session *sess, const char *req_uri) { int inside = 0; size_t n; ne_uri uri; /* Parse the Request-URI; it will be an absoluteURI if using a * proxy, and possibly '*'. */ if (strcmp(req_uri, "*") == 0 || ne_uri_parse(req_uri, &uri) != 0) { /* Presume outside the authentication domain. */ return 0; } for (n = 0; n < sess->ndomains && !inside; n++) { const char *d = sess->domains[n]; inside = strncmp(uri.path, d, strlen(d)) == 0; } NE_DEBUG(NE_DBG_HTTPAUTH, "auth: '%s' is inside auth domain: %d.", uri.path, inside); ne_uri_free(&uri); return inside; } /* Return Digest authentication credentials header value for the given * session. */ static char *request_digest(auth_session *sess, struct auth_request *req) { struct ne_md5_ctx *a2, *rdig; char a2_md5_ascii[33], rdig_md5_ascii[33]; char nc_value[9] = {0}; const char *qop_value = "auth"; /* qop-value */ ne_buffer *ret; /* Do not submit credentials if an auth domain is defined and this * request-uri fails outside it. */ if (sess->ndomains && !inside_domain(sess, req->uri)) { return NULL; } /* Increase the nonce-count */ if (sess->qop != auth_qop_none) { sess->nonce_count++; ne_snprintf(nc_value, 9, "%08x", sess->nonce_count); } /* Calculate H(A2). */ a2 = ne_md5_create_ctx(); ne_md5_process_bytes(req->method, strlen(req->method), a2); ne_md5_process_bytes(":", 1, a2); ne_md5_process_bytes(req->uri, strlen(req->uri), a2); ne_md5_finish_ascii(a2, a2_md5_ascii); ne_md5_destroy_ctx(a2); NE_DEBUG(NE_DBG_HTTPAUTH, "auth: H(A2): %s", a2_md5_ascii); /* Now, calculation of the Request-Digest. * The first section is the regardless of qop value * H(A1) ":" unq(nonce-value) ":" */ rdig = ne_md5_create_ctx(); /* Use the calculated H(A1) */ ne_md5_process_bytes(sess->h_a1, 32, rdig); ne_md5_process_bytes(":", 1, rdig); ne_md5_process_bytes(sess->nonce, strlen(sess->nonce), rdig); ne_md5_process_bytes(":", 1, rdig); if (sess->qop != auth_qop_none) { /* Add on: * nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" */ ne_md5_process_bytes(nc_value, 8, rdig); ne_md5_process_bytes(":", 1, rdig); ne_md5_process_bytes(sess->cnonce, strlen(sess->cnonce), rdig); ne_md5_process_bytes(":", 1, rdig); /* Store a copy of this structure (see note below) */ if (sess->stored_rdig) ne_md5_destroy_ctx(sess->stored_rdig); sess->stored_rdig = ne_md5_dup_ctx(rdig); ne_md5_process_bytes(qop_value, strlen(qop_value), rdig); ne_md5_process_bytes(":", 1, rdig); } /* And finally, H(A2) */ ne_md5_process_bytes(a2_md5_ascii, 32, rdig); ne_md5_finish_ascii(rdig, rdig_md5_ascii); ne_md5_destroy_ctx(rdig); ret = ne_buffer_create(); ne_buffer_concat(ret, "Digest username=\"", sess->username, "\", " "realm=\"", sess->realm, "\", " "nonce=\"", sess->nonce, "\", " "uri=\"", req->uri, "\", " "response=\"", rdig_md5_ascii, "\", " "algorithm=\"", sess->alg == auth_alg_md5 ? "MD5" : "MD5-sess", "\"", NULL); if (sess->opaque != NULL) { ne_buffer_concat(ret, ", opaque=\"", sess->opaque, "\"", NULL); } if (sess->qop != auth_qop_none) { /* Add in cnonce and nc-value fields */ ne_buffer_concat(ret, ", cnonce=\"", sess->cnonce, "\", " "nc=", nc_value, ", " "qop=\"", qop_value, "\"", NULL); } ne_buffer_zappend(ret, "\r\n"); return ne_buffer_finish(ret); } /* Parse line of comma-separated key-value pairs. If 'ischall' == 1, * then also return a leading space-separated token, as *value == * NULL. Otherwise, if return value is 0, *key and *value will be * non-NULL. If return value is non-zero, parsing has ended. If * 'sep' is non-NULL and ischall is 1, the separator character is * written to *sep when a challenge is parsed. */ static int tokenize(char **hdr, char **key, char **value, char *sep, int ischall) { char *pnt = *hdr; enum { BEFORE_EQ, AFTER_EQ, AFTER_EQ_QUOTED } state = BEFORE_EQ; if (**hdr == '\0') return 1; *key = NULL; do { switch (state) { case BEFORE_EQ: if (*pnt == '=') { if (*key == NULL) return -1; *pnt = '\0'; *value = pnt + 1; state = AFTER_EQ; } else if ((*pnt == ' ' || *pnt == ',') && ischall && *key != NULL) { *value = NULL; if (sep) *sep = *pnt; *pnt = '\0'; *hdr = pnt + 1; return 0; } else if (*key == NULL && strchr(" \r\n\t", *pnt) == NULL) { *key = pnt; } break; case AFTER_EQ: if (*pnt == ',') { *pnt = '\0'; *hdr = pnt + 1; return 0; } else if (*pnt == '\"') { state = AFTER_EQ_QUOTED; } break; case AFTER_EQ_QUOTED: if (*pnt == '\"') { state = AFTER_EQ; *pnt = '\0'; } break; } } while (*++pnt != '\0'); if (state == BEFORE_EQ && ischall && *key != NULL) { *value = NULL; if (sep) *sep = '\0'; } *hdr = pnt; /* End of string: */ return 0; } /* Pass this the value of the 'Authentication-Info:' header field, if * one is received. * Returns: * 0 if it gives a valid authentication for the server * non-zero otherwise (don't believe the response in this case!). */ static int verify_digest_response(struct auth_request *req, auth_session *sess, const char *value) { char *hdr, *pnt, *key, *val; auth_qop qop = auth_qop_none; char *nextnonce, *rspauth, *cnonce, *nc, *qop_value; unsigned int nonce_count; int ret = NE_OK; nextnonce = rspauth = cnonce = nc = qop_value = NULL; pnt = hdr = ne_strdup(value); NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Got Auth-Info header: %s", value); while (tokenize(&pnt, &key, &val, NULL, 0) == 0) { val = ne_shave(val, "\""); if (ne_strcasecmp(key, "qop") == 0) { qop_value = val; if (ne_strcasecmp(val, "auth") == 0) { qop = auth_qop_auth; } else { qop = auth_qop_none; } } else if (ne_strcasecmp(key, "nextnonce") == 0) { nextnonce = val; } else if (ne_strcasecmp(key, "rspauth") == 0) { rspauth = val; } else if (ne_strcasecmp(key, "cnonce") == 0) { cnonce = val; } else if (ne_strcasecmp(key, "nc") == 0) { nc = val; } } if (qop == auth_qop_none) { /* The 2069-style A-I header only has the entity and nextnonce * parameters. */ NE_DEBUG(NE_DBG_HTTPAUTH, "auth: 2069-style A-I header."); } else if (!rspauth || !cnonce || !nc) { ret = NE_ERROR; ne_set_error(sess->sess, _("Digest mutual authentication failure: " "missing parameters")); } else if (strcmp(cnonce, sess->cnonce) != 0) { ret = NE_ERROR; ne_set_error(sess->sess, _("Digest mutual authentication failure: " "client nonce mismatch")); } else if (nc) { char *ptr; errno = 0; nonce_count = strtoul(nc, &ptr, 16); if (*ptr != '\0' || errno) { ret = NE_ERROR; ne_set_error(sess->sess, _("Digest mutual authentication failure: " "could not parse nonce count")); } else if (nonce_count != sess->nonce_count) { ret = NE_ERROR; ne_set_error(sess->sess, _("Digest mutual authentication failure: " "nonce count mismatch (%u not %u)"), nonce_count, sess->nonce_count); } } /* Finally, for qop=auth cases, if everything else is OK, verify * the response-digest field. */ if (qop == auth_qop_auth && ret == NE_OK) { struct ne_md5_ctx *a2; char a2_md5_ascii[33], rdig_md5_ascii[33]; /* Modified H(A2): */ a2 = ne_md5_create_ctx(); ne_md5_process_bytes(":", 1, a2); ne_md5_process_bytes(req->uri, strlen(req->uri), a2); ne_md5_finish_ascii(a2, a2_md5_ascii); ne_md5_destroy_ctx(a2); /* sess->stored_rdig contains digest-so-far of: * H(A1) ":" unq(nonce-value) */ /* Add in qop-value */ ne_md5_process_bytes(qop_value, strlen(qop_value), sess->stored_rdig); ne_md5_process_bytes(":", 1, sess->stored_rdig); /* Digest ":" H(A2) */ ne_md5_process_bytes(a2_md5_ascii, 32, sess->stored_rdig); /* All done */ ne_md5_finish_ascii(sess->stored_rdig, rdig_md5_ascii); ne_md5_destroy_ctx(sess->stored_rdig); sess->stored_rdig = NULL; /* And... do they match? */ ret = ne_strcasecmp(rdig_md5_ascii, rspauth) == 0 ? NE_OK : NE_ERROR; NE_DEBUG(NE_DBG_HTTPAUTH, "auth: response-digest match: %s " "(expected [%s] vs actual [%s])\n", ret == NE_OK ? "yes" : "no", rdig_md5_ascii, rspauth); if (ret) { ne_set_error(sess->sess, _("Digest mutual authentication failure: " "request-digest mismatch")); } } /* Check for a nextnonce */ if (nextnonce != NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Found nextnonce of [%s].", nextnonce); ne_free(sess->nonce); sess->nonce = ne_strdup(nextnonce); sess->nonce_count = 0; } ne_free(hdr); return ret; } static const struct auth_protocol protocols[] = { { NE_AUTH_BASIC, 10, "Basic", basic_challenge, request_basic, NULL, 0 }, { NE_AUTH_DIGEST, 20, "Digest", digest_challenge, request_digest, verify_digest_response, 0 }, #ifdef HAVE_GSSAPI { NE_AUTH_GSSAPI, 30, "Negotiate", negotiate_challenge, request_negotiate, verify_negotiate_response, AUTH_FLAG_OPAQUE_PARAM|AUTH_FLAG_VERIFY_NON40x|AUTH_FLAG_CONN_AUTH }, #endif #ifdef HAVE_SSPI { NE_AUTH_NTLM, 30, "NTLM", sspi_challenge, request_sspi, NULL, AUTH_FLAG_OPAQUE_PARAM|AUTH_FLAG_VERIFY_NON40x|AUTH_FLAG_CONN_AUTH }, { NE_AUTH_GSSAPI, 30, "Negotiate", sspi_challenge, request_sspi, verify_sspi, AUTH_FLAG_OPAQUE_PARAM|AUTH_FLAG_VERIFY_NON40x|AUTH_FLAG_CONN_AUTH }, #endif #ifdef HAVE_NTLM { NE_AUTH_NTLM, 30, "NTLM", ntlm_challenge, request_ntlm, NULL, AUTH_FLAG_OPAQUE_PARAM|AUTH_FLAG_VERIFY_NON40x|AUTH_FLAG_CONN_AUTH }, #endif { 0 } }; /* Insert a new auth challenge for protocol 'proto' in list of * challenges 'list'. The challenge list is kept in sorted order of * strength, with highest strength first. */ static struct auth_challenge *insert_challenge(struct auth_challenge **list, const struct auth_protocol *proto) { struct auth_challenge *ret = ne_calloc(sizeof *ret); struct auth_challenge *chall, *prev; for (chall = *list, prev = NULL; chall != NULL; prev = chall, chall = chall->next) { if (proto->strength > chall->protocol->strength) { break; } } if (prev) { ret->next = prev->next; prev->next = ret; } else { ret->next = *list; *list = ret; } ret->protocol = proto; return ret; } static void challenge_error(ne_buffer **errbuf, const char *fmt, ...) { char err[128]; va_list ap; size_t len; va_start(ap, fmt); len = ne_vsnprintf(err, sizeof err, fmt, ap); va_end(ap); if (*errbuf == NULL) { *errbuf = ne_buffer_create(); ne_buffer_append(*errbuf, err, len); } else { ne_buffer_concat(*errbuf, ", ", err, NULL); } } /* Passed the value of a "(Proxy,WWW)-Authenticate: " header field. * Returns 0 if valid challenge was accepted; non-zero if no valid * challenge was found. */ static int auth_challenge(auth_session *sess, int attempt, const char *value) { char *pnt, *key, *val, *hdr, sep; struct auth_challenge *chall = NULL, *challenges = NULL; ne_buffer *errmsg = NULL; pnt = hdr = ne_strdup(value); /* The header value may be made up of one or more challenges. We * split it down into attribute-value pairs, then search for * schemes in the pair keys. */ while (!tokenize(&pnt, &key, &val, &sep, 1)) { if (val == NULL) { const struct auth_protocol *proto = NULL; struct auth_handler *hdl; size_t n; for (hdl = sess->handlers; hdl; hdl = hdl->next) { for (n = 0; protocols[n].id; n++) { if (protocols[n].id & hdl->protomask && ne_strcasecmp(key, protocols[n].name) == 0) { proto = &protocols[n]; break; } } if (proto) break; } if (proto == NULL) { /* Ignore this challenge. */ chall = NULL; challenge_error(&errmsg, _("ignored %s challenge"), key); continue; } NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Got '%s' challenge.", proto->name); chall = insert_challenge(&challenges, proto); chall->handler = hdl; if ((proto->flags & AUTH_FLAG_OPAQUE_PARAM) && sep == ' ') { /* Cope with the fact that the unquoted base64 * paramater token doesn't match the 2617 auth-param * grammar: */ chall->opaque = ne_shave(ne_token(&pnt, ','), " \t"); NE_DEBUG(NE_DBG_HTTPAUTH, "auth: %s opaque parameter '%s'", proto->name, chall->opaque); if (!pnt) break; /* stop parsing at end-of-string. */ } continue; } else if (chall == NULL) { /* Ignore pairs for an unknown challenge. */ NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Ignored parameter: %s = %s", key, val); continue; } /* Strip quotes off value. */ val = ne_shave(val, "\"'"); if (ne_strcasecmp(key, "realm") == 0) { chall->realm = val; } else if (ne_strcasecmp(key, "nonce") == 0) { chall->nonce = val; } else if (ne_strcasecmp(key, "opaque") == 0) { chall->opaque = val; } else if (ne_strcasecmp(key, "stale") == 0) { /* Truth value */ chall->stale = (ne_strcasecmp(val, "true") == 0); } else if (ne_strcasecmp(key, "algorithm") == 0) { if (ne_strcasecmp(val, "md5") == 0) { chall->alg = auth_alg_md5; } else if (ne_strcasecmp(val, "md5-sess") == 0) { chall->alg = auth_alg_md5_sess; } else { chall->alg = auth_alg_unknown; } } else if (ne_strcasecmp(key, "qop") == 0) { /* iterate over each token in the value */ do { const char *tok = ne_shave(ne_token(&val, ','), " \t"); if (ne_strcasecmp(tok, "auth") == 0) { chall->qop_auth = 1; } } while (val); chall->got_qop = chall->qop_auth; } else if (ne_strcasecmp(key, "domain") == 0) { chall->domain = val; } } sess->protocol = NULL; /* Iterate through the challenge list (which is sorted from * strongest to weakest) attempting to accept each one. */ for (chall = challenges; chall != NULL; chall = chall->next) { NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Trying %s challenge...", chall->protocol->name); if (chall->protocol->challenge(sess, attempt, chall, &errmsg) == 0) { NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Accepted %s challenge.", chall->protocol->name); sess->protocol = chall->protocol; break; } } if (!sess->protocol) { NE_DEBUG(NE_DBG_HTTPAUTH, "auth: No challenges accepted."); ne_set_error(sess->sess, _(sess->spec->error_noauth), errmsg ? errmsg->data : _("could not parse challenge")); } while (challenges != NULL) { chall = challenges->next; ne_free(challenges); challenges = chall; } ne_free(hdr); if (errmsg) ne_buffer_destroy(errmsg); return !(sess->protocol != NULL); } static void ah_create(ne_request *req, void *session, const char *method, const char *uri) { auth_session *sess = session; int is_connect = strcmp(method, "CONNECT") == 0; if (sess->context == AUTH_ANY || (is_connect && sess->context == AUTH_CONNECT) || (!is_connect && sess->context == AUTH_NOTCONNECT)) { struct auth_request *areq = ne_calloc(sizeof *areq); struct auth_handler *hdl; NE_DEBUG(NE_DBG_HTTPAUTH, "ah_create, for %s", sess->spec->resp_hdr); areq->method = method; areq->uri = uri; areq->request = req; ne_set_request_private(req, sess->spec->id, areq); /* For each new request, reset the attempt counter in every * registered handler. */ for (hdl = sess->handlers; hdl; hdl = hdl->next) { hdl->attempt = 0; } } } static void ah_pre_send(ne_request *r, void *cookie, ne_buffer *request) { auth_session *sess = cookie; struct auth_request *req = ne_get_request_private(r, sess->spec->id); if (sess->protocol && req) { char *value; NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Sending '%s' response.", sess->protocol->name); value = sess->protocol->response(sess, req); if (value != NULL) { ne_buffer_concat(request, sess->spec->req_hdr, ": ", value, NULL); ne_free(value); } } } static int ah_post_send(ne_request *req, void *cookie, const ne_status *status) { auth_session *sess = cookie; struct auth_request *areq = ne_get_request_private(req, sess->spec->id); const char *auth_hdr, *auth_info_hdr; int ret = NE_OK; if (!areq) return NE_OK; auth_hdr = ne_get_response_header(req, sess->spec->resp_hdr); auth_info_hdr = ne_get_response_header(req, sess->spec->resp_info_hdr); if (sess->context == AUTH_CONNECT && status->code == 401 && !auth_hdr) { /* Some broken proxies issue a 401 as a proxy auth challenge * to a CONNECT request; handle this here. */ auth_hdr = ne_get_response_header(req, "WWW-Authenticate"); auth_info_hdr = NULL; } #ifdef HAVE_GSSAPI /* whatever happens: forget the GSSAPI token cached thus far */ if (sess->gssapi_token) { ne_free(sess->gssapi_token); sess->gssapi_token = NULL; } #endif #ifdef HAVE_SSPI /* whatever happens: forget the SSPI token cached thus far */ if (sess->sspi_token) { ne_free(sess->sspi_token); sess->sspi_token = NULL; } #endif NE_DEBUG(NE_DBG_HTTPAUTH, "ah_post_send (#%d), code is %d (want %d), %s is %s\n", areq->attempt, status->code, sess->spec->status_code, sess->spec->resp_hdr, auth_hdr ? auth_hdr : "(none)"); if (auth_info_hdr && sess->protocol && sess->protocol->verify && (sess->protocol->flags & AUTH_FLAG_VERIFY_NON40x) == 0) { ret = sess->protocol->verify(areq, sess, auth_info_hdr); } else if (sess->protocol && sess->protocol->verify && (sess->protocol->flags & AUTH_FLAG_VERIFY_NON40x) && (status->klass == 2 || status->klass == 3) && auth_hdr) { ret = sess->protocol->verify(areq, sess, auth_hdr); } else if ((status->code == sess->spec->status_code || (status->code == 401 && sess->context == AUTH_CONNECT)) && auth_hdr) { /* note above: allow a 401 in response to a CONNECT request * from a proxy since some buggy proxies send that. */ NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Got challenge (code %d).", status->code); if (!auth_challenge(sess, areq->attempt++, auth_hdr)) { ret = NE_RETRY; } else { clean_session(sess); ret = sess->spec->fail_code; } /* Set or clear the conn-auth flag according to whether this * was an accepted challenge for a borked protocol. */ ne_set_session_flag(sess->sess, NE_SESSFLAG_CONNAUTH, sess->protocol && (sess->protocol->flags & AUTH_FLAG_CONN_AUTH)); } #ifdef HAVE_SSPI /* Clear the SSPI context after successfull authentication. */ if ((status->klass == 2 || status->klass == 3) && sess->sspi_context) { ne_sspi_clear_context(sess->sspi_context); } #endif return ret; } static void ah_destroy(ne_request *req, void *session) { auth_session *sess = session; struct auth_request *areq = ne_get_request_private(req, sess->spec->id); if (areq) { ne_free(areq); } } static void free_auth(void *cookie) { auth_session *sess = cookie; struct auth_handler *hdl, *next; #ifdef HAVE_GSSAPI if (sess->gssname != GSS_C_NO_NAME) { unsigned int major; gss_release_name(&major, &sess->gssname); } #endif for (hdl = sess->handlers; hdl; hdl = next) { next = hdl->next; ne_free(hdl); } clean_session(sess); ne_free(sess); } static void auth_register(ne_session *sess, int isproxy, unsigned protomask, const struct auth_class *ahc, const char *id, ne_auth_creds creds, void *userdata) { auth_session *ahs; struct auth_handler **hdl; /* Handle the _ALL and _DEFAULT protocol masks: */ if (protomask == NE_AUTH_ALL) { protomask |= NE_AUTH_BASIC | NE_AUTH_DIGEST | NE_AUTH_NEGOTIATE; } else if (protomask == NE_AUTH_DEFAULT) { protomask |= NE_AUTH_BASIC | NE_AUTH_DIGEST; if (strcmp(ne_get_scheme(sess), "https") == 0 || isproxy) { protomask |= NE_AUTH_NEGOTIATE; } } if ((protomask & NE_AUTH_NEGOTIATE) == NE_AUTH_NEGOTIATE) { /* Map NEGOTIATE to NTLM | GSSAPI. */ protomask |= NE_AUTH_GSSAPI | NE_AUTH_NTLM; } ahs = ne_get_session_private(sess, id); if (ahs == NULL) { ahs = ne_calloc(sizeof *ahs); ahs->sess = sess; ahs->spec = ahc; if (strcmp(ne_get_scheme(sess), "https") == 0) { ahs->context = isproxy ? AUTH_CONNECT : AUTH_NOTCONNECT; } else { ahs->context = AUTH_ANY; } /* Register hooks */ ne_hook_create_request(sess, ah_create, ahs); ne_hook_pre_send(sess, ah_pre_send, ahs); ne_hook_post_send(sess, ah_post_send, ahs); ne_hook_destroy_request(sess, ah_destroy, ahs); ne_hook_destroy_session(sess, free_auth, ahs); ne_set_session_private(sess, id, ahs); } #ifdef HAVE_GSSAPI if ((protomask & NE_AUTH_GSSAPI) && ahs->gssname == GSS_C_NO_NAME) { ne_uri uri = {0}; if (isproxy) ne_fill_proxy_uri(sess, &uri); else ne_fill_server_uri(sess, &uri); get_gss_name(&ahs->gssname, uri.host); ne_uri_free(&uri); } #endif /* Find the end of the handler list, and add a new one. */ hdl = &ahs->handlers; while (*hdl) hdl = &(*hdl)->next; *hdl = ne_malloc(sizeof **hdl); (*hdl)->protomask = protomask; (*hdl)->creds = creds; (*hdl)->userdata = userdata; (*hdl)->next = NULL; (*hdl)->attempt = 0; } void ne_set_server_auth(ne_session *sess, ne_auth_creds creds, void *userdata) { auth_register(sess, 0, NE_AUTH_DEFAULT, &ah_server_class, HOOK_SERVER_ID, creds, userdata); } void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdata) { auth_register(sess, 1, NE_AUTH_DEFAULT, &ah_proxy_class, HOOK_PROXY_ID, creds, userdata); } void ne_add_server_auth(ne_session *sess, unsigned protocol, ne_auth_creds creds, void *userdata) { auth_register(sess, 0, protocol, &ah_server_class, HOOK_SERVER_ID, creds, userdata); } void ne_add_proxy_auth(ne_session *sess, unsigned protocol, ne_auth_creds creds, void *userdata) { auth_register(sess, 1, protocol, &ah_proxy_class, HOOK_PROXY_ID, creds, userdata); } void ne_forget_auth(ne_session *sess) { auth_session *as; if ((as = ne_get_session_private(sess, HOOK_SERVER_ID)) != NULL) clean_session(as); if ((as = ne_get_session_private(sess, HOOK_PROXY_ID)) != NULL) clean_session(as); } davix-R_0_5_0/deps/libneon/src/ne_auth.h000066400000000000000000000127611257152637300202400ustar00rootroot00000000000000/* HTTP authentication routines Copyright (C) 1999-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_AUTH_H #define NE_AUTH_H #include "ne_session.h" /* for ne_session */ NE_BEGIN_DECLS /* Size of username/password buffers passed to ne_auth_creds * callback. */ #define NE_ABUFSIZ (256) /* The callback used to request the username and password in the given * realm. The username and password must be copied into the buffers * which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero * on the first call to the callback, and increases by one each time * an attempt to authenticate fails. * * The callback must return zero to indicate that authentication * should be attempted with the username/password, or non-zero to * cancel the request. (if non-zero, username and password are * ignored.) * * IMPORTANT NOTE: The callback will be invoked repeatedly until * either it returns non-zero, or authentication is successful. * * Hint: if you just wish to attempt authentication just once (even if * the user gets the username/password wrong), have the callback * function use 'attempt' value as the function return value. */ typedef int (*ne_auth_creds)(void *userdata, const char *realm, int attempt, char *username, char *password); /* Set callbacks to provide credentials for server and proxy * authentication, using the default set of authentication protocols. * userdata is passed as the first argument to the callback. */ void ne_set_server_auth(ne_session *sess, ne_auth_creds creds, void *userdata); void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdata); /* As an alternative to using ne_set_server_auth and * ne_set_proxy_auth, the following interfaces may be used; these * allow control over which authentication protocol is used. */ /* NE_AUTH_BASIC: Basic authentication transmits the username and * password unprotected over the channel; this allows a passive attack * to steal the credentials if using an unsecured channel * (i.e. non-SSL). */ #define NE_AUTH_BASIC (0x0001) /* NE_AUTH_DIGEST: Digest authentication uses a hash of the username, * password, and certain aspects of the request, so prevents passive * attackers from obtaining the credentials; active attackers can * still modify most of the request/response if using an unsecured * channel. */ #define NE_AUTH_DIGEST (0x0002) /* NE_AUTH_NEGOTIATE: Negotiate uses GSSAPI/SSPI, or NTLM, to * authenticate the user; an active attacker can modify any of the * request/response at will, so this must not be used over an * unsecured channel. NE_AUTH_NEGOTIATE is currently equivalent to * use of (NE_AUTH_GSSAPI | NE_AUTH_NTLM). */ #define NE_AUTH_NEGOTIATE (0x0004) /* NE_AUTH_GSSAPI: Use GSSAPI or SSPI to authenticate the user; an * active attacker can modify any of the request/response at will, so * this must not be used over an unsecured channel. */ #define NE_AUTH_GSSAPI (0x0008) /* NE_AUTH_NTLM: Use NTLM to authenticate the user; an active attacker * can modify any of the request/response at will, so this must not be * used over an unsecured channel. */ #define NE_AUTH_NTLM (0x0010) /* The default set of supported protocols, as deemed appropriate for * the given session scheme. */ #define NE_AUTH_DEFAULT (0x1000) /* All protocols supported by the library. */ #define NE_AUTH_ALL (0x2000) /* Add a callback to provide credentials for server and proxy * authentication using a particular auth protocol or set of * protocols. The protocol is supplied as a bitmask of NE_AUTH_* * values. For NE_AUTH_NEGOTIATE, the creds and userdata arguments * are ignored and may be NULL. * * These functions may be called multiple times per session to * register callbacks for different protocols. If the server presents * more than one protocol in an auth challenge, the following * algorithm will be used to determine which callback is used: * * - iterate over the registered callbacks in the order registered * - for each each callback, iterate over the known set of protocols * in order of algorithm strength (strongest first). * - if the protocol mask for that callback matches the protocol, * attempt authentication using this protocol. * * Therefore, if multiple calls to ne_add_server_auth or * ne_add_proxy_auth are used for a given session, the caller must * ensure that the order in which those calls are made reflects the * precedence of protocols to be used. */ void ne_add_server_auth(ne_session *sess, unsigned protocol, ne_auth_creds creds, void *userdata); void ne_add_proxy_auth(ne_session *sess, unsigned protocol, ne_auth_creds creds, void *userdata); /* Clear any cached authentication credentials for the given * session. */ void ne_forget_auth(ne_session *sess); NE_END_DECLS #endif /* NE_AUTH_H */ davix-R_0_5_0/deps/libneon/src/ne_basic.c000066400000000000000000000310571257152637300203520ustar00rootroot00000000000000/* Basic HTTP and WebDAV methods Copyright (C) 1999-2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #include /* for struct stat */ #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include "ne_request.h" #include "ne_alloc.h" #include "ne_utils.h" #include "ne_basic.h" #include "ne_207.h" #ifdef NE_HAVE_DAV #include "ne_uri.h" #include "ne_locks.h" #endif #include "ne_dates.h" #include "ne_internal.h" int ne_getmodtime(ne_session *sess, const char *uri, time_t *modtime) { ne_request *req = ne_request_create(sess, "HEAD", uri); const char *value; int ret; ret = ne_request_dispatch(req); value = ne_get_response_header(req, "Last-Modified"); if (ret == NE_OK && ne_get_status(req)->klass != 2) { *modtime = -1; ret = NE_ERROR; } else if (value) { *modtime = ne_httpdate_parse(value); } else { *modtime = -1; } ne_request_destroy(req); return ret; } #ifdef NE_LFS #define ne_fstat fstat64 typedef struct stat64 struct_stat; #else #define ne_fstat fstat typedef struct stat struct_stat; #endif /* PUT's from fd to URI */ int ne_put(ne_session *sess, const char *uri, int fd) { ne_request *req; struct_stat st; int ret; if (ne_fstat(fd, &st)) { int errnum = errno; char buf[200]; ne_set_error(sess, _("Could not determine file size: %s"), ne_strerror(errnum, buf, sizeof buf)); return NE_ERROR; } req = ne_request_create(sess, "PUT", uri); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, uri, 0); ne_lock_using_parent(req, uri); #endif ne_set_request_body_fd(req, fd, 0, st.st_size); ret = ne_request_dispatch(req); if (ret == NE_OK && ne_get_status(req)->klass != 2) ret = NE_ERROR; ne_request_destroy(req); return ret; } /* Dispatch a GET request REQ, writing the response body to FD fd. If * RANGE is non-NULL, then it is the value of the Range request * header, e.g. "bytes=1-5". Returns an NE_* error code. */ static int dispatch_to_fd(ne_request *req, int fd, const char *range) { ne_session *const sess = ne_get_session(req); const ne_status *const st = ne_get_status(req); int ret; size_t rlen; /* length of bytespec after "bytes=" */ rlen = range ? strlen(range + 6) : 0; do { const char *value; ret = ne_begin_request(req); if (ret != NE_OK) break; value = ne_get_response_header(req, "Content-Range"); /* For a 206 response, check that a Content-Range header is * given which matches the Range request header. */ if (range && st->code == 206 && (value == NULL || strncmp(value, "bytes ", 6) != 0 || strncmp(range + 6, value + 6, rlen) || (range[5 + rlen] != '-' && value[6 + rlen] != '/'))) { ne_set_error(sess, _("Response did not include requested range")); return NE_ERROR; } if ((range && st->code == 206) || (!range && st->klass == 2)) { ret = ne_read_response_to_fd(req, fd); } else { ret = ne_discard_response(req); } if (ret == NE_OK) ret = ne_end_request(req); } while (ret == NE_RETRY); return ret; } static int get_range_common(ne_session *sess, const char *uri, const char *brange, int fd) { ne_request *req = ne_request_create(sess, "GET", uri); const ne_status *status; int ret; ne_add_request_header(req, "Range", brange); ne_add_request_header(req, "Accept-Ranges", "bytes"); ret = dispatch_to_fd(req, fd, brange); status = ne_get_status(req); if (ret == NE_OK && status->code == 416) { /* connection is terminated too early with Apache/1.3, so we check * this even if ret == NE_ERROR... */ ne_set_error(sess, _("Range is not satisfiable")); ret = NE_ERROR; } else if (ret == NE_OK) { if (status->klass == 2 && status->code != 206) { ne_set_error(sess, _("Resource does not support ranged GET requests")); ret = NE_ERROR; } else if (status->klass != 2) { ret = NE_ERROR; } } ne_request_destroy(req); return ret; } int ne_get_range(ne_session *sess, const char *uri, ne_content_range *range, int fd) { char brange[64]; if (range->end == -1) { ne_snprintf(brange, sizeof brange, "bytes=%" FMT_NE_OFF_T "-", range->start); } else { ne_snprintf(brange, sizeof brange, "bytes=%" FMT_NE_OFF_T "-%" FMT_NE_OFF_T, range->start, range->end); } return get_range_common(sess, uri, brange, fd); } /* Get to given fd */ int ne_get(ne_session *sess, const char *uri, int fd) { ne_request *req = ne_request_create(sess, "GET", uri); int ret; ret = dispatch_to_fd(req, fd, NULL); if (ret == NE_OK && ne_get_status(req)->klass != 2) { ret = NE_ERROR; } ne_request_destroy(req); return ret; } /* Get to given fd */ int ne_post(ne_session *sess, const char *uri, int fd, const char *buffer) { ne_request *req = ne_request_create(sess, "POST", uri); int ret; ne_set_request_flag(req, NE_REQFLAG_IDEMPOTENT, 0); ne_set_request_body_buffer(req, buffer, strlen(buffer)); ret = dispatch_to_fd(req, fd, NULL); if (ret == NE_OK && ne_get_status(req)->klass != 2) { ret = NE_ERROR; } ne_request_destroy(req); return ret; } int ne_get_content_type(ne_request *req, ne_content_type *ct) { const char *value; char *sep, *stype; value = ne_get_response_header(req, "Content-Type"); if (value == NULL || strchr(value, '/') == NULL) { return -1; } ct->value = ne_strdup(value); stype = strchr(ct->value, '/'); *stype++ = '\0'; ct->type = ct->value; ct->charset = NULL; sep = strchr(stype, ';'); if (sep) { char *tok; /* look for the charset parameter. TODO; probably better to * hand-carve a parser than use ne_token/strstr/shave here. */ *sep++ = '\0'; do { tok = ne_qtoken(&sep, ';', "\"\'"); if (tok) { tok = strstr(tok, "charset="); if (tok) ct->charset = ne_shave(tok+8, "\"\'"); } else { break; } } while (sep != NULL); } /* set subtype, losing any trailing whitespace */ ct->subtype = ne_shave(stype, " \t"); if (ct->charset == NULL && ne_strcasecmp(ct->type, "text") == 0) { /* 3280§3.1: text/xml without charset implies us-ascii. */ if (ne_strcasecmp(ct->subtype, "xml") == 0) ct->charset = "us-ascii"; /* 2616§3.7.1: subtypes of text/ default to charset ISO-8859-1. */ else ct->charset = "ISO-8859-1"; } return 0; } static const struct options_map { const char *name; unsigned int cap; } options_map[] = { { "1", NE_CAP_DAV_CLASS1 }, { "2", NE_CAP_DAV_CLASS2 }, { "3", NE_CAP_DAV_CLASS3 }, { "", NE_CAP_MODDAV_EXEC }, { "access-control", NE_CAP_DAV_ACL }, { "version-control", NE_CAP_VER_CONTROL }, { "checkout-in-place", NE_CAP_CO_IN_PLACE }, { "version-history", NE_CAP_VER_HISTORY }, { "workspace", NE_CAP_WORKSPACE }, { "update", NE_CAP_UPDATE }, { "label", NE_CAP_LABEL }, { "working-resource", NE_CAP_WORK_RESOURCE }, { "merge", NE_CAP_MERGE }, { "baseline", NE_CAP_BASELINE }, { "version-controlled-collection", NE_CAP_VC_COLLECTION } }; static void parse_dav_header(const char *value, unsigned int *caps) { char *tokens = ne_strdup(value), *pnt = tokens; *caps = 0; do { char *tok = ne_qtoken(&pnt, ',', "\"'"); unsigned n; if (!tok) break; tok = ne_shave(tok, " \r\t\n"); for (n = 0; n < sizeof(options_map)/sizeof(options_map[0]); n++) { if (strcmp(tok, options_map[n].name) == 0) { *caps |= options_map[n].cap; } } } while (pnt != NULL); ne_free(tokens); } int ne_options2(ne_session *sess, const char *uri, unsigned int *caps) { ne_request *req = ne_request_create(sess, "OPTIONS", uri); int ret = ne_request_dispatch(req); const char *header = ne_get_response_header(req, "DAV"); if (header) parse_dav_header(header, caps); if (ret == NE_OK && ne_get_status(req)->klass != 2) { ret = NE_ERROR; } ne_request_destroy(req); return ret; } int ne_options(ne_session *sess, const char *path, ne_server_capabilities *caps) { int ret; unsigned int capmask = 0; memset(caps, 0, sizeof *caps); ret = ne_options2(sess, path, &capmask); caps->dav_class1 = capmask & NE_CAP_DAV_CLASS1 ? 1 : 0; caps->dav_class2 = capmask & NE_CAP_DAV_CLASS2 ? 1 : 0; caps->dav_executable = capmask & NE_CAP_MODDAV_EXEC ? 1 : 0; return ret; } #ifdef NE_HAVE_DAV void ne_add_depth_header(ne_request *req, int depth) { const char *value; switch(depth) { case NE_DEPTH_ZERO: value = "0"; break; case NE_DEPTH_ONE: value = "1"; break; default: value = "infinity"; break; } ne_add_request_header(req, "Depth", value); } static int copy_or_move(ne_session *sess, int is_move, int overwrite, int depth, const char *src, const char *dest) { ne_request *req = ne_request_create( sess, is_move?"MOVE":"COPY", src ); /* 2518 S8.9.2 says only use Depth: infinity with MOVE. */ if (!is_move) { ne_add_depth_header(req, depth); } #ifdef NE_HAVE_DAV if (is_move) { ne_lock_using_resource(req, src, NE_DEPTH_INFINITE); } ne_lock_using_resource(req, dest, NE_DEPTH_INFINITE); /* And we need to be able to add members to the destination's parent */ ne_lock_using_parent(req, dest); #endif if (ne_get_session_flag(sess, NE_SESSFLAG_RFC4918)) { ne_add_request_header(req, "Destination", dest); } else { ne_print_request_header(req, "Destination", "%s://%s%s", ne_get_scheme(sess), ne_get_server_hostport(sess), dest); } ne_add_request_header(req, "Overwrite", overwrite?"T":"F"); return ne_simple_request(sess, req); } int ne_copy(ne_session *sess, int overwrite, int depth, const char *src, const char *dest) { return copy_or_move(sess, 0, overwrite, depth, src, dest); } int ne_move(ne_session *sess, int overwrite, const char *src, const char *dest) { return copy_or_move(sess, 1, overwrite, 0, src, dest); } /* Deletes the specified resource. (and in only two lines of code!) */ int ne_delete(ne_session *sess, const char *uri) { ne_request *req = ne_request_create(sess, "DELETE", uri); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, uri, NE_DEPTH_INFINITE); ne_lock_using_parent(req, uri); #endif /* joe: I asked on the DAV WG list about whether we might get a * 207 error back from a DELETE... conclusion, you shouldn't if * you don't send the Depth header, since we might be an HTTP/1.1 * client and a 2xx response indicates success to them. But * it's all a bit unclear. In any case, DAV servers today do * return 207 to DELETE even if we don't send the Depth header. * So we handle 207 errors appropriately. */ return ne_simple_request(sess, req); } int ne_mkcol(ne_session *sess, const char *uri) { ne_request *req; char *real_uri; int ret; if (ne_path_has_trailing_slash(uri)) { real_uri = ne_strdup(uri); } else { real_uri = ne_concat(uri, "/", NULL); } req = ne_request_create(sess, "MKCOL", real_uri); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, real_uri, 0); ne_lock_using_parent(req, real_uri); #endif ret = ne_simple_request(sess, req); ne_free(real_uri); return ret; } #endif /* NE_HAVE_DAV */ davix-R_0_5_0/deps/libneon/src/ne_basic.h000066400000000000000000000140041257152637300203500ustar00rootroot00000000000000/* HTTP/1.1 methods Copyright (C) 1999-2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_BASIC_H #define NE_BASIC_H #include /* for time_t */ #include "ne_request.h" NE_BEGIN_DECLS /* Perform a GET request on resource at 'path', writing the entity * body which is returned to 'fd'. */ int ne_get(ne_session *sess, const char *path, int fd); /* Perform a PUT request on resource at 'path', reading the entity * body to submit from 'fd'. */ int ne_put(ne_session *sess, const char *path, int fd); #define NE_DEPTH_ZERO (0) #define NE_DEPTH_ONE (1) #define NE_DEPTH_INFINITE (2) /* For ne_copy and ne_move: * * If a resource exists at "dest" and overwrite is zero, the operation * will fail; if overwrite is non-zero, any existing resource will * be over-written. */ /* Copy resource from 'src to 'dest' paths. If 'src' identifies a * collection resource, depth may be NE_DEPTH_ZERO to request that the * collection and its properties are to be copied, or * NE_DEPTH_INFINITE to request that the collection and its contents * are to be copied. Returns NE_* error code. */ int ne_copy(ne_session *sess, int overwrite, int depth, const char *src, const char *dest); /* Move resource from 'src' to 'dest' path. Returns NE_* error * code. */ int ne_move(ne_session *sess, int overwrite, const char *src, const char *dest); /* Delete resource at 'path'. Returns NE_* error code. */ int ne_delete(ne_session *sess, const char *path); /* Create a collection at 'path', which is required to have a trailing * slash. Returns NE_* error code. */ int ne_mkcol(ne_session *sess, const char *path); /* Adds a Depth: header to a request. */ void ne_add_depth_header(ne_request *req, int depth); /* Retrieve modification time of resource at location 'path', using * the HEAD method, placing parsed time in *modtime. *modtime is set * to -1 if no Last-Modified response header was given, or the date * given could not be parsed. Returns NE_* error code. */ int ne_getmodtime(ne_session *sess, const char *path, time_t *modtime); typedef struct { const char *type, *subtype; const char *charset; char *value; } ne_content_type; /* Retrieve the content-type of the response; returns zero if response * had valid content-type, in which case all fields in *ctype are set * (and never NULL); the caller must free(ctype->value) after use. * Returns non-zero on error, in which case *ctype is not altered. */ int ne_get_content_type(ne_request *req, ne_content_type *ctype); /* DEPRECATED: Server capabilities. */ typedef struct { unsigned int dav_class1; /* True if Class 1 WebDAV server */ unsigned int dav_class2; /* True if Class 2 WebDAV server */ unsigned int dav_executable; /* True if supports the 'executable' * property a. la. mod_dav */ } ne_server_capabilities; /* DEPRECATED: Determines server capabilities (using OPTIONS). */ int ne_options(ne_session *sess, const char *path, ne_server_capabilities *caps); #define NE_CAP_DAV_CLASS1 (0x0001) /* Class 1 WebDAV (RFC 2518) */ #define NE_CAP_DAV_CLASS2 (0x0002) /* Class 2 WebDAV (RFC 2518) */ #define NE_CAP_DAV_CLASS3 (0x0004) /* Class 3 WebDAV (RFC 4918) */ #define NE_CAP_MODDAV_EXEC (0x0008) /* mod_dav "executable" property */ #define NE_CAP_DAV_ACL (0x0010) /* WebDAV ACL (RFC 3744) */ #define NE_CAP_VER_CONTROL (0x0020) /* DeltaV version-control */ #define NE_CAP_CO_IN_PLACE (0x0040) /* DeltaV checkout-in-place */ #define NE_CAP_VER_HISTORY (0x0080) /* DeltaV version-history */ #define NE_CAP_WORKSPACE (0x0100) /* DeltaV workspace */ #define NE_CAP_UPDATE (0x0200) /* DeltaV update */ #define NE_CAP_LABEL (0x0400) /* DeltaV label */ #define NE_CAP_WORK_RESOURCE (0x0800) /* DeltaV working-resouce */ #define NE_CAP_MERGE (0x1000) /* DeltaV merge */ #define NE_CAP_BASELINE (0x2000) /* DeltaV baseline */ #define NE_CAP_ACTIVITY (0x4000) /* DeltaV activity */ #define NE_CAP_VC_COLLECTION (0x8000) /* DeltaV version-controlled-collection */ /* Determines resource capailities, using an OPTIONS request. On * return, *caps is set to a bit-mask of the above NE_CAP_* constants * describing the advertised resource capabilities. */ int ne_options2(ne_session *sess, const char *path, unsigned int *caps); /* Defines a range of bytes, starting at 'start' and ending * at 'end'. 'total' is the number of bytes in the range. */ typedef struct { ne_off_t start, end, total; } ne_content_range; /* Partial GET. range->start must be >= 0. range->total is ignored. * * If range->end is -1, then the rest of the resource from start is * requested, and range->total and end are filled in on success. * * Otherwise, bytes from range->start to range->end are requested. * * This will write to the CURRENT position of f; so if you want * to do a resume download, use: * struct ne_content_range range; * range.start = resume_from; * range.end = range.start + 999; (= 1000 bytes) * fseek(myfile, resume_from, SEEK_SET); * ne_get_range(sess, path, &range, myfile); */ int ne_get_range(ne_session *sess, const char *path, ne_content_range *range, int fd); /* Post using buffer as request-body: stream response into f */ int ne_post(ne_session *sess, const char *path, int fd, const char *buffer); NE_END_DECLS #endif /* NE_BASIC_H */ davix-R_0_5_0/deps/libneon/src/ne_compress.c000066400000000000000000000324361257152637300211260ustar00rootroot00000000000000/* Handling of compressed HTTP responses Copyright (C) 2001-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include "ne_request.h" #include "ne_compress.h" #include "ne_utils.h" #include "ne_internal.h" #ifdef NE_HAVE_ZLIB #include /* Adds support for the 'gzip' Content-Encoding in HTTP. gzip is a * file format which wraps the DEFLATE compression algorithm. zlib * implements DEFLATE: we have to unwrap the gzip format (specified in * RFC1952) as it comes off the wire, and hand off chunks of data to * be inflated. */ struct ne_decompress_s { ne_request *request; /* associated request. */ ne_session *session; /* associated session. */ /* temporary buffer for holding inflated data. */ char outbuf[NE_BUFSIZ]; z_stream zstr; int zstrinit; /* non-zero if zstr has been initialized */ /* pass blocks back to this. */ ne_block_reader reader; ne_accept_response acceptor; void *userdata; /* buffer for gzip header bytes. */ unsigned char header[10]; size_t hdrcount; /* bytes in header */ unsigned char footer[8]; size_t footcount; /* bytes in footer. */ /* CRC32 checksum: odd that zlib uses uLong for this since it is a * 64-bit integer on LP64 platforms. */ uLong checksum; /* current state. */ enum state { NE_Z_BEFORE_DATA, /* not received any response blocks yet. */ NE_Z_PASSTHROUGH, /* response not compressed: passing through. */ NE_Z_IN_HEADER, /* received a few bytes of response data, but not * got past the gzip header yet. */ NE_Z_POST_HEADER, /* waiting for the end of the NUL-terminated bits. */ NE_Z_INFLATING, /* inflating response bytes. */ NE_Z_AFTER_DATA, /* after data; reading CRC32 & ISIZE */ NE_Z_FINISHED /* stream is finished. */ } state; }; /* Convert 'buf' to unsigned int; 'buf' must be 'unsigned char *' */ #define BUF2UINT(buf) (((buf)[3]<<24) + ((buf)[2]<<16) + ((buf)[1]<<8) + (buf)[0]) #define ID1 0x1f #define ID2 0x8b #define HDR_DONE 0 #define HDR_EXTENDED 1 #define HDR_ERROR 2 #define HDR_ID1(ctx) ((ctx)->header[0]) #define HDR_ID2(ctx) ((ctx)->header[1]) #define HDR_CMETH(ctx) ((ctx)->header[2]) #define HDR_FLAGS(ctx) ((ctx)->header[3]) #define HDR_MTIME(ctx) (BUF2UINT(&(ctx)->header[4])) #define HDR_XFLAGS(ctx) ((ctx)->header[8]) #define HDR_OS(ctx) ((ctx)->header[9]) /* parse_header parses the gzip header, sets the next state and returns * HDR_DONE: all done, bytes following are raw DEFLATE data. * HDR_EXTENDED: all done, expect a NUL-termianted string * before the DEFLATE data * HDR_ERROR: invalid header, give up (session error is set). */ static int parse_header(ne_decompress *ctx) { NE_DEBUG(NE_DBG_HTTP, "ID1: %d ID2: %d, cmeth %d, flags %d", HDR_ID1(ctx), HDR_ID2(ctx), HDR_CMETH(ctx), HDR_FLAGS(ctx)); if (HDR_ID1(ctx) != ID1 || HDR_ID2(ctx) != ID2 || HDR_CMETH(ctx) != 8) { ne_set_error(ctx->session, "Compressed stream invalid"); return HDR_ERROR; } NE_DEBUG(NE_DBG_HTTP, "mtime: %d, xflags: %d, os: %d", HDR_MTIME(ctx), HDR_XFLAGS(ctx), HDR_OS(ctx)); /* TODO: we can only handle one NUL-terminated extensions field * currently. Really, we should count the number of bits set, and * skip as many fields as bits set (bailing if any reserved bits * are set. */ if (HDR_FLAGS(ctx) == 8) { ctx->state = NE_Z_POST_HEADER; return HDR_EXTENDED; } else if (HDR_FLAGS(ctx) != 0) { ne_set_error(ctx->session, "Compressed stream not supported"); return HDR_ERROR; } NE_DEBUG(NE_DBG_HTTP, "compress: Good stream."); ctx->state = NE_Z_INFLATING; return HDR_DONE; } /* Process extra 'len' bytes of 'buf' which were received after the * DEFLATE data. */ static int process_footer(ne_decompress *ctx, const unsigned char *buf, size_t len) { if (len + ctx->footcount > 8) { ne_set_error(ctx->session, "Too many bytes (%" NE_FMT_SIZE_T ") in gzip footer", len); return -1; } else { memcpy(ctx->footer + ctx->footcount, buf, len); ctx->footcount += len; if (ctx->footcount == 8) { uLong crc = BUF2UINT(ctx->footer) & 0xFFFFFFFF; if (crc == ctx->checksum) { ctx->state = NE_Z_FINISHED; NE_DEBUG(NE_DBG_HTTP, "compress: End of response; checksum match."); } else { NE_DEBUG(NE_DBG_HTTP, "compress: End of response; checksum mismatch: " "given %lu vs computed %lu\n", crc, ctx->checksum); ne_set_error(ctx->session, "Checksum invalid for compressed stream"); return -1; } } } return 0; } /* A zlib function failed with 'code'; set the session error string * appropriately. */ static void set_zlib_error(ne_decompress *ctx, const char *msg, int code) { if (ctx->zstr.msg) ne_set_error(ctx->session, "%s: %s", msg, ctx->zstr.msg); else { const char *err; switch (code) { case Z_STREAM_ERROR: err = "stream error"; break; case Z_DATA_ERROR: err = "data corrupt"; break; case Z_MEM_ERROR: err = "out of memory"; break; case Z_BUF_ERROR: err = "buffer error"; break; case Z_VERSION_ERROR: err = "library version mismatch"; break; default: err = "unknown error"; break; } ne_set_error(ctx->session, _("%s: %s (code %d)"), msg, err, code); } } /* Inflate response buffer 'buf' of length 'len'. */ static int do_inflate(ne_decompress *ctx, const char *buf, size_t len) { int ret; ctx->zstr.avail_in = len; ctx->zstr.next_in = (unsigned char *)buf; ctx->zstr.total_in = 0; do { ctx->zstr.avail_out = sizeof ctx->outbuf; ctx->zstr.next_out = (unsigned char *)ctx->outbuf; ctx->zstr.total_out = 0; ret = inflate(&ctx->zstr, Z_NO_FLUSH); NE_DEBUG(NE_DBG_HTTP, "compress: inflate %d, %ld bytes out, %d remaining\n", ret, ctx->zstr.total_out, ctx->zstr.avail_in); #if 0 NE_DEBUG(NE_DBG_HTTPBODY, "Inflated body block (%ld):\n[%.*s]\n", ctx->zstr.total_out, (int)ctx->zstr.total_out, ctx->outbuf); #endif /* update checksum. */ ctx->checksum = crc32(ctx->checksum, (unsigned char *)ctx->outbuf, ctx->zstr.total_out); /* pass on the inflated data, if any */ if (ctx->zstr.total_out > 0) { int rret = ctx->reader(ctx->userdata, ctx->outbuf, ctx->zstr.total_out); if (rret) return rret; } } while (ret == Z_OK && ctx->zstr.avail_in > 0); if (ret == Z_STREAM_END) { NE_DEBUG(NE_DBG_HTTP, "compress: end of data stream, %d bytes remain.", ctx->zstr.avail_in); /* process the footer. */ ctx->state = NE_Z_AFTER_DATA; return process_footer(ctx, ctx->zstr.next_in, ctx->zstr.avail_in); } else if (ret != Z_OK) { set_zlib_error(ctx, _("Could not inflate data"), ret); return NE_ERROR; } return 0; } /* Callback which is passed blocks of the response body. */ static int gz_reader(void *ud, const char *buf, size_t len) { ne_decompress *ctx = ud; const char *zbuf; size_t count; const char *hdr; if (len == 0) { /* End of response: */ switch (ctx->state) { case NE_Z_BEFORE_DATA: hdr = ne_get_response_header(ctx->request, "Content-Encoding"); if (hdr && ne_strcasecmp(hdr, "gzip") == 0) { /* response was truncated: return error. */ break; } /* else, fall through */ case NE_Z_FINISHED: /* complete gzip response */ case NE_Z_PASSTHROUGH: /* complete uncompressed response */ return ctx->reader(ctx->userdata, buf, 0); default: /* invalid state: truncated response. */ break; } /* else: truncated response, fail. */ ne_set_error(ctx->session, "Compressed response was truncated"); return NE_ERROR; } switch (ctx->state) { case NE_Z_PASSTHROUGH: /* move along there. */ return ctx->reader(ctx->userdata, buf, len); case NE_Z_FINISHED: /* Could argue for tolerance, and ignoring trailing content; * but it could mean something more serious. */ if (len > 0) { ne_set_error(ctx->session, "Unexpected content received after compressed stream"); return NE_ERROR; } break; case NE_Z_BEFORE_DATA: /* work out whether this is a compressed response or not. */ hdr = ne_get_response_header(ctx->request, "Content-Encoding"); if (hdr && ne_strcasecmp(hdr, "gzip") == 0) { int ret; NE_DEBUG(NE_DBG_HTTP, "compress: got gzipped stream."); /* inflateInit2() works here where inflateInit() doesn't. */ ret = inflateInit2(&ctx->zstr, -MAX_WBITS); if (ret != Z_OK) { set_zlib_error(ctx, _("Could not initialize zlib"), ret); return -1; } ctx->zstrinit = 1; } else { /* No Content-Encoding header: pass it on. TODO: we could * hack it and register the real callback now. But that * would require add_resp_body_rdr to have defined * ordering semantics etc etc */ ctx->state = NE_Z_PASSTHROUGH; return ctx->reader(ctx->userdata, buf, len); } ctx->state = NE_Z_IN_HEADER; /* FALLTHROUGH */ case NE_Z_IN_HEADER: /* copy as many bytes as possible into the buffer. */ if (len + ctx->hdrcount > 10) { count = 10 - ctx->hdrcount; } else { count = len; } memcpy(ctx->header + ctx->hdrcount, buf, count); ctx->hdrcount += count; /* have we got the full header yet? */ if (ctx->hdrcount != 10) { return 0; } buf += count; len -= count; switch (parse_header(ctx)) { case HDR_EXTENDED: if (len == 0) return 0; break; case HDR_ERROR: return NE_ERROR; case HDR_DONE: if (len > 0) { return do_inflate(ctx, buf, len); } break; } /* FALLTHROUGH */ case NE_Z_POST_HEADER: /* eating the filename string. */ zbuf = memchr(buf, '\0', len); if (zbuf == NULL) { /* not found it yet. */ return 0; } NE_DEBUG(NE_DBG_HTTP, "compresss: skipped %" NE_FMT_SIZE_T " header bytes.\n", zbuf - buf); /* found end of string. */ len -= (1 + zbuf - buf); buf = zbuf + 1; ctx->state = NE_Z_INFLATING; if (len == 0) { /* end of string was at end of buffer. */ return 0; } /* FALLTHROUGH */ case NE_Z_INFLATING: return do_inflate(ctx, buf, len); case NE_Z_AFTER_DATA: return process_footer(ctx, (unsigned char *)buf, len); } return 0; } /* Prepare for a compressed response; may be called many times per * request, for auth retries etc. */ static void gz_pre_send(ne_request *r, void *ud, ne_buffer *req) { ne_decompress *ctx = ud; if (ctx->request == r) { NE_DEBUG(NE_DBG_HTTP, "compress: Initialization."); /* (Re-)Initialize the context */ ctx->state = NE_Z_BEFORE_DATA; if (ctx->zstrinit) inflateEnd(&ctx->zstr); ctx->zstrinit = 0; ctx->hdrcount = ctx->footcount = 0; ctx->checksum = crc32(0L, Z_NULL, 0); } } /* Wrapper for user-passed acceptor function. */ static int gz_acceptor(void *userdata, ne_request *req, const ne_status *st) { ne_decompress *ctx = userdata; return ctx->acceptor(ctx->userdata, req, st); } /* A slightly ugly hack: the pre_send hook is scoped per-session, so * must check that the invoking request is this one, before doing * anything, and must be unregistered when the context is * destroyed. */ ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt, ne_block_reader rdr, void *userdata) { ne_decompress *ctx = ne_calloc(sizeof *ctx); ne_add_request_header(req, "Accept-Encoding", "gzip"); ne_add_response_body_reader(req, gz_acceptor, gz_reader, ctx); ctx->reader = rdr; ctx->userdata = userdata; ctx->session = ne_get_session(req); ctx->request = req; ctx->acceptor = acpt; ne_hook_pre_send(ne_get_session(req), gz_pre_send, ctx); return ctx; } void ne_decompress_destroy(ne_decompress *ctx) { if (ctx->zstrinit) inflateEnd(&ctx->zstr); ne_unhook_pre_send(ctx->session, gz_pre_send, ctx); ne_free(ctx); } #else /* !NE_HAVE_ZLIB */ /* Pass-through interface present to provide ABI compatibility. */ ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt, ne_block_reader rdr, void *userdata) { ne_add_response_body_reader(req, acpt, rdr, userdata); /* an arbitrary return value: don't confuse them by returning NULL. */ return (ne_decompress *)req; } void ne_decompress_destroy(ne_decompress *dc) { } #endif /* NE_HAVE_ZLIB */ davix-R_0_5_0/deps/libneon/src/ne_compress.h000066400000000000000000000033221257152637300211230ustar00rootroot00000000000000/* Compressed HTTP response handling Copyright (C) 2001-2004, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_COMPRESS_H #define NE_COMPRESS_H #include "ne_request.h" NE_BEGIN_DECLS typedef struct ne_decompress_s ne_decompress; /* Call this to register a 'reader' callback which will be passed * blocks of response body (if the 'acceptance' callback is * successful). If the response body is returned compressed by the * server, this reader will receive UNCOMPRESSED blocks. * * Returns pointer to context object which must be passed to * ne_decompress_destroy after the request has been dispatched, to * free any internal state. If an error occurs during decompression, * the request will be aborted and session error string set. */ ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response accpt, ne_block_reader rdr, void *userdata); /* Destroys decompression state. */ void ne_decompress_destroy(ne_decompress *ctx); NE_END_DECLS #endif /* NE_COMPRESS_H */ davix-R_0_5_0/deps/libneon/src/ne_dates.c000066400000000000000000000161651257152637300203740ustar00rootroot00000000000000/* Date manipulation routines Copyright (C) 1999-2006, Joe Orton Copyright (C) 2004 Jiang Lei This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif #include #ifdef HAVE_STRING_H #include #endif #ifdef WIN32 #include /* for TIME_ZONE_INFORMATION */ #endif #include "ne_alloc.h" #include "ne_dates.h" #include "ne_string.h" /* Generic date manipulation routines. */ /* ISO8601: 2001-01-01T12:30:00Z */ #define ISO8601_FORMAT_Z "%04d-%02d-%02dT%02d:%02d:%lfZ" #define ISO8601_FORMAT_M "%04d-%02d-%02dT%02d:%02d:%lf-%02d:%02d" #define ISO8601_FORMAT_P "%04d-%02d-%02dT%02d:%02d:%lf+%02d:%02d" /* RFC1123: Sun, 06 Nov 1994 08:49:37 GMT */ #define RFC1123_FORMAT "%3s, %02d %3s %4d %02d:%02d:%02d GMT" /* RFC850: Sunday, 06-Nov-94 08:49:37 GMT */ #define RFC1036_FORMAT "%10s %2d-%3s-%2d %2d:%2d:%2d GMT" /* asctime: Wed Jun 30 21:49:08 1993 */ #define ASCTIME_FORMAT "%3s %3s %2d %2d:%2d:%2d %4d" static const char rfc1123_weekdays[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char short_months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; #if defined(HAVE_STRUCT_TM_TM_GMTOFF) #define GMTOFF(t) ((t).tm_gmtoff) #elif defined(HAVE_STRUCT_TM___TM_GMTOFF) #define GMTOFF(t) ((t).__tm_gmtoff) #elif defined(WIN32) #define GMTOFF(t) (gmt_to_local_win32()) #elif defined(HAVE_TIMEZONE) /* FIXME: the following assumes fixed dst offset of 1 hour */ #define GMTOFF(t) (-timezone + ((t).tm_isdst > 0 ? 3600 : 0)) #else /* FIXME: work out the offset anyway. */ #define GMTOFF(t) (0) #endif #ifdef WIN32 time_t gmt_to_local_win32(void) { TIME_ZONE_INFORMATION tzinfo; DWORD dwStandardDaylight; long bias; dwStandardDaylight = GetTimeZoneInformation(&tzinfo); bias = tzinfo.Bias; if (dwStandardDaylight == TIME_ZONE_ID_STANDARD) bias += tzinfo.StandardBias; if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT) bias += tzinfo.DaylightBias; return (- bias * 60); } #endif /* Returns the time/date GMT, in RFC1123-type format: eg * Sun, 06 Nov 1994 08:49:37 GMT. */ char *ne_rfc1123_date(time_t anytime) { struct tm *gmt; char *ret; gmt = gmtime(&anytime); if (gmt == NULL) return NULL; ret = ne_malloc(29 + 1); /* dates are 29 chars long */ /* it goes: Sun, 06 Nov 1994 08:49:37 GMT */ ne_snprintf(ret, 30, RFC1123_FORMAT, rfc1123_weekdays[gmt->tm_wday], gmt->tm_mday, short_months[gmt->tm_mon], 1900 + gmt->tm_year, gmt->tm_hour, gmt->tm_min, gmt->tm_sec); return ret; } /* Takes an ISO-8601-formatted date string and returns the time_t. * Returns (time_t)-1 if the parse fails. */ time_t ne_iso8601_parse(const char *date) { struct tm gmt = {0}; int off_hour, off_min; double sec; off_t fix; int n; time_t result; /* it goes: ISO8601: 2001-01-01T12:30:00+03:30 */ if ((n = sscanf(date, ISO8601_FORMAT_P, &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday, &gmt.tm_hour, &gmt.tm_min, &sec, &off_hour, &off_min)) == 8) { gmt.tm_sec = (int)sec; fix = - off_hour * 3600 - off_min * 60; } /* it goes: ISO8601: 2001-01-01T12:30:00-03:30 */ else if ((n = sscanf(date, ISO8601_FORMAT_M, &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday, &gmt.tm_hour, &gmt.tm_min, &sec, &off_hour, &off_min)) == 8) { gmt.tm_sec = (int)sec; fix = off_hour * 3600 + off_min * 60; } /* it goes: ISO8601: 2001-01-01T12:30:00Z */ else if ((n = sscanf(date, ISO8601_FORMAT_Z, &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday, &gmt.tm_hour, &gmt.tm_min, &sec)) == 6) { gmt.tm_sec = (int)sec; fix = 0; } else { return (time_t)-1; } gmt.tm_year -= 1900; gmt.tm_isdst = -1; gmt.tm_mon--; result = mktime(&gmt) + fix; return result + GMTOFF(gmt); } /* Takes an RFC1123-formatted date string and returns the time_t. * Returns (time_t)-1 if the parse fails. */ time_t ne_rfc1123_parse(const char *date) { struct tm gmt = {0}; char wkday[4], mon[4]; int n; time_t result; /* it goes: Sun, 06 Nov 1994 08:49:37 GMT */ n = sscanf(date, RFC1123_FORMAT, wkday, &gmt.tm_mday, mon, &gmt.tm_year, &gmt.tm_hour, &gmt.tm_min, &gmt.tm_sec); /* Is it portable to check n==7 here? */ gmt.tm_year -= 1900; for (n=0; n<12; n++) if (strcmp(mon, short_months[n]) == 0) break; /* tm_mon comes out as 12 if the month is corrupt, which is desired, * since the mktime will then fail */ gmt.tm_mon = n; gmt.tm_isdst = -1; result = mktime(&gmt); return result + GMTOFF(gmt); } /* Takes a string containing a RFC1036-style date and returns the time_t */ time_t ne_rfc1036_parse(const char *date) { struct tm gmt = {0}; int n; char wkday[11], mon[4]; time_t result; /* RFC850/1036 style dates: Sunday, 06-Nov-94 08:49:37 GMT */ n = sscanf(date, RFC1036_FORMAT, wkday, &gmt.tm_mday, mon, &gmt.tm_year, &gmt.tm_hour, &gmt.tm_min, &gmt.tm_sec); if (n != 7) { return (time_t)-1; } /* portable to check n here? */ for (n=0; n<12; n++) if (strcmp(mon, short_months[n]) == 0) break; /* tm_mon comes out as 12 if the month is corrupt, which is desired, * since the mktime will then fail */ /* Defeat Y2K bug. */ if (gmt.tm_year < 50) gmt.tm_year += 100; gmt.tm_mon = n; gmt.tm_isdst = -1; result = mktime(&gmt); return result + GMTOFF(gmt); } /* (as)ctime dates are like: * Wed Jun 30 21:49:08 1993 */ time_t ne_asctime_parse(const char *date) { struct tm gmt = {0}; int n; char wkday[4], mon[4]; time_t result; n = sscanf(date, ASCTIME_FORMAT, wkday, mon, &gmt.tm_mday, &gmt.tm_hour, &gmt.tm_min, &gmt.tm_sec, &gmt.tm_year); /* portable to check n here? */ for (n=0; n<12; n++) if (strcmp(mon, short_months[n]) == 0) break; /* tm_mon comes out as 12 if the month is corrupt, which is desired, * since the mktime will then fail */ gmt.tm_mon = n; gmt.tm_isdst = -1; result = mktime(&gmt); return result + GMTOFF(gmt); } /* HTTP-date parser */ time_t ne_httpdate_parse(const char *date) { time_t tmp; tmp = ne_rfc1123_parse(date); if (tmp == -1) { tmp = ne_rfc1036_parse(date); if (tmp == -1) tmp = ne_asctime_parse(date); } return tmp; } davix-R_0_5_0/deps/libneon/src/ne_dates.h000066400000000000000000000031561257152637300203750ustar00rootroot00000000000000/* Date manipulation routines Copyright (C) 1999-2002, 2005, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_DATES_H #define NE_DATES_H #include #include "ne_defs.h" NE_BEGIN_DECLS /* Date manipulation routines as per RFC1123 and RFC1036 */ /* Return current date/time in RFC1123 format */ char *ne_rfc1123_date(time_t anytime); /* Returns time from date/time using the subset of the ISO8601 format * referenced in RFC2518 (e.g as used in the creationdate property in * the DAV: namespace). */ time_t ne_iso8601_parse(const char *date); /* Returns time from date/time in RFC1123 format */ time_t ne_rfc1123_parse(const char *date); time_t ne_rfc1036_parse(const char *date); /* Parses asctime date string */ time_t ne_asctime_parse(const char *date); /* Parse an HTTP-date as per RFC2616 */ time_t ne_httpdate_parse(const char *date); NE_END_DECLS #endif /* NE_DATES_H */ davix-R_0_5_0/deps/libneon/src/ne_defs.h000066400000000000000000000037321257152637300202160ustar00rootroot00000000000000/* Standard definitions for neon headers Copyright (C) 2003-2008, 2010, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #undef NE_BEGIN_DECLS #undef NE_END_DECLS #ifdef __cplusplus # define NE_BEGIN_DECLS extern "C" { # define NE_END_DECLS } #else # define NE_BEGIN_DECLS /* empty */ # define NE_END_DECLS /* empty */ #endif #ifndef NE_DEFS_H #define NE_DEFS_H #include #ifdef NE_LFS typedef off64_t ne_off_t; #else typedef off_t ne_off_t; #endif /* define ssize_t for Win32 */ #if defined(WIN32) && !defined(ssize_t) #define ssize_t int #endif #ifdef __NETWARE__ #include /* for time_t */ #endif #ifdef __GNUC__ #if __GNUC__ >= 3 #ifndef NE_PRIVATE #define NE_PRIVATE __attribute__((visibility ("hidden"))) #endif #define ne_attribute_malloc __attribute__((malloc)) #else #define ne_attribute_malloc #endif #if __GNUC__ > 3 #define ne_attribute_sentinel __attribute__((sentinel)) #else #define ne_attribute_sentinel #endif #define ne_attribute(x) __attribute__(x) #else #define ne_attribute(x) #define ne_attribute_malloc #define ne_attribute_sentinel #endif #ifndef NE_PRIVATE #define NE_PRIVATE #endif #ifndef NE_BUFSIZ #define NE_BUFSIZ 8192 #endif #ifndef NE_BUFSIZ_LARGE #define NE_BUFSIZ_LARGE (1 << 18) #endif #endif /* NE_DEFS_H */ davix-R_0_5_0/deps/libneon/src/ne_gnutls.c000066400000000000000000001210251257152637300206000ustar00rootroot00000000000000/* neon SSL/TLS support using GNU TLS Copyright (C) 2002-2010, Joe Orton Copyright (C) 2004, Aleix Conchillo Flaque This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif #include #include #include #include #include #include #ifdef NE_HAVE_TS_SSL #include #include #if LIBGNUTLS_VERSION_NUMBER < 0x020b01 #include GCRY_THREAD_OPTION_PTHREAD_IMPL; #endif #else #if LIBGNUTLS_VERSION_NUMBER < 0x020b01 #include #endif #endif #ifdef HAVE_ICONV #include #endif #include "ne_ssl.h" #include "ne_string.h" #include "ne_session.h" #include "ne_internal.h" #include "ne_private.h" #include "ne_privssl.h" #if LIBGNUTLS_VERSION_NUMBER >= 0x020302 /* The GnuTLS DN functions in 2.3.2 and later allow a simpler DN * abstraction to be used. */ #define HAVE_NEW_DN_API #endif struct ne_ssl_dname_s { #ifdef HAVE_NEW_DN_API gnutls_x509_dn_t dn; #else int subject; /* non-zero if this is the subject DN object */ gnutls_x509_crt cert; #endif }; struct ne_ssl_certificate_s { ne_ssl_dname subj_dn, issuer_dn; gnutls_x509_crt *chain; unsigned chain_len; ne_ssl_certificate *issuer; char *identity; }; struct ne_ssl_client_cert_s { gnutls_pkcs12 p12; int decrypted; /* non-zero if successfully decrypted. */ int keyless; ne_ssl_certificate cert; gnutls_x509_privkey pkey; char *friendly_name; }; /* Returns the highest used index in subject (or issuer) DN of * certificate CERT for OID, or -1 if no RDNs are present in the DN * using that OID. */ static int oid_find_highest_index(gnutls_x509_crt cert, int subject, const char *oid) { int ret, idx = -1; do { size_t len = 0; if (subject) ret = gnutls_x509_crt_get_dn_by_oid(cert, oid, ++idx, 0, NULL, &len); else ret = gnutls_x509_crt_get_issuer_dn_by_oid(cert, oid, ++idx, 0, NULL, &len); } while (ret == GNUTLS_E_SHORT_MEMORY_BUFFER); return idx - 1; } #ifdef HAVE_GNUTLS_X509_DN_GET_RDN_AVA /* New-style RDN handling introduced in GnuTLS 1.7.x. */ #ifdef HAVE_ICONV static void convert_dirstring(ne_buffer *buf, const char *charset, gnutls_datum *data) { iconv_t id = iconv_open("UTF-8", charset); size_t inlen = data->size, outlen = buf->length - buf->used; char *inbuf = (char *)data->data; char *outbuf = buf->data + buf->used - 1; if (id == (iconv_t)-1) { char err[128], err2[128]; ne_snprintf(err, sizeof err, "[unprintable in %s: %s]", charset, ne_strerror(errno, err2, sizeof err2)); ne_buffer_zappend(buf, err); return; } ne_buffer_grow(buf, buf->used + 64); while (inlen && outlen && iconv(id, &inbuf, &inlen, &outbuf, &outlen) == 0) ; iconv_close(id); buf->used += buf->length - buf->used - outlen; buf->data[buf->used - 1] = '\0'; } #endif /* From section 11.13 of the Dubuisson ASN.1 bible: */ #define TAG_UTF8 (12) #define TAG_PRINTABLE (19) #define TAG_T61 (20) #define TAG_IA5 (22) #define TAG_VISIBLE (26) #define TAG_UNIVERSAL (28) #define TAG_BMP (30) static void append_dirstring(ne_buffer *buf, gnutls_datum *data, unsigned long tag) { switch (tag) { case TAG_UTF8: case TAG_IA5: case TAG_PRINTABLE: case TAG_VISIBLE: ne_buffer_append(buf, (char *)data->data, data->size); break; #ifdef HAVE_ICONV case TAG_T61: convert_dirstring(buf, "ISO-8859-1", data); break; case TAG_BMP: convert_dirstring(buf, "UCS-2BE", data); break; #endif default: { char tmp[128]; ne_snprintf(tmp, sizeof tmp, _("[unprintable:#%lu]"), tag); ne_buffer_zappend(buf, tmp); } break; } } /* OIDs to not include in readable DNs by default: */ #define OID_emailAddress "1.2.840.113549.1.9.1" #define OID_commonName "2.5.4.3" #define CMPOID(a,o) ((a)->oid.size == sizeof(o) \ && memcmp((a)->oid.data, o, strlen(o)) == 0) char *ne_ssl_readable_dname(const ne_ssl_dname *name) { gnutls_x509_dn_t dn; int ret, rdn = 0, flag = 0; ne_buffer *buf; gnutls_x509_ava_st val; #ifdef HAVE_NEW_DN_API dn = name->dn; #else if (name->subject) ret = gnutls_x509_crt_get_subject(name->cert, &dn); else ret = gnutls_x509_crt_get_issuer(name->cert, &dn); if (ret) return ne_strdup(_("[unprintable]")); #endif /* HAVE_NEW_DN_API */ buf = ne_buffer_create(); /* Find the highest rdn... */ while (gnutls_x509_dn_get_rdn_ava(dn, rdn++, 0, &val) == 0) ; /* ..then iterate back to the first: */ while (--rdn >= 0) { int ava = 0; /* Iterate through all AVAs for multivalued AVAs; better than * ne_openssl can do! */ do { ret = gnutls_x509_dn_get_rdn_ava(dn, rdn, ava, &val); /* If the *only* attribute to append is the common name or * email address, use it; otherwise skip those * attributes. */ if (ret == 0 && val.value.size > 0 && ((!CMPOID(&val, OID_emailAddress) && !CMPOID(&val, OID_commonName)) || (buf->used == 1 && rdn == 0))) { flag = 1; if (buf->used > 1) ne_buffer_append(buf, ", ", 2); append_dirstring(buf, &val.value, val.value_tag); } ava++; } while (ret == 0); } return ne_buffer_finish(buf); } #else /* !HAVE_GNUTLS_X509_DN_GET_RDN_AVA */ /* Appends the value of RDN with given oid from certitifcate x5 * subject (if subject is non-zero), or issuer DN to buffer 'buf': */ static void append_rdn(ne_buffer *buf, gnutls_x509_crt x5, int subject, const char *oid) { int idx, top, ret; char rdn[50]; top = oid_find_highest_index(x5, subject, oid); for (idx = top; idx >= 0; idx--) { size_t rdnlen = sizeof rdn; if (subject) ret = gnutls_x509_crt_get_dn_by_oid(x5, oid, idx, 0, rdn, &rdnlen); else ret = gnutls_x509_crt_get_issuer_dn_by_oid(x5, oid, idx, 0, rdn, &rdnlen); if (ret < 0) return; if (buf->used > 1) { ne_buffer_append(buf, ", ", 2); } ne_buffer_append(buf, rdn, rdnlen); } } char *ne_ssl_readable_dname(const ne_ssl_dname *name) { ne_buffer *buf = ne_buffer_create(); int ret, idx = 0; do { char oid[32] = {0}; size_t oidlen = sizeof oid; ret = name->subject ? gnutls_x509_crt_get_dn_oid(name->cert, idx, oid, &oidlen) : gnutls_x509_crt_get_issuer_dn_oid(name->cert, idx, oid, &oidlen); if (ret == 0) { append_rdn(buf, name->cert, name->subject, oid); idx++; } } while (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); return ne_buffer_finish(buf); } #endif /* HAVE_GNUTLS_X509_DN_GET_RDN_AVA */ int ne_ssl_dname_cmp(const ne_ssl_dname *dn1, const ne_ssl_dname *dn2) { char c1[1024], c2[1024]; size_t s1 = sizeof c1, s2 = sizeof c2; #ifdef HAVE_NEW_DN_API if (gnutls_x509_dn_export(dn1->dn, GNUTLS_X509_FMT_DER, c1, &s1)) return 1; if (gnutls_x509_dn_export(dn2->dn, GNUTLS_X509_FMT_DER, c2, &s2)) return -1; #else int ret; if (dn1->subject) ret = gnutls_x509_crt_get_dn(dn1->cert, c1, &s1); else ret = gnutls_x509_crt_get_issuer_dn(dn1->cert, c1, &s1); if (ret) return 1; if (dn2->subject) ret = gnutls_x509_crt_get_dn(dn2->cert, c2, &s2); else ret = gnutls_x509_crt_get_issuer_dn(dn2->cert, c2, &s2); if (ret) return -1; #endif /* HAVE_NEW_DN_API */ if (s1 != s2) return s2 - s1; return memcmp(c1, c2, s1); } void ne_ssl_clicert_free(ne_ssl_client_cert *cc) { if (cc->p12) gnutls_pkcs12_deinit(cc->p12); if (cc->decrypted) { unsigned n; if (cc->cert.identity) ne_free(cc->cert.identity); if (cc->pkey) gnutls_x509_privkey_deinit(cc->pkey); for (n = 0; n < cc->cert.chain_len; ++n) gnutls_x509_crt_deinit(cc->cert.chain[n]); gnutls_free(cc->cert.chain); } if (cc->friendly_name) ne_free(cc->friendly_name); ne_free(cc); } void ne_ssl_cert_validity_time(const ne_ssl_certificate *cert, time_t *from, time_t *until) { if (from) { *from = gnutls_x509_crt_get_activation_time(cert->chain[0]); } if (until) { *until = gnutls_x509_crt_get_expiration_time(cert->chain[0]); } } /* Check certificate identity. Returns zero if identity matches; 1 if * identity does not match, or <0 if the certificate had no identity. * If 'identity' is non-NULL, store the malloc-allocated identity in * *identity. If 'server' is non-NULL, it must be the network address * of the server in use, and identity must be NULL. */ static int check_identity(const ne_uri *server, gnutls_x509_crt cert, char **identity) { char name[255]; unsigned int critical; int ret, seq = 0; int match = 0, found = 0; size_t len; const char *hostname; hostname = server ? server->host : ""; do { len = sizeof name - 1; ret = gnutls_x509_crt_get_subject_alt_name(cert, seq, name, &len, &critical); switch (ret) { case GNUTLS_SAN_DNSNAME: name[len] = '\0'; if (identity && !found) *identity = ne_strdup(name); match = ne__ssl_match_hostname(name, len, hostname); found = 1; break; case GNUTLS_SAN_IPADDRESS: { ne_inet_addr *ia; if (len == 4) ia = ne_iaddr_make(ne_iaddr_ipv4, (unsigned char *)name); else if (len == 16) ia = ne_iaddr_make(ne_iaddr_ipv6, (unsigned char *)name); else ia = NULL; if (ia) { char buf[128]; match = strcmp(hostname, ne_iaddr_print(ia, buf, sizeof buf)) == 0; if (identity) *identity = ne_strdup(buf); found = 1; ne_iaddr_free(ia); } else { NE_DEBUG(NE_DBG_SSL, "iPAddress name with unsupported " "address type (length %" NE_FMT_SIZE_T "), skipped.\n", len); } } break; case GNUTLS_SAN_URI: { ne_uri uri; name[len] = '\0'; if (ne_uri_parse(name, &uri) == 0 && uri.host && uri.scheme) { ne_uri tmp; if (identity && !found) *identity = ne_strdup(name); found = 1; if (server) { /* For comparison purposes, all that matters is * host, scheme and port; ignore the rest. */ memset(&tmp, 0, sizeof tmp); tmp.host = uri.host; tmp.scheme = uri.scheme; tmp.port = uri.port; match = ne_uri_cmp(server, &tmp) == 0; } } ne_uri_free(&uri); } break; default: break; } seq++; } while (!match && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); /* Check against the commonName if no DNS alt. names were found, * as per RFC3280. */ if (!found) { seq = oid_find_highest_index(cert, 1, GNUTLS_OID_X520_COMMON_NAME); if (seq >= 0) { len = sizeof name; name[0] = '\0'; ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, seq, 0, name, &len); if (ret == 0) { if (identity) *identity = ne_strdup(name); match = ne__ssl_match_hostname(name, len, hostname); } } else { return -1; } } if (*hostname) NE_DEBUG(NE_DBG_SSL, "ssl: Identity match for '%s': %s", hostname, match ? "good" : "bad"); return match ? 0 : 1; } /* Populate an ne_ssl_certificate structure from an X509 object. Note * that x5 is owned by returned cert object and must not be otherwise * freed by the caller. */ static ne_ssl_certificate *populate_cert(ne_ssl_certificate *cert, gnutls_x509_crt x5) { #ifdef HAVE_NEW_DN_API gnutls_x509_crt_get_subject(x5, &cert->subj_dn.dn); gnutls_x509_crt_get_issuer(x5, &cert->issuer_dn.dn); #else cert->subj_dn.cert = x5; cert->subj_dn.subject = 1; cert->issuer_dn.cert = x5; cert->issuer_dn.subject = 0; #endif cert->issuer = NULL; cert->chain_len = 1; cert->chain = gnutls_malloc(sizeof(gnutls_x509_crt)); cert->chain[0] = x5; cert->identity = NULL; check_identity(NULL, x5, &cert->identity); return cert; } /* Returns a copy certificate of certificate SRC. */ static gnutls_x509_crt x509_crt_copy(gnutls_x509_crt src) { int ret; size_t size; gnutls_datum tmp; gnutls_x509_crt dest; if (gnutls_x509_crt_init(&dest) != 0) { return NULL; } if (gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, NULL, &size) != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_x509_crt_deinit(dest); return NULL; } tmp.data = ne_malloc(size); ret = gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, tmp.data, &size); if (ret == 0) { tmp.size = size; ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER); } if (ret) { gnutls_x509_crt_deinit(dest); dest = NULL; } ne_free(tmp.data); return dest; } /* Duplicate a client certificate, which must be in the decrypted state. */ ne_ssl_client_cert *dup_client_cert(const ne_ssl_client_cert *cc) { int ret, n; ne_ssl_client_cert *newcc = ne_calloc(sizeof *newcc); newcc->decrypted = 1; if (cc->keyless) { newcc->keyless = 1; } else { ret = gnutls_x509_privkey_init(&newcc->pkey); if (ret != 0) goto dup_error; ret = gnutls_x509_privkey_cpy(newcc->pkey, cc->pkey); if (ret != 0) goto dup_error; } newcc->cert.chain = gnutls_malloc(sizeof(gnutls_x509_crt_t) * cc->cert.chain_len); memset(newcc->cert.chain, 0, sizeof(gnutls_x509_crt_t) * cc->cert.chain_len); newcc->cert.chain_len = cc->cert.chain_len; for (n = 0; n < cc->cert.chain_len; ++n) { newcc->cert.chain[n] = x509_crt_copy(cc->cert.chain[n]); if (!newcc->cert.chain[n]) goto dup_error; } return newcc; dup_error: if (newcc->pkey) gnutls_x509_privkey_deinit(newcc->pkey); if (newcc->cert.chain) { for (n = 0; n < cc->cert.chain_len; ++n) gnutls_x509_crt_deinit(newcc->cert.chain[n]); gnutls_free(newcc->cert.chain); } ne_free(newcc); return NULL; } ne_ssl_client_cert * ne_ssl_dup_client_cert(const ne_ssl_client_cert *cc) { return dup_client_cert(cc); } /* Callback invoked when the SSL server requests a client certificate. */ static int provide_client_cert(gnutls_session session, const gnutls_datum *req_ca_rdn, int nreqs, const gnutls_pk_algorithm *sign_algos, int sign_algos_length, gnutls_retr_st *st) { ne_session *sess = gnutls_session_get_ptr(session); if (!sess) { return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; } NE_DEBUG(NE_DBG_SSL, "ssl: Client cert provider callback; %d CA names.", nreqs); if (!sess->client_cert && sess->ssl_provide_fn) { #ifdef HAVE_NEW_DN_API const ne_ssl_dname **dns; ne_ssl_dname *dnarray; unsigned dncount = 0; int n; dns = ne_malloc(nreqs * sizeof(ne_ssl_dname *)); dnarray = ne_calloc(nreqs * sizeof(ne_ssl_dname)); for (n = 0; n < nreqs; n++) { gnutls_x509_dn_t dn; if (gnutls_x509_dn_init(&dn) == 0) { dnarray[n].dn = dn; if (gnutls_x509_dn_import(dn, &req_ca_rdn[n]) == 0) { dns[dncount++] = &dnarray[n]; } else { gnutls_x509_dn_deinit(dn); } } } NE_DEBUG(NE_DBG_SSL, "ssl: Mapped %d CA names to %u DN objects.", nreqs, dncount); sess->ssl_provide_fn(sess->ssl_provide_ud, sess, dns, dncount); for (n = 0; n < nreqs; n++) { if (dnarray[n].dn) { gnutls_x509_dn_deinit(dnarray[n].dn); } } ne_free(dns); ne_free(dnarray); #else /* HAVE_NEW_DN_API */ /* Nothing to do here other than pretend no CA names were * given, and hope the caller can cope. */ sess->ssl_provide_fn(sess->ssl_provide_ud, sess, NULL, 0); #endif } if (sess->client_cert) { gnutls_certificate_type type = gnutls_certificate_type_get(session); if (type == GNUTLS_CRT_X509) { NE_DEBUG(NE_DBG_SSL, "Supplying client certificate."); st->type = type; st->ncerts = sess->client_cert->cert.chain_len;; st->cert.x509 = sess->client_cert->cert.chain; st->key.x509 = sess->client_cert->pkey; /* tell GNU TLS not to deallocate the certs. */ st->deinit_all = 0; } else { return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } } else { NE_DEBUG(NE_DBG_SSL, "No client certificate supplied."); st->ncerts = 0; sess->ssl_cc_requested = 1; return 0; } return 0; } void ne_ssl_set_clicert(ne_session *sess, const ne_ssl_client_cert *cc) { sess->client_cert = dup_client_cert(cc); } ne_ssl_context *ne_ssl_context_create(int flags) { ne_ssl_context *ctx = ne_calloc(sizeof *ctx); gnutls_certificate_allocate_credentials(&ctx->cred); if (flags == NE_SSL_CTX_CLIENT) { gnutls_certificate_client_set_retrieve_function(ctx->cred, provide_client_cert); } gnutls_certificate_set_verify_flags(ctx->cred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); return ctx; } int ne_ssl_context_keypair(ne_ssl_context *ctx, const char *cert, const char *key) { gnutls_certificate_set_x509_key_file(ctx->cred, cert, key, GNUTLS_X509_FMT_PEM); return 0; } int ne_ssl_context_set_verify(ne_ssl_context *ctx, int required, const char *ca_names, const char *verify_cas) { ctx->verify = required; if (verify_cas) { gnutls_certificate_set_x509_trust_file(ctx->cred, verify_cas, GNUTLS_X509_FMT_PEM); } /* gnutls_certificate_send_x509_rdn_sequence in gnutls >= 1.2 can * be used to *suppress* sending the CA names, but not control it, * it seems. */ return 0; } void ne_ssl_context_set_flag(ne_ssl_context *ctx, int flag, int value) { /* SSLv2 not supported. */ } void ne_ssl_context_destroy(ne_ssl_context *ctx) { gnutls_certificate_free_credentials(ctx->cred); if (ctx->cache.client.data) { ne_free(ctx->cache.client.data); } else if (ctx->cache.server.key.data) { gnutls_free(ctx->cache.server.key.data); gnutls_free(ctx->cache.server.data.data); } ne_free(ctx); } #ifdef HAVE_GNUTLS_CERTIFICATE_GET_X509_CAS /* Return the issuer of the given certificate, or NULL if none can be * found. */ static gnutls_x509_crt find_issuer(gnutls_x509_crt *ca_list, unsigned int num_cas, gnutls_x509_crt cert) { unsigned int n; for (n = 0; n < num_cas; n++) { if (gnutls_x509_crt_check_issuer(cert, ca_list[n]) == 1) return ca_list[n]; } return NULL; } #endif /* Return the certificate chain sent by the peer, or NULL on error. */ static ne_ssl_certificate *make_peers_chain(gnutls_session sock, gnutls_certificate_credentials crd) { ne_ssl_certificate *current = NULL, *top = NULL; const gnutls_datum *certs; unsigned int n, count; ne_ssl_certificate *cert; certs = gnutls_certificate_get_peers(sock, &count); if (!certs) { return NULL; } NE_DEBUG(NE_DBG_SSL, "ssl: Got %u certs in peer chain.", count); for (n = 0; n < count; n++) { gnutls_x509_crt x5; if (gnutls_x509_crt_init(&x5) || gnutls_x509_crt_import(x5, &certs[n], GNUTLS_X509_FMT_DER)) { if (top) { ne_ssl_cert_free(top); } return NULL; } cert = populate_cert(ne_calloc(sizeof *cert), x5); if (top == NULL) { current = top = cert; } else { current->issuer = cert; current = cert; } } #ifdef HAVE_GNUTLS_CERTIFICATE_GET_X509_CAS /* GnuTLS only returns the peers which were *sent* by the server * in the Certificate list during the handshake. Fill in the * complete chain manually against the certs we trust: */ if (current->issuer == NULL) { gnutls_x509_crt issuer; gnutls_x509_crt *ca_list; unsigned int num_cas; gnutls_certificate_get_x509_cas(crd, &ca_list, &num_cas); do { /* Look up the issuer. */ issuer = find_issuer(ca_list, num_cas, current->chain[0]); if (issuer) { issuer = x509_crt_copy(issuer); cert = populate_cert(ne_calloc(sizeof *cert), issuer); /* Check that the issuer does not match the current * cert. */ if (ne_ssl_cert_cmp(current, cert)) { current = current->issuer = cert; } else { ne_ssl_cert_free(cert); issuer = NULL; } } } while (issuer); } #endif return top; } /* Map from GnuTLS verify failure mask *status to NE_SSL_* failure * bitmask, which is returned. *status is modified, removing all * mapped bits. */ static int map_verify_failures(unsigned int *status) { static const struct { gnutls_certificate_status_t from; int to; } map[] = { { GNUTLS_CERT_REVOKED, NE_SSL_REVOKED }, #if LIBGNUTLS_VERSION_NUMBER >= 0x020800 { GNUTLS_CERT_NOT_ACTIVATED, NE_SSL_NOTYETVALID }, { GNUTLS_CERT_EXPIRED, NE_SSL_EXPIRED }, #endif { GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_FOUND, NE_SSL_UNTRUSTED }, { GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_CA, NE_SSL_UNTRUSTED } }; size_t n; int ret = 0; for (n = 0; n < sizeof(map)/sizeof(map[0]); n++) { if ((*status & map[n].from) == map[n].from) { *status &= ~map[n].from; ret |= map[n].to; } } return ret; } /* Return a malloc-allocated human-readable error string describing * GnuTLS verification error bitmask 'status'; return value must be * freed by the caller. */ static char *verify_error_string(unsigned int status) { ne_buffer *buf = ne_buffer_create(); /* sorry, i18n-ers */ if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { ne_buffer_zappend(buf, _("signed using insecure algorithm")); } else { ne_buffer_snprintf(buf, 64, _("unrecognized errors (%u)"), status); } return ne_buffer_finish(buf); } /* Return NE_SSL_* failure bits after checking chain expiry. */ static int check_chain_expiry(ne_ssl_certificate *chain) { time_t before, after, now = time(NULL); ne_ssl_certificate *cert; int failures = 0; /* Check that all certs within the chain are inside their defined * validity period. Note that the errors flagged for the server * cert are different from the generic error for issues higher up * the chain. */ for (cert = chain; cert; cert = cert->issuer) { before = gnutls_x509_crt_get_activation_time(cert->chain[0]); after = gnutls_x509_crt_get_expiration_time(cert->chain[0]); if (now < before) failures |= (cert == chain) ? NE_SSL_NOTYETVALID : NE_SSL_BADCHAIN; else if (now > after) failures |= (cert == chain) ? NE_SSL_EXPIRED : NE_SSL_BADCHAIN; } return failures; } /* Verifies an SSL server certificate. */ static int check_certificate(ne_session *sess, gnutls_session sock, ne_ssl_certificate *chain) { int ret, failures = 0; ne_uri server; unsigned int status; memset(&server, 0, sizeof server); ne_fill_server_uri(sess, &server); ret = check_identity(&server, chain->chain[0], NULL); ne_uri_free(&server); if (ret < 0) { ne_set_error(sess, _("Server certificate was missing commonName " "attribute in subject name")); return NE_ERROR; } else if (ret > 0) { failures |= NE_SSL_IDMISMATCH; } failures |= check_chain_expiry(chain); ret = gnutls_certificate_verify_peers2(sock, &status); NE_DEBUG(NE_DBG_SSL, "ssl: Verify peers returned %d, status=%u", ret, status); if (ret != GNUTLS_E_SUCCESS) { ne_set_error(sess, _("Could not verify server certificate: %s"), gnutls_strerror(ret)); return NE_ERROR; } failures |= map_verify_failures(&status); NE_DEBUG(NE_DBG_SSL, "ssl: Verification failures = %d (status = %u).", failures, status); if (status && status != GNUTLS_CERT_INVALID) { char *errstr = verify_error_string(status); ne_set_error(sess, _("Certificate verification error: %s"), errstr); ne_free(errstr); return NE_ERROR; } if (failures == 0) { ret = NE_OK; } else { ne__ssl_set_verify_err(sess, failures); ret = NE_ERROR; if (sess->ssl_verify_fn && sess->ssl_verify_fn(sess->ssl_verify_ud, failures, chain) == 0) ret = NE_OK; } return ret; } /* Negotiate an SSL connection. */ int ne__negotiate_ssl(ne_session *sess) { ne_ssl_context *const ctx = sess->ssl_context; ne_ssl_certificate *chain; gnutls_session sock; NE_DEBUG(NE_DBG_SSL, "Negotiating SSL connection."); /* Pass through the hostname if SNI is enabled. */ ctx->hostname = sess->flags[NE_SESSFLAG_TLS_SNI] ? sess->server.hostname : NULL; if (ne_sock_connect_ssl(sess->socket, ctx, sess)) { if (sess->ssl_cc_requested) { ne_set_error(sess, _("SSL handshake failed, " "client certificate was requested: %s"), ne_sock_error(sess->socket)); } else { ne_set_error(sess, _("SSL handshake failed: %s"), ne_sock_error(sess->socket)); } return NE_ERROR; } sock = ne__sock_sslsock(sess->socket); chain = make_peers_chain(sock, ctx->cred); if (chain == NULL) { ne_set_error(sess, _("Server did not send certificate chain")); return NE_ERROR; } if (sess->server_cert && ne_ssl_cert_cmp(sess->server_cert, chain) == 0) { /* Same cert as last time; presume OK. This is not optimal as * make_peers_chain() has already gone through and done the * expensive DER parsing stuff for the whole chain by now. */ ne_ssl_cert_free(chain); return NE_OK; } if (check_certificate(sess, sock, chain)) { ne_ssl_cert_free(chain); return NE_ERROR; } sess->server_cert = chain; return NE_OK; } const ne_ssl_dname *ne_ssl_cert_issuer(const ne_ssl_certificate *cert) { return &cert->issuer_dn; } const ne_ssl_dname *ne_ssl_cert_subject(const ne_ssl_certificate *cert) { return &cert->subj_dn; } const ne_ssl_certificate *ne_ssl_cert_signedby(const ne_ssl_certificate *cert) { return cert->issuer; } const char *ne_ssl_cert_identity(const ne_ssl_certificate *cert) { return cert->identity; } void ne_ssl_context_trustcert(ne_ssl_context *ctx, const ne_ssl_certificate *cert) { gnutls_x509_crt certs = cert->chain[0]; gnutls_certificate_set_x509_trust(ctx->cred, &certs, 1); } void ne_ssl_trust_default_ca(ne_session *sess) { #ifdef NE_SSL_CA_BUNDLE gnutls_certificate_set_x509_trust_file(sess->ssl_context->cred, NE_SSL_CA_BUNDLE, GNUTLS_X509_FMT_PEM); #endif } /* Read the contents of file FILENAME into *DATUM. */ static int read_to_datum(const char *filename, gnutls_datum *datum) { FILE *f = fopen(filename, "r"); ne_buffer *buf; char tmp[4192]; size_t len; if (!f) { return -1; } buf = ne_buffer_ncreate(8192); while ((len = fread(tmp, 1, sizeof tmp, f)) > 0) { ne_buffer_append(buf, tmp, len); } if (!feof(f)) { fclose(f); ne_buffer_destroy(buf); return -1; } fclose(f); datum->size = ne_buffer_size(buf); datum->data = (unsigned char *)ne_buffer_finish(buf); return 0; } /* Parses a PKCS#12 structure and loads the certificate, private key * and friendly name if possible. Returns zero on success, non-zero * on error. */ static int pkcs12_parse(gnutls_pkcs12 p12, gnutls_x509_privkey *pkey, gnutls_x509_crt **chain, int *chain_len, char **friendly_name, const char *password) { gnutls_pkcs12_bag bag = NULL; int i, j, ret = 0; gnutls_x509_crt certs[10]; int ncerts = 0; for (i = 0; ret == 0; ++i) { if (bag) gnutls_pkcs12_bag_deinit(bag); ret = gnutls_pkcs12_bag_init(&bag); if (ret < 0) continue; ret = gnutls_pkcs12_get_bag(p12, i, bag); if (ret < 0) continue; gnutls_pkcs12_bag_decrypt(bag, password); for (j = 0; ret == 0 && j < gnutls_pkcs12_bag_get_count(bag); ++j) { gnutls_pkcs12_bag_type type; gnutls_datum data; if (friendly_name && *friendly_name == NULL) { char *name = NULL; gnutls_pkcs12_bag_get_friendly_name(bag, j, &name); if (name) { if (name[0] == '.') name++; /* weird GnuTLS bug? */ *friendly_name = ne_strdup(name); } } type = gnutls_pkcs12_bag_get_type(bag, j); switch (type) { case GNUTLS_BAG_PKCS8_KEY: case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: /* Ignore any but the first key encountered; really * need to match up keyids. */ if (*pkey) break; gnutls_x509_privkey_init(pkey); ret = gnutls_pkcs12_bag_get_data(bag, j, &data); if (ret < 0) continue; ret = gnutls_x509_privkey_import_pkcs8(*pkey, &data, GNUTLS_X509_FMT_DER, password, 0); if (ret < 0) continue; break; case GNUTLS_BAG_CERTIFICATE: if (ncerts >= 10) continue; ret = gnutls_x509_crt_init(&certs[ncerts]); if (ret < 0) continue; ret = gnutls_pkcs12_bag_get_data(bag, j, &data); if (ret < 0) continue; ret = gnutls_x509_crt_import(certs[ncerts], &data, GNUTLS_X509_FMT_DER); if (ret < 0) continue; ++ncerts; break; default: break; } } } /* Make sure last bag is freed */ if (bag) gnutls_pkcs12_bag_deinit(bag); /* Free in case of error */ if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { for (i = 0; i < ncerts; ++i) gnutls_x509_crt_deinit(certs[i]); if (*pkey) gnutls_x509_privkey_deinit(*pkey); if (friendly_name && *friendly_name) ne_free(*friendly_name); } else { /* Copy to chain */ *chain_len = ncerts; *chain = gnutls_malloc(sizeof(gnutls_x509_crt_t) * ncerts); for (i = 0; i < ncerts; ++i) (*chain)[i] = certs[i]; } if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) ret = 0; return ret; } ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename) { int ret; gnutls_datum data; gnutls_pkcs12 p12; ne_ssl_client_cert *cc; char *friendly_name = NULL; gnutls_x509_crt* chain = NULL; unsigned chain_len = 0; gnutls_x509_privkey pkey = NULL; if (read_to_datum(filename, &data)) return NULL; if (gnutls_pkcs12_init(&p12) != 0) { return NULL; } ret = gnutls_pkcs12_import(p12, &data, GNUTLS_X509_FMT_DER, 0); ne_free(data.data); if (ret < 0) { gnutls_pkcs12_deinit(p12); return NULL; } if (gnutls_pkcs12_verify_mac(p12, "") == 0) { if (pkcs12_parse(p12, &pkey, &chain, &chain_len, &friendly_name, "") != 0 || !chain || !pkey) { gnutls_pkcs12_deinit(p12); return NULL; } cc = ne_calloc(sizeof *cc); cc->pkey = pkey; cc->decrypted = 1; cc->friendly_name = friendly_name; cc->cert.chain = chain; cc->cert.chain_len = chain_len; gnutls_pkcs12_deinit(p12); cc->p12 = NULL; return cc; } else { /* TODO: calling pkcs12_parse() here to find the friendly_name * seems to break horribly. */ cc = ne_calloc(sizeof *cc); cc->p12 = p12; return cc; } } ne_ssl_client_cert *ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len) { ne_ssl_client_cert *cc; gnutls_x509_crt x5; gnutls_datum datum; datum.data = (unsigned char *)der; datum.size = der_len; if (gnutls_x509_crt_init(&x5) || gnutls_x509_crt_import(x5, &datum, GNUTLS_X509_FMT_DER)) { NE_DEBUG(NE_DBG_SSL, "ssl: crt_import failed."); return NULL; } cc = ne_calloc(sizeof *cc); cc->keyless = 1; cc->decrypted = 1; populate_cert(&cc->cert, x5); return cc; } int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *cc) { return !cc->decrypted; } int ne_ssl_clicert_decrypt(ne_ssl_client_cert *cc, const char *password) { int ret; gnutls_x509_crt *chain = NULL; int chain_len = 0; gnutls_x509_privkey pkey = NULL; if (gnutls_pkcs12_verify_mac(cc->p12, password) != 0) { return -1; } ret = pkcs12_parse(cc->p12, &pkey, &chain, &chain_len, NULL, password); if (ret < 0) return ret; if (!chain || (!pkey && !cc->keyless)) { int n; for (n = 0; n < chain_len; ++n) gnutls_x509_crt_deinit(chain[0]); gnutls_free(chain); if (pkey) gnutls_x509_privkey_deinit(pkey); return -1; } gnutls_pkcs12_deinit(cc->p12); cc->cert.chain = chain; cc->cert.chain_len = chain_len; cc->pkey = pkey; cc->decrypted = 1; cc->p12 = NULL; return 0; } const ne_ssl_certificate *ne_ssl_clicert_owner(const ne_ssl_client_cert *cc) { return &cc->cert; } const char *ne_ssl_clicert_name(const ne_ssl_client_cert *ccert) { return ccert->friendly_name; } ne_ssl_certificate *ne_ssl_cert_read(const char *filename) { int ret; gnutls_datum data; gnutls_x509_crt x5; if (read_to_datum(filename, &data)) return NULL; if (gnutls_x509_crt_init(&x5) != 0) return NULL; ret = gnutls_x509_crt_import(x5, &data, GNUTLS_X509_FMT_PEM); ne_free(data.data); if (ret < 0) { gnutls_x509_crt_deinit(x5); return NULL; } return populate_cert(ne_calloc(sizeof(struct ne_ssl_certificate_s)), x5); } int ne_ssl_cert_write(const ne_ssl_certificate *cert, const char *filename) { unsigned char buffer[10*1024]; size_t len = sizeof buffer; FILE *fp = fopen(filename, "w"); if (fp == NULL) return -1; if (gnutls_x509_crt_export(cert->chain[0], GNUTLS_X509_FMT_PEM, buffer, &len) < 0) { fclose(fp); return -1; } if (fwrite(buffer, len, 1, fp) != 1) { fclose(fp); return -1; } if (fclose(fp) != 0) return -1; return 0; } void ne_ssl_cert_free(ne_ssl_certificate *cert) { int n; for (n = 0; n < cert->chain_len; ++n) gnutls_x509_crt_deinit(cert->chain[n]); gnutls_free(cert->chain); if (cert->identity) ne_free(cert->identity); if (cert->issuer) ne_ssl_cert_free(cert->issuer); ne_free(cert); } int ne_ssl_cert_cmp(const ne_ssl_certificate *c1, const ne_ssl_certificate *c2) { char digest1[NE_SSL_DIGESTLEN], digest2[NE_SSL_DIGESTLEN]; if (ne_ssl_cert_digest(c1, digest1) || ne_ssl_cert_digest(c2, digest2)) { return -1; } return strcmp(digest1, digest2); } /* The certificate import/export format is the base64 encoding of the * raw DER; PEM without the newlines and wrapping. */ ne_ssl_certificate *ne_ssl_cert_import(const char *data) { int ret; size_t len; unsigned char *der; gnutls_datum buffer = { NULL, 0 }; gnutls_x509_crt x5; if (gnutls_x509_crt_init(&x5) != 0) return NULL; /* decode the base64 to get the raw DER representation */ len = ne_unbase64(data, &der); if (len == 0) return NULL; buffer.data = der; buffer.size = len; ret = gnutls_x509_crt_import(x5, &buffer, GNUTLS_X509_FMT_DER); ne_free(der); if (ret < 0) { gnutls_x509_crt_deinit(x5); return NULL; } return populate_cert(ne_calloc(sizeof(struct ne_ssl_certificate_s)), x5); } char *ne_ssl_cert_export(const ne_ssl_certificate *cert) { unsigned char *der; size_t len = 0; char *ret; /* find the length of the DER encoding. */ if (gnutls_x509_crt_export(cert->chain[0], GNUTLS_X509_FMT_DER, NULL, &len) != GNUTLS_E_SHORT_MEMORY_BUFFER) { return NULL; } der = ne_malloc(len); if (gnutls_x509_crt_export(cert->chain[0], GNUTLS_X509_FMT_DER, der, &len)) { ne_free(der); return NULL; } ret = ne_base64(der, len); ne_free(der); return ret; } int ne_ssl_cert_digest(const ne_ssl_certificate *cert, char *digest) { char sha1[20], *p; int j; size_t len = sizeof sha1; if (gnutls_x509_crt_get_fingerprint(cert->chain[0], GNUTLS_DIG_SHA, sha1, &len) < 0) return -1; for (j = 0, p = digest; j < 20; j++) { *p++ = NE_HEX2ASC((sha1[j] >> 4) & 0x0f); *p++ = NE_HEX2ASC(sha1[j] & 0x0f); *p++ = ':'; } *--p = '\0'; return 0; } int ne__ssl_init(void) { #if LIBGNUTLS_VERSION_NUMBER < 0x020b01 #ifdef NE_HAVE_TS_SSL gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); #endif return gnutls_global_init(); } void ne__ssl_exit(void) { /* No way to unregister the thread callbacks. Doomed. */ #if LIBGNUTLS_VERSION_MAJOR > 1 || LIBGNUTLS_VERSION_MINOR > 3 \ || (LIBGNUTLS_VERSION_MINOR == 3 && LIBGNUTLS_VERSION_PATCH >= 3) /* It's safe to call gnutls_global_deinit() here only with * gnutls >= 1.3., since older versions don't refcount and * doing so would prevent any other use of gnutls within * the process. */ gnutls_global_deinit(); #endif } davix-R_0_5_0/deps/libneon/src/ne_i18n.c000066400000000000000000000030011257152637300200340ustar00rootroot00000000000000/* Internationalization of neon Copyright (C) 1999-2005, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include "ne_i18n.h" #ifdef HAVE_LIBINTL_H #include #endif void ne_i18n_init(const char *encoding) { #if defined(NE_HAVE_I18N) && defined(NEON_IS_LIBRARY) /* The bindtextdomain call is only enabled if neon is built as a * library rather than as a bundled source; it would be possible * in the future to allow it for bundled builds too, if the neon * message catalogs could be installed alongside the app's own * message catalogs. */ bindtextdomain("neon", LOCALEDIR); #ifdef HAVE_BIND_TEXTDOMAIN_CODESET if (encoding) { bind_textdomain_codeset("neon", encoding); } #endif /* HAVE_BIND_TEXTDOMAIN_CODESET */ #endif } davix-R_0_5_0/deps/libneon/src/ne_i18n.h000066400000000000000000000037301257152637300200520ustar00rootroot00000000000000/* Internationalization of neon Copyright (C) 2005-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_I18N_H #define NE_I18N_H #include "ne_defs.h" NE_BEGIN_DECLS /* Initialize translated error messages within neon. If 'encoding' is * non-NULL, it specifies the character encoding for the generated * translated strings. If it is NULL, the appropriate character * encoding for the locale will be used. * * This call is only strictly necessary if either: * * a) neon has been installed into a different prefix than the * gettext() implementation on which it depends for i18n purposes, or * * b) the caller requires that translated messages are in a particular * character encoding. * * If ne_i18n_init() is never called, the message catalogs will not be * found if case (a) applies (and so English error messages will be * used), and will use the default character encoding specified by the * process locale. The library will otherwise operate correctly. * * Note that the encoding used is a process-global setting and so * results may be unexpected if other users of neon within the process * call ne_i18n_init() with a different encoding parameter. */ void ne_i18n_init(const char *encoding); NE_END_DECLS #endif /* NE_I18N_H */ davix-R_0_5_0/deps/libneon/src/ne_internal.h000066400000000000000000000043131257152637300211050ustar00rootroot00000000000000/* Global interfaces private to neon. Copyright (C) 2005-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* NOTE WELL: The interfaces defined in this file are internal to neon * and MUST NOT be used by neon-based applications. */ #ifndef NE_INTERNAL_H #define NE_INTERNAL_H 1 #include "config.h" #ifdef HAVE_SYS_LIMITS_H #include #endif #ifdef HAVE_LIMITS_H #include /* for UINT_MAX etc */ #endif #include "ne_defs.h" #undef _ #ifdef NE_HAVE_I18N #include #define _(str) dgettext(PACKAGE_NAME, str) #else #define _(str) (str) #endif /* NE_ENABLE_NLS */ #define N_(str) (str) #if !defined(LONG_LONG_MAX) && defined(LLONG_MAX) #define LONG_LONG_MAX LLONG_MAX #elif !defined(LONG_LONG_MAX) && defined(LONGLONG_MAX) #define LONG_LONG_MAX LONGLONG_MAX #endif #if defined(NE_LFS) #define ne_lseek lseek64 #define FMT_NE_OFF_T NE_FMT_OFF64_T #define NE_OFFT_MAX LONG_LONG_MAX #ifdef HAVE_STRTOLL #define ne_strtoff strtoll #else #define ne_strtoff strtoq #endif #else /* !NE_LFS */ #define ne_lseek lseek #define FMT_NE_OFF_T NE_FMT_OFF_T #if defined(SIZEOF_LONG_LONG) && defined(LONG_LONG_MAX) \ && SIZEOF_OFF_T == SIZEOF_LONG_LONG #define NE_OFFT_MAX LONG_LONG_MAX #else #define NE_OFFT_MAX LONG_MAX #endif #if SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_STRTOLL) #define ne_strtoff strtoll #elif SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_STRTOQ) #define ne_strtoff strtoq #else #define ne_strtoff strtol #endif #endif /* NE_LFS */ #endif /* NE_INTERNAL_H */ davix-R_0_5_0/deps/libneon/src/ne_locks.c000066400000000000000000000534201257152637300204020ustar00rootroot00000000000000/* WebDAV Class 2 locking operations Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_LIMITS_H #include #endif #include /* for isdigit() */ #include "ne_alloc.h" #include "ne_request.h" #include "ne_xml.h" #include "ne_locks.h" #include "ne_uri.h" #include "ne_basic.h" #include "ne_props.h" #include "ne_207.h" #include "ne_internal.h" #include "ne_xmlreq.h" #define HOOK_ID "http://webdav.org/neon/hooks/webdav-locking" /* A list of lock objects. */ struct lock_list { struct ne_lock *lock; struct lock_list *next, *prev; }; struct ne_lock_store_s { struct lock_list *locks; struct lock_list *cursor; /* current position in 'locks' */ }; struct lh_req_cookie { const ne_lock_store *store; struct lock_list *submit; }; /* Context for PROPFIND/lockdiscovery callbacks */ struct discover_ctx { ne_propfind_handler *phandler; ne_lock_result results; void *userdata; ne_buffer *cdata; }; /* Context for handling LOCK response */ struct lock_ctx { struct ne_lock active; /* activelock */ ne_request *req; /* the request in question */ ne_xml_parser *parser; char *token; /* the token we're after. */ int found; ne_buffer *cdata; }; /* use the "application" state space. */ #define ELM_LOCK_FIRST (NE_PROPS_STATE_TOP + 66) #define ELM_lockdiscovery (ELM_LOCK_FIRST) #define ELM_activelock (ELM_LOCK_FIRST + 1) #define ELM_lockscope (ELM_LOCK_FIRST + 2) #define ELM_locktype (ELM_LOCK_FIRST + 3) #define ELM_depth (ELM_LOCK_FIRST + 4) #define ELM_owner (ELM_LOCK_FIRST + 5) #define ELM_timeout (ELM_LOCK_FIRST + 6) #define ELM_locktoken (ELM_LOCK_FIRST + 7) #define ELM_lockinfo (ELM_LOCK_FIRST + 8) #define ELM_write (ELM_LOCK_FIRST + 9) #define ELM_exclusive (ELM_LOCK_FIRST + 10) #define ELM_shared (ELM_LOCK_FIRST + 11) #define ELM_href (ELM_LOCK_FIRST + 12) #define ELM_prop (NE_207_STATE_PROP) static const struct ne_xml_idmap element_map[] = { #define ELM(x) { "DAV:", #x, ELM_ ## x } ELM(lockdiscovery), ELM(activelock), ELM(prop), ELM(lockscope), ELM(locktype), ELM(depth), ELM(owner), ELM(timeout), ELM(locktoken), ELM(lockinfo), ELM(lockscope), ELM(locktype), ELM(write), ELM(exclusive), ELM(shared), ELM(href) /* no "lockentry" */ #undef ELM }; static const ne_propname lock_props[] = { { "DAV:", "lockdiscovery" }, { NULL } }; /* this simply registers the accessor for the function. */ static void lk_create(ne_request *req, void *session, const char *method, const char *uri) { struct lh_req_cookie *lrc = ne_malloc(sizeof *lrc); lrc->store = session; lrc->submit = NULL; ne_set_request_private(req, HOOK_ID, lrc); } static void lk_pre_send(ne_request *r, void *userdata, ne_buffer *req) { struct lh_req_cookie *lrc = ne_get_request_private(r, HOOK_ID); if (lrc->submit != NULL) { struct lock_list *item; /* Add in the If header */ ne_buffer_czappend(req, "If:"); for (item = lrc->submit; item != NULL; item = item->next) { char *uri = ne_uri_unparse(&item->lock->uri); ne_buffer_concat(req, " <", uri, "> (<", item->lock->token, ">)", NULL); ne_free(uri); } ne_buffer_czappend(req, "\r\n"); } } /* Insert 'lock' into lock list *list. */ static void insert_lock(struct lock_list **list, struct ne_lock *lock) { struct lock_list *item = ne_malloc(sizeof *item); if (*list != NULL) { (*list)->prev = item; } item->prev = NULL; item->next = *list; item->lock = lock; *list = item; } static void free_list(struct lock_list *list, int destroy) { struct lock_list *next; while (list != NULL) { next = list->next; if (destroy) ne_lock_destroy(list->lock); ne_free(list); list = next; } } static void lk_destroy(ne_request *req, void *userdata) { struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID); free_list(lrc->submit, 0); ne_free(lrc); } void ne_lockstore_destroy(ne_lock_store *store) { free_list(store->locks, 1); ne_free(store); } ne_lock_store *ne_lockstore_create(void) { return ne_calloc(sizeof(ne_lock_store)); } #define CURSOR_RET(s) ((s)->cursor?(s)->cursor->lock:NULL) struct ne_lock *ne_lockstore_first(ne_lock_store *store) { store->cursor = store->locks; return CURSOR_RET(store); } struct ne_lock *ne_lockstore_next(ne_lock_store *store) { store->cursor = store->cursor->next; return CURSOR_RET(store); } void ne_lockstore_register(ne_lock_store *store, ne_session *sess) { /* Register the hooks */ ne_hook_create_request(sess, lk_create, store); ne_hook_pre_send(sess, lk_pre_send, store); ne_hook_destroy_request(sess, lk_destroy, store); } /* Submit the given lock for the given URI */ static void submit_lock(struct lh_req_cookie *lrc, struct ne_lock *lock) { struct lock_list *item; /* Check for dups */ for (item = lrc->submit; item != NULL; item = item->next) { if (ne_strcasecmp(item->lock->token, lock->token) == 0) return; } insert_lock(&lrc->submit, lock); } struct ne_lock *ne_lockstore_findbyuri(ne_lock_store *store, const ne_uri *uri) { struct lock_list *cur; for (cur = store->locks; cur != NULL; cur = cur->next) { if (ne_uri_cmp(&cur->lock->uri, uri) == 0) { return cur->lock; } } return NULL; } void ne_lock_using_parent(ne_request *req, const char *path) { struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID); ne_uri u = {0}; struct lock_list *item; char *parent; if (lrc == NULL) return; parent = ne_path_parent(path); if (parent == NULL) return; ne_fill_server_uri(ne_get_session(req), &u); for (item = lrc->store->locks; item != NULL; item = item->next) { /* Only care about locks which are on this server. */ u.path = item->lock->uri.path; if (ne_uri_cmp(&u, &item->lock->uri)) continue; /* This lock is needed if it is an infinite depth lock which * covers the parent, or a lock on the parent itself. */ if ((item->lock->depth == NE_DEPTH_INFINITE && ne_path_childof(item->lock->uri.path, parent)) || ne_path_compare(item->lock->uri.path, parent) == 0) { NE_DEBUG(NE_DBG_LOCKS, "Locked parent, %s on %s", item->lock->token, item->lock->uri.path); submit_lock(lrc, item->lock); } } u.path = parent; /* handy: makes u.path valid and ne_free(parent). */ ne_uri_free(&u); } void ne_lock_using_resource(ne_request *req, const char *uri, int depth) { struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID); struct lock_list *item; int match; if (lrc == NULL) return; /* Iterate over the list of stored locks to see if any of them * apply to this resource */ for (item = lrc->store->locks; item != NULL; item = item->next) { match = 0; if (depth == NE_DEPTH_INFINITE && ne_path_childof(uri, item->lock->uri.path)) { /* Case 1: this is a depth-infinity request which will * modify a lock somewhere inside the collection. */ NE_DEBUG(NE_DBG_LOCKS, "Has child: %s", item->lock->token); match = 1; } else if (ne_path_compare(uri, item->lock->uri.path) == 0) { /* Case 2: this request is directly on a locked resource */ NE_DEBUG(NE_DBG_LOCKS, "Has direct lock: %s", item->lock->token); match = 1; } else if (item->lock->depth == NE_DEPTH_INFINITE && ne_path_childof(item->lock->uri.path, uri)) { /* Case 3: there is a higher-up infinite-depth lock which * covers the resource that this request will modify. */ NE_DEBUG(NE_DBG_LOCKS, "Is child of: %s", item->lock->token); match = 1; } if (match) { submit_lock(lrc, item->lock); } } } void ne_lockstore_add(ne_lock_store *store, struct ne_lock *lock) { insert_lock(&store->locks, lock); } void ne_lockstore_remove(ne_lock_store *store, struct ne_lock *lock) { struct lock_list *item; /* Find the lock */ for (item = store->locks; item != NULL; item = item->next) if (item->lock == lock) break; if (item->prev != NULL) { item->prev->next = item->next; } else { store->locks = item->next; } if (item->next != NULL) { item->next->prev = item->prev; } ne_free(item); } struct ne_lock *ne_lock_copy(const struct ne_lock *lock) { struct ne_lock *ret = ne_calloc(sizeof *ret); ne_uri_copy(&ret->uri, &lock->uri); ret->token = ne_strdup(lock->token); ret->depth = lock->depth; ret->type = lock->type; ret->scope = lock->scope; if (lock->owner) ret->owner = ne_strdup(lock->owner); ret->timeout = lock->timeout; return ret; } struct ne_lock *ne_lock_create(void) { struct ne_lock *lock = ne_calloc(sizeof *lock); lock->depth = NE_DEPTH_ZERO; lock->type = ne_locktype_write; lock->scope = ne_lockscope_exclusive; lock->timeout = NE_TIMEOUT_INVALID; return lock; } void ne_lock_free(struct ne_lock *lock) { ne_uri_free(&lock->uri); if (lock->owner) { ne_free(lock->owner); lock->owner = NULL; } if (lock->token) { ne_free(lock->token); lock->token = NULL; } } void ne_lock_destroy(struct ne_lock *lock) { ne_lock_free(lock); ne_free(lock); } int ne_unlock(ne_session *sess, const struct ne_lock *lock) { ne_request *req = ne_request_create(sess, "UNLOCK", lock->uri.path); int ret; ne_print_request_header(req, "Lock-Token", "<%s>", lock->token); /* UNLOCK of a lock-null resource removes the resource from the * parent collection; so an UNLOCK may modify the parent * collection. (somewhat counter-intuitive, and not easily derived * from 2518.) */ ne_lock_using_parent(req, lock->uri.path); ret = ne_request_dispatch(req); if (ret == NE_OK && ne_get_status(req)->klass != 2) { ret = NE_ERROR; } ne_request_destroy(req); return ret; } static int parse_depth(const char *depth) { if (ne_strcasecmp(depth, "infinity") == 0) { return NE_DEPTH_INFINITE; } else if (isdigit(depth[0])) { return atoi(depth); } else { return -1; } } static long parse_timeout(const char *timeout) { if (ne_strcasecmp(timeout, "infinite") == 0) { return NE_TIMEOUT_INFINITE; } else if (strncasecmp(timeout, "Second-", 7) == 0) { long to = strtol(timeout+7, NULL, 10); if (to == LONG_MIN || to == LONG_MAX) return NE_TIMEOUT_INVALID; return to; } else { return NE_TIMEOUT_INVALID; } } static void discover_results(void *userdata, const ne_uri *uri, const ne_prop_result_set *set) { struct discover_ctx *ctx = userdata; struct ne_lock *lock = ne_propset_private(set); const ne_status *status = ne_propset_status(set, &lock_props[0]); /* Require at least that the lock has a token. */ if (lock->token) { if (status && status->klass != 2) { ctx->results(ctx->userdata, NULL, uri, status); } else { ctx->results(ctx->userdata, lock, uri, NULL); } } else if (status) { ctx->results(ctx->userdata, NULL, uri, status); } NE_DEBUG(NE_DBG_LOCKS, "End of response for %s", uri->path); } static int end_element_common(struct ne_lock *l, int state, const char *cdata) { switch (state) { case ELM_write: l->type = ne_locktype_write; break; case ELM_exclusive: l->scope = ne_lockscope_exclusive; break; case ELM_shared: l->scope = ne_lockscope_shared; break; case ELM_depth: NE_DEBUG(NE_DBG_LOCKS, "Got depth: %s", cdata); l->depth = parse_depth(cdata); if (l->depth == -1) { return -1; } break; case ELM_timeout: NE_DEBUG(NE_DBG_LOCKS, "Got timeout: %s", cdata); l->timeout = parse_timeout(cdata); if (l->timeout == NE_TIMEOUT_INVALID) { return -1; } break; case ELM_owner: l->owner = strdup(cdata); break; case ELM_href: l->token = strdup(cdata); break; } return 0; } /* End-element handler for lock discovery PROPFIND response */ static int end_element_ldisc(void *userdata, int state, const char *nspace, const char *name) { struct discover_ctx *ctx = userdata; struct ne_lock *lock = ne_propfind_current_private(ctx->phandler); return end_element_common(lock, state, ctx->cdata->data); } static inline int can_accept(int parent, int id) { return (parent == NE_XML_STATEROOT && id == ELM_prop) || (parent == ELM_prop && id == ELM_lockdiscovery) || (parent == ELM_lockdiscovery && id == ELM_activelock) || (parent == ELM_activelock && (id == ELM_lockscope || id == ELM_locktype || id == ELM_depth || id == ELM_owner || id == ELM_timeout || id == ELM_locktoken)) || (parent == ELM_lockscope && (id == ELM_exclusive || id == ELM_shared)) || (parent == ELM_locktype && id == ELM_write) || (parent == ELM_locktoken && id == ELM_href); } static int ld_startelm(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { struct discover_ctx *ctx = userdata; int id = ne_xml_mapid(element_map, NE_XML_MAPLEN(element_map), nspace, name); ne_buffer_clear(ctx->cdata); if (can_accept(parent, id)) return id; else return NE_XML_DECLINE; } #define MAX_CDATA (256) static int lk_cdata(void *userdata, int state, const char *cdata, size_t len) { struct lock_ctx *ctx = userdata; if (ctx->cdata->used + len < MAX_CDATA) ne_buffer_append(ctx->cdata, cdata, len); return 0; } static int ld_cdata(void *userdata, int state, const char *cdata, size_t len) { struct discover_ctx *ctx = userdata; if (ctx->cdata->used + len < MAX_CDATA) ne_buffer_append(ctx->cdata, cdata, len); return 0; } static int lk_startelm(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { struct lock_ctx *ctx = userdata; int id; id = ne_xml_mapid(element_map, NE_XML_MAPLEN(element_map), nspace, name); NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: %s => %d", name, id); if (id == 0) return NE_XML_DECLINE; if (parent == 0 && ctx->token == NULL) { const char *token = ne_get_response_header(ctx->req, "Lock-Token"); /* at the root element; retrieve the Lock-Token header, * and bail if it wasn't given. */ if (token == NULL) { ne_xml_set_error(ctx->parser, _("LOCK response missing Lock-Token header")); return NE_XML_ABORT; } if (token[0] == '<') token++; ctx->token = ne_strdup(token); ne_shave(ctx->token, ">"); NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: Finding token %s", ctx->token); } /* TODO: only accept 'prop' as root for LOCK response */ if (!can_accept(parent, id)) return NE_XML_DECLINE; if (id == ELM_activelock && !ctx->found) { /* a new activelock */ ne_lock_free(&ctx->active); memset(&ctx->active, 0, sizeof ctx->active); ctx->active.timeout = NE_TIMEOUT_INVALID; } ne_buffer_clear(ctx->cdata); return id; } /* End-element handler for LOCK response */ static int lk_endelm(void *userdata, int state, const char *nspace, const char *name) { struct lock_ctx *ctx = userdata; if (ctx->found) return 0; if (end_element_common(&ctx->active, state, ctx->cdata->data)) return -1; if (state == ELM_activelock) { if (ctx->active.token && strcmp(ctx->active.token, ctx->token) == 0) { ctx->found = 1; } } return 0; } /* Creator callback for private structure. */ static void *ld_create(void *userdata, const ne_uri *uri) { struct ne_lock *lk = ne_lock_create(); ne_uri_copy(&lk->uri, uri); return lk; } /* Destructor callback for private structure. */ static void ld_destroy(void *userdata, void *private) { struct ne_lock *lk = private; ne_lock_destroy(lk); } /* Discover all locks on URI */ int ne_lock_discover(ne_session *sess, const char *uri, ne_lock_result callback, void *userdata) { ne_propfind_handler *handler; struct discover_ctx ctx = {0}; int ret; ctx.results = callback; ctx.userdata = userdata; ctx.cdata = ne_buffer_create(); ctx.phandler = handler = ne_propfind_create(sess, uri, NE_DEPTH_ZERO); ne_propfind_set_private(handler, ld_create, ld_destroy, &ctx); ne_xml_push_handler(ne_propfind_get_parser(handler), ld_startelm, ld_cdata, end_element_ldisc, &ctx); ret = ne_propfind_named(handler, lock_props, discover_results, &ctx); ne_buffer_destroy(ctx.cdata); ne_propfind_destroy(handler); return ret; } static void add_timeout_header(ne_request *req, long timeout) { if (timeout == NE_TIMEOUT_INFINITE) { ne_add_request_header(req, "Timeout", "Infinite"); } else if (timeout != NE_TIMEOUT_INVALID && timeout > 0) { ne_print_request_header(req, "Timeout", "Second-%ld", timeout); } /* just ignore it if timeout == 0 or invalid. */ } int ne_lock(ne_session *sess, struct ne_lock *lock) { ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path); ne_buffer *body = ne_buffer_create(); ne_xml_parser *parser = ne_xml_create(); int ret; struct lock_ctx ctx; memset(&ctx, 0, sizeof ctx); ctx.cdata = ne_buffer_create(); ctx.req = req; ctx.parser = parser; /* LOCK is not idempotent. */ ne_set_request_flag(req, NE_REQFLAG_IDEMPOTENT, 0); ne_xml_push_handler(parser, lk_startelm, lk_cdata, lk_endelm, &ctx); /* Create the body */ ne_buffer_concat(body, "\n" "\n" " ", lock->scope==ne_lockscope_exclusive? "":"", "\n" "", NULL); if (lock->owner) { ne_buffer_concat(body, "", lock->owner, "\n", NULL); } ne_buffer_czappend(body, "\n"); ne_set_request_body_buffer(req, body->data, ne_buffer_size(body)); ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); ne_add_depth_header(req, lock->depth); add_timeout_header(req, lock->timeout); /* TODO: * By 2518, we need this only if we are creating a lock-null resource. * Since we don't KNOW whether the lock we're given is a lock-null * or not, we cover our bases. */ ne_lock_using_parent(req, lock->uri.path); /* This one is clearer from 2518 sec 8.10.4. */ ne_lock_using_resource(req, lock->uri.path, lock->depth); ret = ne_xml_dispatch_request(req, parser); ne_buffer_destroy(body); ne_buffer_destroy(ctx.cdata); if (ret == NE_OK && ne_get_status(req)->klass == 2) { if (ne_get_status(req)->code == 207) { ret = NE_ERROR; /* TODO: set the error string appropriately */ } else if (ctx.found) { /* it worked: copy over real lock details if given. */ if (lock->token) ne_free(lock->token); lock->token = ctx.token; ctx.token = NULL; if (ctx.active.timeout != NE_TIMEOUT_INVALID) lock->timeout = ctx.active.timeout; lock->scope = ctx.active.scope; lock->type = ctx.active.type; if (ctx.active.depth >= 0) lock->depth = ctx.active.depth; if (ctx.active.owner) { if (lock->owner) ne_free(lock->owner); lock->owner = ctx.active.owner; ctx.active.owner = NULL; } } else { ret = NE_ERROR; ne_set_error(sess, _("Response missing activelock for %s"), ctx.token); } } else if (ret == NE_OK /* && status != 2xx */) { ret = NE_ERROR; } ne_lock_free(&ctx.active); if (ctx.token) ne_free(ctx.token); ne_request_destroy(req); ne_xml_destroy(parser); return ret; } int ne_lock_refresh(ne_session *sess, struct ne_lock *lock) { ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path); ne_xml_parser *parser = ne_xml_create(); int ret; struct lock_ctx ctx; memset(&ctx, 0, sizeof ctx); ctx.cdata = ne_buffer_create(); ctx.req = req; ctx.token = lock->token; ctx.parser = parser; /* Handle the response and update *lock appropriately. */ ne_xml_push_handler(parser, lk_startelm, lk_cdata, lk_endelm, &ctx); /* For a lock refresh, submitting only this lock token must be * sufficient. */ ne_print_request_header(req, "If", "(<%s>)", lock->token); add_timeout_header(req, lock->timeout); ret = ne_xml_dispatch_request(req, parser); if (ret == NE_OK) { if (ne_get_status(req)->klass != 2) { ret = NE_ERROR; /* and use default session error */ } else if (!ctx.found) { ne_set_error(sess, _("No activelock for <%s> returned in " "LOCK refresh response"), lock->token); ret = NE_ERROR; } else /* success! */ { /* update timeout for passed-in lock structure. */ lock->timeout = ctx.active.timeout; } } ne_lock_free(&ctx.active); ne_buffer_destroy(ctx.cdata); ne_request_destroy(req); ne_xml_destroy(parser); return ret; } davix-R_0_5_0/deps/libneon/src/ne_locks.h000066400000000000000000000142651257152637300204130ustar00rootroot00000000000000/* WebDAV Class 2 locking operations Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_LOCKS_H #define NE_LOCKS_H #include "ne_request.h" /* for ne_session + ne_request */ #include "ne_uri.h" /* for ne_uri */ NE_BEGIN_DECLS /* The scope of a lock */ enum ne_lock_scope { ne_lockscope_exclusive, ne_lockscope_shared }; /* Lock type. Only write locks are defined in RFC2518. */ enum ne_lock_type { ne_locktype_write }; /* A lock object. */ struct ne_lock { ne_uri uri; int depth; /* the depth of the lock (NE_DEPTH_*). */ enum ne_lock_type type; enum ne_lock_scope scope; char *token; /* the lock token: uniquely identifies this lock. */ char *owner; /* string describing the owner of the lock. */ long timeout; /* timeout in seconds. (or NE_TIMEOUT_*) */ }; /* NB: struct ne_lock Would be typedef'ed to ne_lock except lock is * a verb and a noun, so we already have ne_lock the function. Damn * the English language. */ #define NE_TIMEOUT_INFINITE -1 #define NE_TIMEOUT_INVALID -2 /* Create a depth zero, exclusive write lock, with default timeout * (allowing a server to pick a default). token, owner and uri are * unset. */ struct ne_lock *ne_lock_create(void); /* HINT: to initialize uri host/port/scheme for the lock's URI, use * ne_fill_server_uri from ne_session.h. */ /* Deep-copy a lock structure: strdup's any of path, token, owner, * hostport which are set. */ struct ne_lock *ne_lock_copy(const struct ne_lock *lock); /* Free a lock structure; free's any of any of the URI, token and * owner which are set, but not the lock object itself. */ void ne_lock_free(struct ne_lock *lock); /* Like ne_lock_free; but free's the lock object itself too. */ void ne_lock_destroy(struct ne_lock *lock); /* ne_lock_store: an opaque type which is used to store a set of lock * objects. */ typedef struct ne_lock_store_s ne_lock_store; /* Create a lock store. */ ne_lock_store *ne_lockstore_create(void); /* Register the lock store 'store' with the HTTP session 'sess': any * operations made using 'sess' which operate on a locked resource, * can use the locks from 'store' if needed. */ void ne_lockstore_register(ne_lock_store *store, ne_session *sess); /* Destroy a lock store, free'ing any locks remaining inside. */ void ne_lockstore_destroy(ne_lock_store *store); /* Add a lock to the store: the store then "owns" the lock object, and * you must not free it. The lock MUST have all of: * - a completed URI structure: scheme, host, port, and path all set * - a valid lock token * - a valid depth */ void ne_lockstore_add(ne_lock_store *store, struct ne_lock *lock); /* Remove given lock object from store: 'lock' MUST point to a lock * object which is known to be in the store. */ void ne_lockstore_remove(ne_lock_store *store, struct ne_lock *lock); /* Returns the first lock in the lock store, or NULL if the store is * empty. */ struct ne_lock *ne_lockstore_first(ne_lock_store *store); /* After ne_lockstore_first has been called; returns the next lock in * the lock store, or NULL if there are no more locks stored. * Behaviour is undefined if ne_lockstore_first has not been called on * 'store' since the store was created, or the last time this function * returned NULL for the store.. */ struct ne_lock *ne_lockstore_next(ne_lock_store *store); /* Find a lock in the store for the given server, and with the given * path. */ struct ne_lock *ne_lockstore_findbyuri(ne_lock_store *store, const ne_uri *uri); /* Issue a LOCK request for the given lock. Requires that the uri, * depth, type, scope, and timeout members of 'lock' are filled in. * owner and token must be malloc-allocated if not NULL; and may be * free()d by this function. On successful return, lock->token will * contain the lock token. */ int ne_lock(ne_session *sess, struct ne_lock *lock); /* Issue an UNLOCK request for the given lock */ int ne_unlock(ne_session *sess, const struct ne_lock *lock); /* Refresh a lock. Updates lock->timeout appropriately. */ int ne_lock_refresh(ne_session *sess, struct ne_lock *lock); /* Callback for lock discovery. If 'lock' is NULL, something went * wrong performing lockdiscovery for the resource, look at 'status' * for the details. * * If lock is non-NULL, at least lock->uri and lock->token will be * filled in; and status will be NULL. */ typedef void (*ne_lock_result)(void *userdata, const struct ne_lock *lock, const ne_uri *uri, const ne_status *status); /* Perform lock discovery on the given path. 'result' is called with * the results (possibly >1 times). */ int ne_lock_discover(ne_session *sess, const char *path, ne_lock_result result, void *userdata); /* The ne_lock_using_* functions should be used before dispatching a * request which modify resources. If a lock store has been * registered with the session associated with the request, and locks * are present in the lock store which cover the resources which are * being modified by the request, then the appropriate lock tokens are * submitted in the request headers. */ /* Indicate that request 'req' will modify the resource at 'path', and * is an operation of given 'depth'. */ void ne_lock_using_resource(ne_request *req, const char *path, int depth); /* Indicate that request 'req' will modify the parent collection of * the resource found at 'path' (for instance when removing the * resource from the collection). */ void ne_lock_using_parent(ne_request *req, const char *path); NE_END_DECLS #endif /* NE_LOCKS_H */ davix-R_0_5_0/deps/libneon/src/ne_md5.c000066400000000000000000000332151257152637300177540ustar00rootroot00000000000000/* 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, 1997 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. */ /* Written by Ulrich Drepper , 1995. */ #include "config.h" #include #include #include #ifdef HAVE_LIMITS_H # include #endif #include "ne_md5.h" #include "ne_string.h" /* for NE_ASC2HEX */ #define md5_process_block ne_md5_process_block #define md5_process_bytes ne_md5_process_bytes #define md5_finish_ctx ne_md5_finish_ctx #define md5_read_ctx ne_md5_read_ctx #define md5_stream ne_md5_stream #define md5_ctx ne_md5_ctx #ifdef WORDS_BIGENDIAN # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else # define SWAP(n) (n) #endif #if SIZEOF_INT == 4 typedef unsigned int md5_uint32; #elif SIZEOF_LONG == 4 typedef unsigned long md5_uint32; #else # error "Cannot determine unsigned 32-bit data type." #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]; }; /* 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) */ static void md5_init_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; } struct ne_md5_ctx * ne_md5_create_ctx(void) { struct md5_ctx *ctx = ne_malloc(sizeof *ctx); md5_init_ctx(ctx); return ctx; } extern void ne_md5_reset_ctx(struct ne_md5_ctx *ctx) { md5_init_ctx(ctx); } struct ne_md5_ctx * ne_md5_dup_ctx(struct ne_md5_ctx *ctx) { return memcpy(ne_malloc(sizeof *ctx), ctx, sizeof *ctx); } void ne_md5_destroy_ctx(struct ne_md5_ctx *ctx) { ne_free(ctx); } /* 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 (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 (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 (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; } void md5_process_bytes (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 (const void *buffer, size_t len, struct md5_ctx *ctx) { md5_uint32 correct_words[16]; const unsigned char *words = buffer; const unsigned char *endp = words + len; 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 \ { \ md5_uint32 WORD_ = (md5_uint32)words[0] | ((md5_uint32)words[1] << 8) \ | ((md5_uint32)words[2] << 16) | ((md5_uint32)words[3] << 24); \ a += FF (b, c, d) + (*cwp++ = WORD_) + T; \ words += 4; \ CYCLIC (a, s); \ a += b; \ } \ while (0) /* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) /* 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 */ /* 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; \ CYCLIC (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; } /* Writes the ASCII representation of the MD5 digest into the * given buffer, which must be at least 33 characters long. */ void ne_md5_to_ascii(const unsigned char md5_buf[16], char *buffer) { int count; for (count = 0; count<16; count++) { buffer[count*2] = NE_HEX2ASC(md5_buf[count] >> 4); buffer[count*2+1] = NE_HEX2ASC(md5_buf[count] & 0x0f); } buffer[32] = '\0'; } /* Reads the ASCII representation of an MD5 digest. The buffer must * be at least 32 characters long. */ void ne_ascii_to_md5(const char *buffer, unsigned char md5_buf[16]) { int count; for (count = 0; count<16; count++) { md5_buf[count] = ((NE_ASC2HEX(buffer[count*2])) << 4) | NE_ASC2HEX(buffer[count*2+1]); } } char *ne_md5_finish_ascii(struct ne_md5_ctx *ctx, char buffer[33]) { md5_uint32 result[4]; ne_md5_finish_ctx(ctx, (void *)result); ne_md5_to_ascii((void *)result, buffer); return buffer; } davix-R_0_5_0/deps/libneon/src/ne_md5.h000066400000000000000000000075201257152637300177610ustar00rootroot00000000000000/* Declaration of functions and data types used for MD5 sum computing library functions. Copyright (C) 2006, Joe Orton Copyright (C) 1995, 1996, 1997 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. */ #ifndef NE_MD5_H #define NE_MD5_H 1 #include #include "ne_defs.h" NE_BEGIN_DECLS /* * The following three functions are build up the low level used in * the functions `md5_stream' and `md5_buffer'. */ struct ne_md5_ctx; /* Create structure containing state of computation. */ extern struct ne_md5_ctx *ne_md5_create_ctx(void); /* 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 ne_md5_process_block(const void *buffer, size_t len, struct ne_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 ne_md5_process_bytes(const void *buffer, size_t len, struct ne_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 is correctly aligned for a 32 bits value. */ extern void *ne_md5_finish_ctx(struct ne_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 *ne_md5_read_ctx(const struct ne_md5_ctx *ctx, void *resbuf); /* Take a copy of the state structure. */ extern struct ne_md5_ctx *ne_md5_dup_ctx(struct ne_md5_ctx *ctx); /* Re-initialize the context structure. */ extern void ne_md5_reset_ctx(struct ne_md5_ctx *ctx); /* Destroy the context structure. */ extern void ne_md5_destroy_ctx(struct ne_md5_ctx *ctx); /* 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 ne_md5_stream(FILE *stream, void *resblock); /* Process the remaining bytes in the buffer and put ASCII representation of the resulting message digest from CTX in the first 33 bytes of BUFFER, including a trailing NUL terminator byte. Returns pointer to buffer. */ char *ne_md5_finish_ascii(struct ne_md5_ctx *ctx, char buffer[33]); /* MD5 ascii->binary conversion */ void ne_md5_to_ascii(const unsigned char md5_buf[16], char *buffer); void ne_ascii_to_md5(const char *buffer, unsigned char md5_buf[16]); NE_END_DECLS #endif /* NE_MD5_H */ davix-R_0_5_0/deps/libneon/src/ne_ntlm.c000066400000000000000000000476141257152637300202510ustar00rootroot00000000000000/* Handling of NTLM Authentication Copyright (C) 2003, Daniel Stenberg Copyright (C) 2009, Kai Sommerfeld This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* NTLM details: http://davenport.sourceforge.net/ntlm.html http://www.innovation.ch/java/ntlm.html */ #include "ne_ntlm.h" #ifdef HAVE_NTLM #include "ne_string.h" typedef enum { NTLMSTATE_NONE, NTLMSTATE_TYPE1, NTLMSTATE_TYPE2, NTLMSTATE_TYPE3, NTLMSTATE_LAST } NTLMState; struct ne_ntlm_context_s { NTLMState state; unsigned char nonce[8]; char *user; char *passwd; char *requestToken; }; typedef enum { NTLM_NONE, /* not a ntlm */ NTLM_BAD, /* an ntlm, but one we don't like */ NTLM_FIRST, /* the first 401-reply we got with NTLM */ NTLM_FINE, /* an ntlm we act on */ NTLM_LAST /* last entry in this enum, don't use */ } ntlm; /* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */ #define NTLMFLAG_NEGOTIATE_UNICODE (1<<0) /* Indicates that Unicode strings are supported for use in security buffer data. */ #define NTLMFLAG_NEGOTIATE_OEM (1<<1) /* Indicates that OEM strings are supported for use in security buffer data. */ #define NTLMFLAG_REQUEST_TARGET (1<<2) /* Requests that the server's authentication realm be included in the Type 2 message. */ /* unknown (1<<3) */ #define NTLMFLAG_NEGOTIATE_SIGN (1<<4) /* Specifies that authenticated communication between the client and server should carry a digital signature (message integrity). */ #define NTLMFLAG_NEGOTIATE_SEAL (1<<5) /* Specifies that authenticated communication between the client and server should be encrypted (message confidentiality). */ #define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6) /* unknown purpose */ #define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7) /* Indicates that the LAN Manager session key should be used for signing and sealing authenticated communications. */ #define NTLMFLAG_NEGOTIATE_NETWARE (1<<8) /* unknown purpose */ #define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9) /* Indicates that NTLM authentication is being used. */ /* unknown (1<<10) */ /* unknown (1<<11) */ #define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12) /* Sent by the client in the Type 1 message to indicate that a desired authentication realm is included in the message. */ #define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13) /* Sent by the client in the Type 1 message to indicate that the client workstation's name is included in the message. */ #define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14) /* Sent by the server to indicate that the server and client are on the same machine. Implies that the client may use a pre-established local security context rather than responding to the challenge. */ #define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15) /* Indicates that authenticated communication between the client and server should be signed with a "dummy" signature. */ #define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16) /* Sent by the server in the Type 2 message to indicate that the target authentication realm is a domain. */ #define NTLMFLAG_TARGET_TYPE_SERVER (1<<17) /* Sent by the server in the Type 2 message to indicate that the target authentication realm is a server. */ #define NTLMFLAG_TARGET_TYPE_SHARE (1<<18) /* Sent by the server in the Type 2 message to indicate that the target authentication realm is a share. Presumably, this is for share-level authentication. Usage is unclear. */ #define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19) /* Indicates that the NTLM2 signing and sealing scheme should be used for protecting authenticated communications. */ #define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20) /* unknown purpose */ #define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21) /* unknown purpose */ #define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22) /* unknown purpose */ #define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23) /* Sent by the server in the Type 2 message to indicate that it is including a Target Information block in the message. */ /* unknown (1<24) */ /* unknown (1<25) */ /* unknown (1<26) */ /* unknown (1<27) */ /* unknown (1<28) */ #define NTLMFLAG_NEGOTIATE_128 (1<<29) /* Indicates that 128-bit encryption is supported. */ #define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30) /* unknown purpose */ #define NTLMFLAG_NEGOTIATE_56 (1<<31) /* Indicates that 56-bit encryption is supported. */ #ifdef HAVE_OPENSSL /* We need OpenSSL for the crypto lib to provide us with MD4 and DES */ /* -- WIN32 approved -- */ #include #include #include #include #include #include #include #include #if OPENSSL_VERSION_NUMBER < 0x00907001L #define DES_key_schedule des_key_schedule #define DES_cblock des_cblock #define DES_set_odd_parity des_set_odd_parity #define DES_set_key des_set_key #define DES_ecb_encrypt des_ecb_encrypt /* This is how things were done in the old days */ #define DESKEY(x) x #define DESKEYARG(x) x #else /* Modern version */ #define DESKEYARG(x) *x #define DESKEY(x) &x #endif /* Define this to make the type-3 message include the NT response message */ #define USE_NTRESPONSES 1 /* (*) = A "security buffer" is a triplet consisting of two shorts and one long: 1. a 'short' containing the length of the buffer in bytes 2. a 'short' containing the allocated space for the buffer in bytes 3. a 'long' containing the offset to the start of the buffer from the beginning of the NTLM message, in bytes. */ static ntlm ne_input_ntlm(ne_ntlm_context *ctx, const char *responseToken) { if(responseToken) { /* We got a type-2 message here: Index Description Content 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" (0x4e544c4d53535000) 8 NTLM Message Type long (0x02000000) 12 Target Name security buffer(*) 20 Flags long 24 Challenge 8 bytes (32) Context (optional) 8 bytes (two consecutive longs) (40) Target Information (optional) security buffer(*) 32 (48) start of data block */ unsigned char * buffer = NULL; int size = ne_unbase64(responseToken, &buffer); ctx->state = NTLMSTATE_TYPE2; /* we got a type-2 */ if(size >= 48) /* the nonce of interest is index [24 .. 31], 8 bytes */ memcpy(ctx->nonce, &buffer[24], 8); /* at index decimal 20, there's a 32bit NTLM flag field */ if (buffer) ne_free(buffer); } else { if(ctx->state >= NTLMSTATE_TYPE1) return NTLM_BAD; ctx->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */ } return NTLM_FINE; } /* * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The * key schedule ks is also set. */ static void setup_des_key(unsigned char *key_56, DES_key_schedule DESKEYARG(ks)) { DES_cblock key; key[0] = key_56[0]; key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1); key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2); key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3); key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4); key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5); key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6); key[7] = (key_56[6] << 1) & 0xFF; DES_set_odd_parity(&key); DES_set_key(&key, ks); } /* * takes a 21 byte array and treats it as 3 56-bit DES keys. The * 8 byte plaintext is encrypted with each key and the resulting 24 * bytes are stored in the results array. */ static void calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results) { DES_key_schedule ks; setup_des_key(keys, DESKEY(ks)); DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results, DESKEY(ks), DES_ENCRYPT); setup_des_key(keys+7, DESKEY(ks)); DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8), DESKEY(ks), DES_ENCRYPT); setup_des_key(keys+14, DESKEY(ks)); DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16), DESKEY(ks), DES_ENCRYPT); } /* * Set up lanmanager and nt hashed passwords */ static void mkhash(char *password, unsigned char *nonce, /* 8 bytes */ unsigned char *lmresp /* must fit 0x18 bytes */ #ifdef USE_NTRESPONSES , unsigned char *ntresp /* must fit 0x18 bytes */ #endif ) { unsigned char lmbuffer[21]; #ifdef USE_NTRESPONSES unsigned char ntbuffer[21]; #endif unsigned char *pw; static const unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; int i; int len = strlen(password); /* make it fit at least 14 bytes */ pw = ne_malloc(len<7?14:len*2); if(!pw) return; /* this will lead to a badly generated package */ if (len > 14) len = 14; for (i=0; i> 8) #define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \ (((x) >>16)&0xff), ((x)>>24) /* this is for creating ntlm header output */ static int ne_output_ntlm(ne_ntlm_context *ctx) { const char *domain=""; /* empty */ const char *host=""; /* empty */ int domlen=strlen(domain); int hostlen = strlen(host); int hostoff; /* host name offset */ int domoff; /* domain name offset */ int size; unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */ if(!ctx->user || !ctx->passwd) /* no user, no auth */ return 0; /* OK */ switch(ctx->state) { case NTLMSTATE_TYPE1: default: /* for the weird cases we (re)start here */ hostoff = 32; domoff = hostoff + hostlen; /* Create and send a type-1 message: Index Description Content 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" (0x4e544c4d53535000) 8 NTLM Message Type long (0x01000000) 12 Flags long 16 Supplied Domain security buffer(*) 24 Supplied Workstation security buffer(*) 32 start of data block */ ne_snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c" "\x01%c%c%c" /* 32-bit type = 1 */ "%c%c%c%c" /* 32-bit NTLM flag field */ "%c%c" /* domain length */ "%c%c" /* domain allocated space */ "%c%c" /* domain name offset */ "%c%c" /* 2 zeroes */ "%c%c" /* host length */ "%c%c" /* host allocated space */ "%c%c" /* host name offset */ "%c%c" /* 2 zeroes */ "%s" /* host name */ "%s", /* domain string */ 0, /* trailing zero */ 0,0,0, /* part of type-1 long */ LONGQUARTET( NTLMFLAG_NEGOTIATE_OEM| /* 2 */ NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */ /* equals 0x0202 */ ), SHORTPAIR(domlen), SHORTPAIR(domlen), SHORTPAIR(domoff), 0,0, SHORTPAIR(hostlen), SHORTPAIR(hostlen), SHORTPAIR(hostoff), 0,0, host, domain); /* initial packet length */ size = 32 + hostlen + domlen; /* now keeper of the base64 encoded package size */ if (ctx->requestToken) ne_free(ctx->requestToken); ctx->requestToken = ne_base64(ntlmbuf, size); break; case NTLMSTATE_TYPE2: /* We received the type-2 already, create a type-3 message: Index Description Content 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" (0x4e544c4d53535000) 8 NTLM Message Type long (0x03000000) 12 LM/LMv2 Response security buffer(*) 20 NTLM/NTLMv2 Response security buffer(*) 28 Domain Name security buffer(*) 36 User Name security buffer(*) 44 Workstation Name security buffer(*) (52) Session Key (optional) security buffer(*) (60) Flags (optional) long 52 (64) start of data block */ { int lmrespoff; int ntrespoff; int useroff; unsigned char lmresp[0x18]; /* fixed-size */ #ifdef USE_NTRESPONSES unsigned char ntresp[0x18]; /* fixed-size */ #endif const char *user; int userlen; user = strchr(ctx->user, '\\'); if(!user) user = strchr(ctx->user, '/'); if (user) { domain = ctx->user; domlen = user - domain; user++; } else user = ctx->user; userlen = strlen(user); mkhash(ctx->passwd, &ctx->nonce[0], lmresp #ifdef USE_NTRESPONSES , ntresp #endif ); domoff = 64; /* always */ useroff = domoff + domlen; hostoff = useroff + userlen; lmrespoff = hostoff + hostlen; ntrespoff = lmrespoff + 0x18; /* Create the big type-3 message binary blob */ size = ne_snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c" "\x03%c%c%c" /* type-3, 32 bits */ "%c%c%c%c" /* LanManager length + allocated space */ "%c%c" /* LanManager offset */ "%c%c" /* 2 zeroes */ "%c%c" /* NT-response length */ "%c%c" /* NT-response allocated space */ "%c%c" /* NT-response offset */ "%c%c" /* 2 zeroes */ "%c%c" /* domain length */ "%c%c" /* domain allocated space */ "%c%c" /* domain name offset */ "%c%c" /* 2 zeroes */ "%c%c" /* user length */ "%c%c" /* user allocated space */ "%c%c" /* user offset */ "%c%c" /* 2 zeroes */ "%c%c" /* host length */ "%c%c" /* host allocated space */ "%c%c" /* host offset */ "%c%c%c%c%c%c" /* 6 zeroes */ "\xff\xff" /* message length */ "%c%c" /* 2 zeroes */ "\x01\x82" /* flags */ "%c%c" /* 2 zeroes */ /* domain string */ /* user string */ /* host string */ /* LanManager response */ /* NT response */ , 0, /* zero termination */ 0,0,0, /* type-3 long, the 24 upper bits */ SHORTPAIR(0x18), /* LanManager response length, twice */ SHORTPAIR(0x18), SHORTPAIR(lmrespoff), 0x0, 0x0, #ifdef USE_NTRESPONSES SHORTPAIR(0x18), /* NT-response length, twice */ SHORTPAIR(0x18), #else 0x0, 0x0, 0x0, 0x0, #endif SHORTPAIR(ntrespoff), 0x0, 0x0, SHORTPAIR(domlen), SHORTPAIR(domlen), SHORTPAIR(domoff), 0x0, 0x0, SHORTPAIR(userlen), SHORTPAIR(userlen), SHORTPAIR(useroff), 0x0, 0x0, SHORTPAIR(hostlen), SHORTPAIR(hostlen), SHORTPAIR(hostoff), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0); /* size is now 64 */ size=64; ntlmbuf[62]=ntlmbuf[63]=0; /* Make sure that the user and domain strings fit in the target buffer before we copy them there. */ if((size_t)size + userlen + domlen >= sizeof(ntlmbuf)) { return -1; } memcpy(&ntlmbuf[size], domain, domlen); size += domlen; memcpy(&ntlmbuf[size], user, userlen); size += userlen; /* we append the binary hashes to the end of the blob */ if(size < ((int)sizeof(ntlmbuf) - 0x18)) { memcpy(&ntlmbuf[size], lmresp, 0x18); size += 0x18; } #ifdef USE_NTRESPONSES if(size < ((int)sizeof(ntlmbuf) - 0x18)) { memcpy(&ntlmbuf[size], ntresp, 0x18); size += 0x18; } #endif ntlmbuf[56] = size & 0xff; ntlmbuf[57] = size >> 8; /* convert the binary blob into base64 */ ctx->requestToken = ne_base64(ntlmbuf, size); ctx->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ } break; case NTLMSTATE_TYPE3: /* connection is already authenticated, * don't send a header in future requests */ if (ctx->requestToken) ne_free(ctx->requestToken); ctx->requestToken = NULL; break; } return 0; /* OK */ } ne_ntlm_context *ne__ntlm_create_context(const char *userName, const char *password) { ne_ntlm_context *ctx = ne_calloc(sizeof(ne_ntlm_context)); ctx->state = NTLMSTATE_NONE; ctx->user = ne_strdup(userName); ctx->passwd = ne_strdup(password); return ctx; } void ne__ntlm_destroy_context(ne_ntlm_context *context) { if (context->user) ne_free(context->user); if (context->passwd) ne_free(context->passwd); if (context->requestToken) ne_free(context->requestToken); ne_free(context); } int ne__ntlm_authenticate(ne_ntlm_context *context, const char *responseToken) { if (context == NULL) { return -1; } else { if (!responseToken && (context->state == NTLMSTATE_TYPE3)) context->state = NTLMSTATE_NONE; if (context->state <= NTLMSTATE_TYPE3) { ntlm ntlmstatus = ne_input_ntlm(context, responseToken); if (ntlmstatus != NTLM_FINE) { return -1; } } } return ne_output_ntlm(context); } char *ne__ntlm_getRequestToken(ne_ntlm_context *context) { char *ret; if (context == NULL || !context->requestToken) { return NULL; } ret = ne_strdup(context->requestToken); ne_free(context->requestToken); context->requestToken = NULL; return ret; } #endif /* HAVE_OPENSSL */ #endif /* HAVE_NTLM */ davix-R_0_5_0/deps/libneon/src/ne_ntlm.h000066400000000000000000000027211257152637300202440ustar00rootroot00000000000000/* Handling of NTLM Authentication Copyright (C) 2009, Kai Sommerfeld This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_NTLM_H #define NE_NTLM_H #include "config.h" /* PRIVATE TO NEON -- NOT PART OF THE EXTERNAL API. */ #ifdef HAVE_NTLM #include "ne_defs.h" typedef struct ne_ntlm_context_s ne_ntlm_context; NE_PRIVATE ne_ntlm_context *ne__ntlm_create_context(const char *userName, const char *password); NE_PRIVATE int ne__ntlm_clear_context(ne_ntlm_context *context); NE_PRIVATE void ne__ntlm_destroy_context(ne_ntlm_context *context); NE_PRIVATE int ne__ntlm_authenticate(ne_ntlm_context *context, const char *responseToken); NE_PRIVATE char *ne__ntlm_getRequestToken(ne_ntlm_context *context); #endif /* HAVE_NTLM */ #endif /* NE_NTLM_H */ davix-R_0_5_0/deps/libneon/src/ne_oldacl.c000066400000000000000000000067621257152637300205340ustar00rootroot00000000000000/* Access control Copyright (C) 2001-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Contributed by Arun Garg */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include "ne_request.h" #include "ne_locks.h" #include "ne_alloc.h" #include "ne_string.h" #include "ne_acl.h" #include "ne_uri.h" #include "ne_xml.h" /* for NE_XML_MEDIA_TYPE */ #define EOL "\r\n" static ne_buffer *acl_body(const ne_acl_entry *right, int count) { ne_buffer *body = ne_buffer_create(); int m; ne_buffer_zappend(body, "" EOL "" EOL); for (m = 0; m < count; m++) { const char *type; type = (right[m].type == ne_acl_grant ? "grant" : "deny"); ne_buffer_concat(body, "" EOL "", NULL); switch (right[m].apply) { case ne_acl_all: ne_buffer_zappend(body, "" EOL); break; case ne_acl_property: ne_buffer_concat(body, "<", right[m].principal, "/>" EOL, NULL); break; case ne_acl_href: ne_buffer_concat(body, "", right[m].principal, "" EOL, NULL); break; } ne_buffer_concat(body, "" EOL "<", type, ">" EOL, NULL); if (right[m].read == 0) ne_buffer_concat(body, "" "" "" EOL, NULL); if (right[m].read_acl == 0) ne_buffer_concat(body, "" "" "" EOL, NULL); if (right[m].write == 0) ne_buffer_concat(body, "" "" "" EOL, NULL); if (right[m].write_acl == 0) ne_buffer_concat(body, "" "" "" EOL, NULL); if (right[m].read_cuprivset == 0) ne_buffer_concat(body, "" "" "" EOL, NULL); ne_buffer_concat(body, "" EOL, NULL); ne_buffer_zappend(body, "" EOL); } ne_buffer_zappend(body, "" EOL); return body; } int ne_acl_set(ne_session *sess, const char *uri, const ne_acl_entry *entries, int numentries) { int ret; ne_request *req = ne_request_create(sess, "ACL", uri); ne_buffer *body = acl_body(entries, numentries); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, uri, 0); #endif ne_set_request_body_buffer(req, body->data, ne_buffer_size(body)); ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); ret = ne_request_dispatch(req); ne_buffer_destroy(body); if (ret == NE_OK && ne_get_status(req)->code == 207) { ret = NE_ERROR; } ne_request_destroy(req); return ret; } davix-R_0_5_0/deps/libneon/src/ne_openssl.c000066400000000000000000001156711257152637300207610ustar00rootroot00000000000000/* neon SSL/TLS support using OpenSSL Copyright (C) 2002-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif #include #ifdef NE_HAVE_TS_SSL #include /* for abort() */ #include #endif #include "ne_ssl.h" #include "ne_string.h" #include "ne_session.h" #include "ne_internal.h" #include "ne_private.h" #include "ne_privssl.h" #include "ne_openssl_internal.h" /* OpenSSL 0.9.6 compatibility */ #if OPENSSL_VERSION_NUMBER < 0x0090700fL #define PKCS12_unpack_authsafes M_PKCS12_unpack_authsafes #define PKCS12_unpack_p7data M_PKCS12_unpack_p7data /* cast away lack of const-ness */ #define OBJ_cmp(a,b) OBJ_cmp((ASN1_OBJECT *)(a), (ASN1_OBJECT *)(b)) #endif /* Second argument for d2i_X509() changed type in 0.9.8. */ #if OPENSSL_VERSION_NUMBER < 0x0090800fL typedef unsigned char ne_d2i_uchar; #else typedef const unsigned char ne_d2i_uchar; #endif #define NE_SSL_UNHANDLED (0x20) /* failure bit for unhandled case. */ /* Append an ASN.1 DirectoryString STR to buffer BUF as UTF-8. * Returns zero on success or non-zero on error. */ static int append_dirstring(ne_buffer *buf, ASN1_STRING *str) { unsigned char *tmp = (unsigned char *)""; /* initialize to workaround 0.9.6 bug */ int len; switch (str->type) { case V_ASN1_IA5STRING: /* definitely ASCII */ case V_ASN1_VISIBLESTRING: /* probably ASCII */ case V_ASN1_PRINTABLESTRING: /* subset of ASCII */ ne_buffer_qappend(buf, str->data, str->length); break; case V_ASN1_UTF8STRING: /* Fail for embedded NUL bytes. */ if (strlen((char *)str->data) != (size_t)str->length) { return -1; } ne_buffer_append(buf, (char *)str->data, str->length); break; case V_ASN1_UNIVERSALSTRING: case V_ASN1_T61STRING: /* let OpenSSL convert it as ISO-8859-1 */ case V_ASN1_BMPSTRING: len = ASN1_STRING_to_UTF8(&tmp, str); if (len > 0) { /* Fail if there were embedded NUL bytes. */ if (strlen((char *)tmp) != (size_t)len) { OPENSSL_free(tmp); return -1; } else { ne_buffer_append(buf, (char *)tmp, len); OPENSSL_free(tmp); } break; } else { ERR_clear_error(); return -1; } break; default: NE_DEBUG(NE_DBG_SSL, "Could not convert DirectoryString type %d", str->type); return -1; } return 0; } /* Returns a malloc-allocated version of IA5 string AS, escaped for * safety. */ static char *dup_ia5string(const ASN1_IA5STRING *as) { return ne_strnqdup(as->data, as->length); } char *ne_ssl_readable_dname(const ne_ssl_dname *name) { int n, flag = 0; ne_buffer *dump = ne_buffer_create(); const ASN1_OBJECT * const cname = OBJ_nid2obj(NID_commonName), * const email = OBJ_nid2obj(NID_pkcs9_emailAddress); for (n = X509_NAME_entry_count(name->dn); n > 0; n--) { X509_NAME_ENTRY *ent = X509_NAME_get_entry(name->dn, n-1); /* Skip commonName or emailAddress except if there is no other * attribute in dname. */ if ((OBJ_cmp(ent->object, cname) && OBJ_cmp(ent->object, email)) || (!flag && n == 1)) { if (flag++) ne_buffer_append(dump, ", ", 2); if (append_dirstring(dump, ent->value)) ne_buffer_czappend(dump, "???"); } } return ne_buffer_finish(dump); } int ne_ssl_dname_cmp(const ne_ssl_dname *dn1, const ne_ssl_dname *dn2) { return X509_NAME_cmp(dn1->dn, dn2->dn); } void ne_ssl_clicert_free(ne_ssl_client_cert *cc) { if (cc->p12) PKCS12_free(cc->p12); if (cc->decrypted) { if (cc->cert.identity) ne_free(cc->cert.identity); EVP_PKEY_free(cc->pkey); X509_free(cc->cert.subject); if(cc->cert.chain != NULL) sk_X509_pop_free(cc->cert.chain, X509_free); } if (cc->friendly_name) ne_free(cc->friendly_name); ne_free(cc); } /* Format an ASN1 time to a string. 'buf' must be at least of size * 'NE_SSL_VDATELEN'. */ static time_t asn1time_to_timet(const ASN1_TIME *atm) { struct tm tm = {0}; int i = atm->length; if (i < 10) return (time_t )-1; tm.tm_year = (atm->data[0]-'0') * 10 + (atm->data[1]-'0'); /* Deal with Year 2000 */ if (tm.tm_year < 70) tm.tm_year += 100; tm.tm_mon = (atm->data[2]-'0') * 10 + (atm->data[3]-'0') - 1; tm.tm_mday = (atm->data[4]-'0') * 10 + (atm->data[5]-'0'); tm.tm_hour = (atm->data[6]-'0') * 10 + (atm->data[7]-'0'); tm.tm_min = (atm->data[8]-'0') * 10 + (atm->data[9]-'0'); tm.tm_sec = (atm->data[10]-'0') * 10 + (atm->data[11]-'0'); #ifdef HAVE_TIMEZONE /* ANSI C time handling is... interesting. */ return mktime(&tm) - timezone; #else return mktime(&tm); #endif } void ne_ssl_cert_validity_time(const ne_ssl_certificate *cert, time_t *from, time_t *until) { if (from) { *from = asn1time_to_timet(X509_get_notBefore(cert->subject)); } if (until) { *until = asn1time_to_timet(X509_get_notAfter(cert->subject)); } } /* Check certificate identity. Returns zero if identity matches; 1 if * identity does not match, or <0 if the certificate had no identity. * If 'identity' is non-NULL, store the malloc-allocated identity in * *identity. Logic specified by RFC 2818 and RFC 3280. */ static int check_identity(const ne_uri *server, X509 *cert, char **identity) { STACK_OF(GENERAL_NAME) *names; int match = 0, found = 0; const char *hostname; hostname = server ? server->host : ""; names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); if (names) { int n; /* subjectAltName contains a sequence of GeneralNames */ for (n = 0; n < sk_GENERAL_NAME_num(names) && !match; n++) { GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, n); /* handle dNSName and iPAddress name extensions only. */ if (nm->type == GEN_DNS) { char *name = dup_ia5string(nm->d.ia5); if (identity && !found) *identity = ne_strdup(name); match = ne__ssl_match_hostname(name, strlen(name), hostname); ne_free(name); found = 1; } else if (nm->type == GEN_IPADD) { /* compare IP address with server IP address. */ ne_inet_addr *ia; if (nm->d.ip->length == 4) ia = ne_iaddr_make(ne_iaddr_ipv4, nm->d.ip->data); else if (nm->d.ip->length == 16) ia = ne_iaddr_make(ne_iaddr_ipv6, nm->d.ip->data); else ia = NULL; /* ne_iaddr_make returns NULL if address type is unsupported */ if (ia != NULL) { /* address type was supported. */ char buf[128]; match = strcmp(hostname, ne_iaddr_print(ia, buf, sizeof buf)) == 0; found = 1; ne_iaddr_free(ia); } else { NE_DEBUG(NE_DBG_SSL, "iPAddress name with unsupported " "address type (length %d), skipped.\n", nm->d.ip->length); } } else if (nm->type == GEN_URI) { char *name = dup_ia5string(nm->d.ia5); ne_uri uri; if (ne_uri_parse(name, &uri) == 0 && uri.host && uri.scheme) { ne_uri tmp; if (identity && !found) *identity = ne_strdup(name); found = 1; if (server) { /* For comparison purposes, all that matters is * host, scheme and port; ignore the rest. */ memset(&tmp, 0, sizeof tmp); tmp.host = uri.host; tmp.scheme = uri.scheme; tmp.port = uri.port; match = ne_uri_cmp(server, &tmp) == 0; } } ne_uri_free(&uri); ne_free(name); } } /* free the whole stack. */ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); } /* Check against the commonName if no DNS alt. names were found, * as per RFC3280. */ if (!found) { X509_NAME *subj = X509_get_subject_name(cert); X509_NAME_ENTRY *entry; ne_buffer *cname = ne_buffer_ncreate(30); int idx = -1, lastidx; /* find the most specific commonName attribute. */ do { lastidx = idx; idx = X509_NAME_get_index_by_NID(subj, NID_commonName, lastidx); } while (idx >= 0); if (lastidx < 0) { /* no commonName attributes at all. */ ne_buffer_destroy(cname); return -1; } /* extract the string from the entry */ entry = X509_NAME_get_entry(subj, lastidx); if (append_dirstring(cname, X509_NAME_ENTRY_get_data(entry))) { ne_buffer_destroy(cname); return -1; } if (identity) *identity = ne_strdup(cname->data); match = ne__ssl_match_hostname(cname->data, cname->used - 1, hostname); ne_buffer_destroy(cname); } NE_DEBUG(NE_DBG_SSL, "Identity match for '%s': %s", hostname, match ? "good" : "bad"); return match ? 0 : 1; } /* Populate an ne_ssl_certificate structure from an X509 object. */ ne_ssl_certificate *populate_cert(ne_ssl_certificate *cert, X509 *x5) { cert->subj_dn.dn = X509_get_subject_name(x5); cert->issuer_dn.dn = X509_get_issuer_name(x5); cert->issuer = NULL; cert->subject = x5; /* Retrieve the cert identity; pass a dummy hostname to match. */ cert->identity = NULL; check_identity(NULL, x5, &cert->identity); return cert; } /* OpenSSL cert verification callback. This is invoked for *each* * error which is encoutered whilst verifying the cert chain; multiple * invocations for any particular cert in the chain are possible. */ static int verify_callback(int ok, X509_STORE_CTX *ctx) { /* OpenSSL, living in its own little happy world of global state, * where userdata was just a twinkle in the eye of an API designer * yet to be born. Or... "Seriously, wtf?" */ SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ne_session *sess = SSL_get_app_data(ssl); int depth = X509_STORE_CTX_get_error_depth(ctx); int err = X509_STORE_CTX_get_error(ctx); int failures = 0; /* If there's no error, nothing to do here. */ if (ok) return ok; NE_DEBUG(NE_DBG_SSL, "ssl: Verify callback @ %d => %d", depth, err); /* Map the error code onto any of the exported cert validation * errors, if possible. */ switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_CERT_UNTRUSTED: case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: failures |= NE_SSL_UNTRUSTED; break; case X509_V_ERR_CERT_NOT_YET_VALID: failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_NOTYETVALID; break; case X509_V_ERR_CERT_HAS_EXPIRED: failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_EXPIRED; break; case X509_V_OK: break; default: /* Clear the failures bitmask so check_certificate knows this * is a bailout. */ sess->ssl_context->failures |= NE_SSL_UNHANDLED; NE_DEBUG(NE_DBG_SSL, "ssl: Unhandled verification error %d -> %s", err, X509_verify_cert_error_string(err)); return 0; } sess->ssl_context->failures |= failures; NE_DEBUG(NE_DBG_SSL, "ssl: Verify failures |= %d => %d", failures, sess->ssl_context->failures); return 1; } /* Return a linked list of certificate objects from an OpenSSL chain. */ static ne_ssl_certificate *make_chain(STACK_OF(X509) *chain) { int n, count = sk_X509_num(chain); ne_ssl_certificate *top = NULL, *current = NULL; NE_DEBUG(NE_DBG_SSL, "Chain depth: %d", count); for (n = 0; n < count; n++) { ne_ssl_certificate *cert = ne_malloc(sizeof *cert); populate_cert(cert, X509_dup(sk_X509_value(chain, n))); //#ifdef NE_DEBUGGING if((davix_get_log_scope() & NE_DBG_SSL) && (davix_get_log_level() >= DAVIX_LOG_DEBUG)){ NE_DEBUG(NE_DBG_SSL, "Cert #%d:", n); BIO *mem = BIO_new(BIO_s_mem()); X509_print(mem, cert->subject); BIO_puts(mem, ""); // force \0 char* cert_str= NULL; long str_size = BIO_get_mem_data(mem, &cert_str); if(str_size > 0){ NE_DEBUG(NE_DBG_SSL,"%s",cert_str); } BIO_free(mem); } //#endif if (top == NULL) { current = top = cert; } else { current->issuer = cert; current = cert; } } return top; } /* Verifies an SSL server certificate. */ static int check_certificate(ne_session *sess, SSL *ssl, ne_ssl_certificate *chain) { X509 *cert = chain->subject; int ret, failures = sess->ssl_context->failures; ne_uri server; /* If the verification callback hit a case which can't be mapped * to one of the exported error bits, it's treated as a hard * failure rather than invoking the callback, which can't present * a useful error to the user. "Um, something is wrong. OK?" */ if (failures & NE_SSL_UNHANDLED) { long result = SSL_get_verify_result(ssl); ne_set_error(sess, _("Certificate verification error: %s"), X509_verify_cert_error_string(result)); return NE_ERROR; } /* Check certificate was issued to this server; pass URI of * server. */ memset(&server, 0, sizeof server); ne_fill_server_uri(sess, &server); ret = check_identity(&server, cert, NULL); ne_uri_free(&server); if (ret < 0) { ne_set_error(sess, _("Server certificate was missing commonName " "attribute in subject name")); return NE_ERROR; } else if (ret > 0) failures |= NE_SSL_IDMISMATCH; if (failures == 0) { /* verified OK! */ ret = NE_OK; } else { /* Set up the error string. */ ne__ssl_set_verify_err(sess, failures); ret = NE_ERROR; /* Allow manual override */ if (sess->ssl_verify_fn && sess->ssl_verify_fn(sess->ssl_verify_ud, failures, chain) == 0) ret = NE_OK; } return ret; } /* Duplicate a client certificate, which must be in the decrypted state. */ static ne_ssl_client_cert *dup_client_cert(const ne_ssl_client_cert *cc) { ne_ssl_client_cert *newcc = ne_calloc(sizeof *newcc); newcc->decrypted = 1; newcc->pkey = cc->pkey; if (cc->friendly_name) newcc->friendly_name = ne_strdup(cc->friendly_name); populate_cert(&newcc->cert, cc->cert.subject); cc->cert.subject->references++; cc->pkey->references++; if(cc->cert.chain != NULL){ int count, n; newcc->cert.chain = sk_X509_dup(cc->cert.chain); count = sk_X509_num(newcc->cert.chain); for (n = 0; n < count; ++n) { sk_X509_value(newcc->cert.chain, n)->references++; } } return newcc; } /* Callback invoked when the SSL server requests a client certificate. */ static int provide_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey) { ne_session *const sess = SSL_get_app_data(ssl); if (!sess->client_cert && sess->ssl_provide_fn) { ne_ssl_dname **dnames = NULL, *dnarray = NULL; int n, count = 0; STACK_OF(X509_NAME) *ca_list = SSL_get_client_CA_list(ssl); count = ca_list ? sk_X509_NAME_num(ca_list) : 0; if (count > 0) { dnames = ne_malloc(count * sizeof(ne_ssl_dname *)); dnarray = ne_malloc(count * sizeof(ne_ssl_dname)); for (n = 0; n < count; n++) { dnames[n] = &dnarray[n]; dnames[n]->dn = sk_X509_NAME_value(ca_list, n); } } NE_DEBUG(NE_DBG_SSL, "Calling client certificate provider..."); sess->ssl_provide_fn(sess->ssl_provide_ud, sess, (const ne_ssl_dname *const *)dnames, count); if (count) { ne_free(dnarray); ne_free(dnames); } } if (sess->client_cert) { int count, n; SSL_CTX* ctx; ne_ssl_client_cert *const cc = sess->client_cert; NE_DEBUG(NE_DBG_SSL, "Supplying client certificate."); cc->pkey->references++; cc->cert.subject->references++; *cert = cc->cert.subject; *pkey = cc->pkey; /* The only way of adding intermediate cert support (needed for proxies) * is to call this method. See man page for SSL_CTX_set_client_cert_cb */ if(cc->cert.chain != NULL){ ctx = SSL_get_SSL_CTX(ssl); count = sk_X509_num(cc->cert.chain); for (n = 0; n < count; ++n) { SSL_CTX_add_extra_chain_cert(ctx, X509_dup(sk_X509_value(cc->cert.chain, n))); } } return 1; } else { sess->ssl_cc_requested = 1; NE_DEBUG(NE_DBG_SSL, "No client certificate supplied."); return 0; } } void ne_ssl_set_clicert(ne_session *sess, const ne_ssl_client_cert *cc) { sess->client_cert = dup_client_cert(cc); } ne_ssl_client_cert * ne_ssl_dup_client_cert(const ne_ssl_client_cert *cc) { return dup_client_cert(cc); } ne_ssl_context *ne_ssl_context_create(int mode) { ne_ssl_context *ctx = ne_calloc(sizeof *ctx); if (mode == NE_SSL_CTX_CLIENT) { ctx->ctx = SSL_CTX_new(SSLv23_client_method()); ctx->sess = NULL; /* set client cert callback. */ SSL_CTX_set_client_cert_cb(ctx->ctx, provide_client_cert); /* enable workarounds for buggy SSL server implementations */ SSL_CTX_set_options(ctx->ctx, SSL_OP_ALL); SSL_CTX_set_verify(ctx->ctx, SSL_VERIFY_PEER, verify_callback); } else if (mode == NE_SSL_CTX_SERVER) { ctx->ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_session_cache_mode(ctx->ctx, SSL_SESS_CACHE_CLIENT); } else { ctx->ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_session_cache_mode(ctx->ctx, SSL_SESS_CACHE_CLIENT); } SSL_CTX_set_options(ctx->ctx, SSL_OP_NO_SSLv2); // Disable SSLv2, vulnerable SSL_CTX_set_options(ctx->ctx, SSL_OP_NO_SSLv3); // Disable SSLv3, vulnerable return ctx; } void ne_ssl_context_set_flag(ne_ssl_context *ctx, int flag, int value) { long opts = SSL_CTX_get_options(ctx->ctx); switch (flag) { case NE_SSL_CTX_SSLv2: if (value) { /* Enable SSLv2 support; clear the "no SSLv2" flag. */ opts &= ~SSL_OP_NO_SSLv2; } else { /* Disable it: set the flag. */ opts |= SSL_OP_NO_SSLv2; } break; } SSL_CTX_set_options(ctx->ctx, opts); } int ne_ssl_context_keypair(ne_ssl_context *ctx, const char *cert, const char *key) { int ret; ret = SSL_CTX_use_PrivateKey_file(ctx->ctx, key, SSL_FILETYPE_PEM); if (ret == 1) { ret = SSL_CTX_use_certificate_chain_file(ctx->ctx, cert); } return ret == 1 ? 0 : -1; } int ne_ssl_context_set_verify(ne_ssl_context *ctx, int required, const char *ca_names, const char *verify_cas) { if (required) { SSL_CTX_set_verify(ctx->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } if (ca_names) { SSL_CTX_set_client_CA_list(ctx->ctx, SSL_load_client_CA_file(ca_names)); } if (verify_cas) { SSL_CTX_load_verify_locations(ctx->ctx, verify_cas, NULL); } return 0; } void ne_ssl_context_destroy(ne_ssl_context *ctx) { SSL_CTX_free(ctx->ctx); if (ctx->sess) SSL_SESSION_free(ctx->sess); ne_free(ctx); } #if !defined(HAVE_SSL_SESSION_CMP) && !defined(SSL_SESSION_cmp) \ && defined(OPENSSL_VERSION_NUMBER) \ && OPENSSL_VERSION_NUMBER > 0x10000000L /* OpenSSL 1.0 removed SSL_SESSION_cmp for no apparent reason - hoping * it is reasonable to assume that comparing the session IDs is * sufficient. */ static int SSL_SESSION_cmp(SSL_SESSION *a, SSL_SESSION *b) { return a->session_id_length == b->session_id_length && memcmp(a->session_id, b->session_id, a->session_id_length) == 0; } #endif /* For internal use only. */ int ne__negotiate_ssl(ne_session *sess) { ne_ssl_context *ctx = sess->ssl_context; SSL *ssl; STACK_OF(X509) *chain; int freechain = 0; /* non-zero if chain should be free'd. */ NE_DEBUG(NE_DBG_SSL, "Doing SSL negotiation."); /* Pass through the hostname if SNI is enabled. */ ctx->hostname = sess->flags[NE_SESSFLAG_TLS_SNI] ? sess->server.hostname : NULL; sess->ssl_cc_requested = 0; ctx->failures = 0; if (ne_sock_connect_ssl(sess->socket, ctx, sess)) { if (ctx->sess) { /* remove cached session. */ SSL_SESSION_free(ctx->sess); ctx->sess = NULL; } if (sess->ssl_cc_requested) { ne_set_error(sess, _("SSL handshake failed, " "client certificate was requested: %s"), ne_sock_error(sess->socket)); } else { ne_set_error(sess, _("SSL handshake failed: %s"), ne_sock_error(sess->socket)); } return NE_ERROR; } ssl = ne__sock_sslsock(sess->socket); chain = SSL_get_peer_cert_chain(ssl); /* For an SSLv2 connection, the cert chain will always be NULL. */ if (chain == NULL) { X509 *cert = SSL_get_peer_certificate(ssl); if (cert) { chain = sk_X509_new_null(); sk_X509_push(chain, cert); freechain = 1; } } if (chain == NULL || sk_X509_num(chain) == 0) { ne_set_error(sess, _("SSL server did not present certificate")); return NE_ERROR; } if (sess->server_cert) { int diff = X509_cmp(sk_X509_value(chain, 0), sess->server_cert->subject); if (freechain) sk_X509_free(chain); /* no longer need the chain */ if (diff) { /* This could be a MITM attack: fail the request. */ ne_set_error(sess, _("Server certificate changed: " "connection intercepted?")); return NE_ERROR; } /* certificate has already passed verification: no need to * verify it again. */ } else { /* new connection: create the chain. */ ne_ssl_certificate *cert = make_chain(chain); if (freechain) sk_X509_free(chain); /* no longer need the chain */ if (check_certificate(sess, ssl, cert)) { NE_DEBUG(NE_DBG_SSL, "SSL certificate checks failed: %s", sess->error); ne_ssl_cert_free(cert); return NE_ERROR; } /* remember the chain. */ sess->server_cert = cert; } if (ctx->sess) { SSL_SESSION *newsess = SSL_get0_session(ssl); /* Replace the session if it has changed. */ if (newsess != ctx->sess || SSL_SESSION_cmp(ctx->sess, newsess)) { SSL_SESSION_free(ctx->sess); ctx->sess = SSL_get1_session(ssl); /* bumping the refcount */ } } else { /* Store the session. */ ctx->sess = SSL_get1_session(ssl); } return NE_OK; } const ne_ssl_dname *ne_ssl_cert_issuer(const ne_ssl_certificate *cert) { return &cert->issuer_dn; } const ne_ssl_dname *ne_ssl_cert_subject(const ne_ssl_certificate *cert) { return &cert->subj_dn; } const ne_ssl_certificate *ne_ssl_cert_signedby(const ne_ssl_certificate *cert) { return cert->issuer; } const char *ne_ssl_cert_identity(const ne_ssl_certificate *cert) { return cert->identity; } void ne_ssl_context_trustcert(ne_ssl_context *ctx, const ne_ssl_certificate *cert) { X509_STORE *store = SSL_CTX_get_cert_store(ctx->ctx); X509_STORE_add_cert(store, cert->subject); } int ne_ssl_context_trust_add_ca_path(ne_ssl_context * ctx, const char* path){ X509_STORE *store = SSL_CTX_get_cert_store(ctx->ctx); return ((X509_STORE_load_locations(store, NULL, path) ==1)?0:-1); } void ne_ssl_trust_default_ca(ne_session *sess) { X509_STORE *store = SSL_CTX_get_cert_store(sess->ssl_context->ctx); #ifdef NE_SSL_CA_BUNDLE X509_STORE_load_locations(store, NE_SSL_CA_BUNDLE, NULL); #else X509_STORE_set_default_paths(store); #endif } /* Find a friendly name in a PKCS12 structure the hard way, without * decrypting the parts which are encrypted.. */ static char *find_friendly_name(PKCS12 *p12) { STACK_OF(PKCS7) *safes = PKCS12_unpack_authsafes(p12); int n, m; char *name = NULL; if (safes == NULL) return NULL; /* Iterate over the unpacked authsafes: */ for (n = 0; n < sk_PKCS7_num(safes) && !name; n++) { PKCS7 *safe = sk_PKCS7_value(safes, n); STACK_OF(PKCS12_SAFEBAG) *bags; /* Only looking for unencrypted authsafes. */ if (OBJ_obj2nid(safe->type) != NID_pkcs7_data) continue; bags = PKCS12_unpack_p7data(safe); if (!bags) continue; /* Iterate through the bags, picking out a friendly name */ for (m = 0; m < sk_PKCS12_SAFEBAG_num(bags) && !name; m++) { PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, m); name = PKCS12_get_friendlyname(bag); } sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); } sk_PKCS7_pop_free(safes, PKCS7_free); return name; } ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename) { PKCS12 *p12; FILE *fp; X509 *cert; STACK_OF(X509)* chain = NULL; EVP_PKEY *pkey; ne_ssl_client_cert *cc; fp = fopen(filename, "rb"); if (fp == NULL) return NULL; p12 = d2i_PKCS12_fp(fp, NULL); fclose(fp); if (p12 == NULL) { ERR_clear_error(); return NULL; } /* Try parsing with no password. */ if (PKCS12_parse(p12, NULL, &pkey, &cert, &chain) == 1) { /* Success - no password needed for decryption. */ int len = 0; unsigned char *name; if (!cert || !pkey) { PKCS12_free(p12); return NULL; } name = X509_alias_get0(cert, &len); cc = ne_calloc(sizeof *cc); cc->pkey = pkey; cc->decrypted = 1; if (name && len > 0) cc->friendly_name = ne_strndup((char *)name, len); populate_cert(&cc->cert, cert); cc->cert.chain = chain; PKCS12_free(p12); return cc; } else { /* Failed to parse the file */ int err = ERR_get_error(); ERR_clear_error(); if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 && ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { /* Decryption error due to bad password. */ cc = ne_calloc(sizeof *cc); cc->friendly_name = find_friendly_name(p12); cc->p12 = p12; return cc; } else { /* Some parse error, give up. */ PKCS12_free(p12); return NULL; } } } int ne_ssl_pem_passwd_cb(char *buf, int size, int rwflag, void *userdata){ if(userdata != NULL){ strncpy(buf, (char *)(userdata), size); buf[size - 1] = '\0'; return(strlen(buf)); } return 0; } ne_ssl_client_cert *ne_ssl_clicert_pem_read(const char* pkeyfile, const char* credfile, const char* password){ FILE *fp; BIO* in; X509 *cert,*ca; STACK_OF(X509)* chain = NULL; EVP_PKEY *pkey; ne_ssl_client_cert *cc; int len, err; unsigned char* name; if(pkeyfile ==NULL || credfile ==NULL) return NULL; if( (in = BIO_new(BIO_s_file())) == NULL){ NE_DEBUG(NE_DBG_SSL, "BIO init error"); return NULL; } // load cred if (BIO_read_filename(in, credfile) <= 0){ NE_DEBUG(NE_DBG_SSL, "impossible to open %s : %s", credfile, ERR_reason_error_string(ERR_get_error())); return NULL; } if ( (cert = PEM_read_bio_X509(in, NULL, ne_ssl_pem_passwd_cb, (void*) password)) == NULL){ NE_DEBUG(NE_DBG_SSL, " parse PEM credential %s failed : %s", credfile, ERR_reason_error_string(ERR_get_error())); ERR_clear_error(); BIO_free(in); return NULL; } // load chain chain = sk_X509_new_null(); while ((ca = PEM_read_bio_X509(in,NULL, ne_ssl_pem_passwd_cb, (void*) password)) != NULL){ sk_X509_push(chain, ca); } /* When the while loop ends, it's usually just EOF. */ BIO_free(in); err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE){ ERR_clear_error(); }else{ NE_DEBUG(NE_DBG_SSL, " parse PEM credential chain %s failed : %s", credfile, ERR_reason_error_string(err)); ERR_clear_error(); X509_free(cert); return NULL; } // load pkey fp = fopen(pkeyfile, "rb"); if (fp == NULL){ NE_DEBUG(NE_DBG_SSL, "impossible to open %s : %s", pkeyfile, strerror(errno)); errno = 0; X509_free(cert); return NULL; } if ( (pkey = PEM_read_PrivateKey(fp, NULL, ne_ssl_pem_passwd_cb, (void*) password)) == NULL){ NE_DEBUG(NE_DBG_SSL, " parse PEM private key %s failed : %s", pkeyfile, ERR_reason_error_string(ERR_get_error())); ERR_clear_error(); X509_free(cert); return NULL; } fclose(fp); // load ca chain name = X509_alias_get0(cert, &len); cc = ne_calloc(sizeof(ne_ssl_client_cert)); cc->pkey = pkey; cc->decrypted = 1; if (name && len > 0) cc->friendly_name = ne_strndup((char *)name, len); populate_cert(&cc->cert, cert); cc->cert.chain = chain; return cc; } #ifdef HAVE_PAKCHOIS ne_ssl_client_cert *ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len, const RSA_METHOD *method) { ne_ssl_client_cert *cc; ne_d2i_uchar *p; X509 *x5; RSA *pk; EVP_PKEY *epk, *tpk; p = der; x5 = d2i_X509(NULL, &p, der_len); /* p is incremented */ if (x5 == NULL) { ERR_clear_error(); return NULL; } pk = RSA_new(); RSA_set_method(pk, method); epk = EVP_PKEY_new(); EVP_PKEY_assign_RSA(epk, pk); /* It is necessary to initialize pk->n otherwise OpenSSL will barf * later calling RSA_size() on this RSA structure. * X509_get_pubkey() forces the relevant RSA parameters to be * extracted from the certificate. */ tpk = X509_get_pubkey(x5); pk->n = BN_dup(tpk->pkey.rsa->n); EVP_PKEY_free(tpk); cc = ne_calloc(sizeof *cc); cc->decrypted = 1; cc->pkey = epk; populate_cert(&cc->cert, x5); return cc; } #endif int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *cc) { return !cc->decrypted; } int ne_ssl_clicert_decrypt(ne_ssl_client_cert *cc, const char *password) { X509 *cert; EVP_PKEY *pkey; if (PKCS12_parse(cc->p12, password, &pkey, &cert, NULL) != 1) { ERR_clear_error(); return -1; } if (X509_check_private_key(cert, pkey) != 1) { ERR_clear_error(); X509_free(cert); EVP_PKEY_free(pkey); NE_DEBUG(NE_DBG_SSL, "Decrypted private key/cert are not matched."); return -1; } PKCS12_free(cc->p12); populate_cert(&cc->cert, cert); cc->pkey = pkey; cc->decrypted = 1; cc->p12 = NULL; return 0; } const ne_ssl_certificate *ne_ssl_clicert_owner(const ne_ssl_client_cert *cc) { return &cc->cert; } const char *ne_ssl_clicert_name(const ne_ssl_client_cert *ccert) { return ccert->friendly_name; } ne_ssl_certificate *ne_ssl_cert_read(const char *filename) { FILE *fp = fopen(filename, "r"); X509 *cert; if (fp == NULL) return NULL; cert = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); if (cert == NULL) { NE_DEBUG(NE_DBG_SSL, "d2i_X509_fp failed: %s", ERR_reason_error_string(ERR_get_error())); ERR_clear_error(); return NULL; } return populate_cert(ne_calloc(sizeof(struct ne_ssl_certificate_s)), cert); } int ne_ssl_cert_write(const ne_ssl_certificate *cert, const char *filename) { FILE *fp = fopen(filename, "w"); if (fp == NULL) return -1; if (PEM_write_X509(fp, cert->subject) != 1) { ERR_clear_error(); fclose(fp); return -1; } if (fclose(fp) != 0) return -1; return 0; } void ne_ssl_cert_free(ne_ssl_certificate *cert) { X509_free(cert->subject); if (cert->issuer) ne_ssl_cert_free(cert->issuer); if (cert->identity) ne_free(cert->identity); ne_free(cert); } int ne_ssl_cert_cmp(const ne_ssl_certificate *c1, const ne_ssl_certificate *c2) { return X509_cmp(c1->subject, c2->subject); } /* The certificate import/export format is the base64 encoding of the * raw DER; PEM without the newlines and wrapping. */ ne_ssl_certificate *ne_ssl_cert_import(const char *data) { unsigned char *der; ne_d2i_uchar *p; size_t len; X509 *x5; /* decode the base64 to get the raw DER representation */ len = ne_unbase64(data, &der); if (len == 0) return NULL; p = der; x5 = d2i_X509(NULL, &p, len); /* p is incremented */ ne_free(der); if (x5 == NULL) { ERR_clear_error(); return NULL; } return populate_cert(ne_calloc(sizeof(struct ne_ssl_certificate_s)), x5); } char *ne_ssl_cert_export(const ne_ssl_certificate *cert) { int len; unsigned char *der, *p; char *ret; /* find the length of the DER encoding. */ len = i2d_X509(cert->subject, NULL); p = der = ne_malloc(len); i2d_X509(cert->subject, &p); /* p is incremented */ ret = ne_base64(der, len); ne_free(der); return ret; } #if SHA_DIGEST_LENGTH != 20 # error SHA digest length is not 20 bytes #endif int ne_ssl_cert_digest(const ne_ssl_certificate *cert, char *digest) { unsigned char sha1[EVP_MAX_MD_SIZE]; unsigned int len, j; char *p; if (!X509_digest(cert->subject, EVP_sha1(), sha1, &len) || len != 20) { ERR_clear_error(); return -1; } for (j = 0, p = digest; j < 20; j++) { *p++ = NE_HEX2ASC((sha1[j] >> 4) & 0x0f); *p++ = NE_HEX2ASC(sha1[j] & 0x0f); *p++ = ':'; } p[-1] = '\0'; return 0; } #ifdef NE_HAVE_TS_SSL /* Implementation of locking callbacks to make OpenSSL thread-safe. * If the OpenSSL API was better designed, this wouldn't be necessary. * In OpenSSL releases without CRYPTO_set_idptr_callback, it's not * possible to implement the locking in a POSIX-compliant way, since * it's necessary to cast from a pthread_t to an unsigned long at some * point. */ static pthread_mutex_t *locks; static size_t num_locks; #ifndef HAVE_CRYPTO_SET_IDPTR_CALLBACK /* Named to be obvious when it shows up in a backtrace. */ static unsigned long thread_id_neon(void) { /* This will break if pthread_t is a structure; upgrading OpenSSL * >= 0.9.9 (which does not require this callback) is the only * solution. */ return (unsigned long) pthread_self(); } #endif /* Another great API design win for OpenSSL: no return value! So if * the lock/unlock fails, all that can be done is to abort. */ static void thread_lock_neon(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { if (pthread_mutex_lock(&locks[n])) { abort(); } } else { if (pthread_mutex_unlock(&locks[n])) { abort(); } } } #endif /* ID_CALLBACK_IS_{NEON,OTHER} evaluate as true if the currently * registered OpenSSL ID callback is the neon function (_NEON), or has * been overwritten by some other app (_OTHER). */ #ifdef HAVE_CRYPTO_SET_IDPTR_CALLBACK #define ID_CALLBACK_IS_OTHER (0) #define ID_CALLBACK_IS_NEON (1) #else #define ID_CALLBACK_IS_OTHER (CRYPTO_get_id_callback() != NULL) #define ID_CALLBACK_IS_NEON (CRYPTO_get_id_callback() == thread_id_neon) #endif int ne__ssl_init(void) { CRYPTO_malloc_init(); SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); #ifdef NE_HAVE_TS_SSL /* If some other library has already come along and set up the * thread-safety callbacks, then it must be presumed that the * other library will have a longer lifetime in the process than * neon. If the library which has installed the callbacks is * unloaded, then all bets are off. */ if (ID_CALLBACK_IS_OTHER || CRYPTO_get_locking_callback() != NULL) { NE_DEBUG(NE_DBG_SOCKET, "ssl: OpenSSL thread-safety callbacks already installed."); NE_DEBUG(NE_DBG_SOCKET, "ssl: neon will not replace existing callbacks."); } else { size_t n; num_locks = CRYPTO_num_locks(); /* For releases where CRYPTO_set_idptr_callback is present, * the default ID callback should be sufficient. */ #ifndef HAVE_CRYPTO_SET_IDPTR_CALLBACK CRYPTO_set_id_callback(thread_id_neon); #endif CRYPTO_set_locking_callback(thread_lock_neon); locks = malloc(num_locks * sizeof *locks); for (n = 0; n < num_locks; n++) { if (pthread_mutex_init(&locks[n], NULL)) { NE_DEBUG(NE_DBG_SOCKET, "ssl: Failed to initialize pthread mutex."); return -1; } } NE_DEBUG(NE_DBG_SOCKET, "ssl: Initialized OpenSSL thread-safety callbacks " "for %" NE_FMT_SIZE_T " locks.\n", num_locks); } #endif return 0; } void ne__ssl_exit(void) { /* Cannot call ERR_free_strings() etc here in case any other code * in the process using OpenSSL. */ #ifdef NE_HAVE_TS_SSL /* Only unregister the callbacks if some *other* library has not * come along in the mean-time and trampled over the callbacks * installed by neon. */ if (CRYPTO_get_locking_callback() == thread_lock_neon && ID_CALLBACK_IS_NEON) { size_t n; #ifndef HAVE_CRYPTO_SET_IDPTR_CALLBACK CRYPTO_set_id_callback(NULL); #endif CRYPTO_set_locking_callback(NULL); for (n = 0; n < num_locks; n++) { pthread_mutex_destroy(&locks[n]); } free(locks); } #endif } davix-R_0_5_0/deps/libneon/src/ne_openssl_internal.h000066400000000000000000000016241257152637300226520ustar00rootroot00000000000000#ifndef DAVIX_OPENSSL_INTERNAL_H #define DAVIX_OPENSSL_INTERNAL_H /// internal openssl declaration #include #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct ne_ssl_dname_s { X509_NAME *dn; }; struct ne_ssl_certificate_s { ne_ssl_dname subj_dn, issuer_dn; X509 *subject; STACK_OF(X509) *chain; ne_ssl_certificate *issuer; char *identity; }; struct ne_ssl_client_cert_s { PKCS12 *p12; int decrypted; /* non-zero if successfully decrypted. */ ne_ssl_certificate cert; EVP_PKEY *pkey; char *friendly_name; }; ne_ssl_certificate *populate_cert(ne_ssl_certificate *cert, X509 *x5); #ifdef __cplusplus } #endif #endif // DAVIX_OPENSSL_INTERNAL_H davix-R_0_5_0/deps/libneon/src/ne_pkcs11.c000066400000000000000000000451101257152637300203660ustar00rootroot00000000000000/* neon PKCS#11 support Copyright (C) 2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include "ne_pkcs11.h" #ifdef HAVE_PAKCHOIS #include #include #include "ne_internal.h" #include "ne_alloc.h" #include "ne_private.h" #include "ne_privssl.h" struct ne_ssl_pkcs11_provider_s { pakchois_module_t *module; ne_ssl_pkcs11_pin_fn pin_fn; void *pin_data; pakchois_session_t *session; ne_ssl_client_cert *clicert; ck_object_handle_t privkey; ck_key_type_t keytype; }; /* To do list for PKCS#11 support: - propagate error strings back to ne_session; use new pakchois_error() for pakchois API 0.2 - add API to specify a particular slot number to use for clicert - add API to specify a particular cert ID for clicert - find a certificate which has an issuer matching the CA dnames given by GnuTLS - make sure subject name matches between pubkey and privkey - check error handling & fail gracefully if the token is ejected mid-session - add API to enumerate/search provided certs and allow direct choice? (or just punt) - the session<->provider interface requires that one clicert is used for all sessions. remove this limitation - add API to import all CA certs as trusted (CKA_CERTIFICATE_CATEGORY seems to be unused unfortunately; just add all X509 certs with CKA_TRUSTED set to true)) - make DSA work */ #ifdef HAVE_OPENSSL #include #include #define PK11_RSA_ERR (RSA_F_RSA_EAY_PRIVATE_ENCRYPT) /* RSA_METHOD ->rsa_sign calback. */ static int pk11_rsa_sign(int type, const unsigned char *m, unsigned int mlen, unsigned char *sigret, unsigned int *siglen, const RSA *r) { ne_ssl_pkcs11_provider *prov = (ne_ssl_pkcs11_provider *)r->meth->app_data; ck_rv_t rv; struct ck_mechanism mech; unsigned long len; if (!prov->session || prov->privkey == CK_INVALID_HANDLE) { NE_DEBUG(NE_DBG_SSL, "pk11: Cannot sign, no session/key."); RSAerr(PK11_RSA_ERR,ERR_R_RSA_LIB); return 0; } mech.mechanism = CKM_RSA_PKCS; mech.parameter = NULL; mech.parameter_len = 0; /* Initialize signing operation; using the private key discovered * earlier. */ rv = pakchois_sign_init(prov->session, &mech, prov->privkey); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: SignInit failed: %lx.", rv); RSAerr(PK11_RSA_ERR, ERR_R_RSA_LIB); return 0; } len = *siglen = RSA_size(r); rv = pakchois_sign(prov->session, (unsigned char *)m, mlen, sigret, &len); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: Sign failed."); RSAerr(PK11_RSA_ERR, ERR_R_RSA_LIB); return 0; } NE_DEBUG(NE_DBG_SSL, "pk11: Signed successfully."); return 1; } /* RSA_METHOD ->rsa_init implementation; called during RSA_new(rsa). */ static int pk11_rsa_init(RSA *rsa) { /* Ensures that RSA_sign() uses meth->rsa_sign: */ rsa->flags |= RSA_FLAG_SIGN_VER; return 1; } /* RSA_METHOD ->rsa_finish implementation; called during * RSA_free(rsa). */ static int pk11_rsa_finish(RSA *rsa) { RSA_METHOD *meth = (RSA_METHOD *)rsa->meth; /* Freeing the dynamically allocated method here works as well as * doing anything else: */ ne_free(meth); /* Does not appear that rsa->meth will be used after this, but in * case it is, ensure a NULL pointer dereference rather than a * random pointer dereference. */ rsa->meth = NULL; return 0; } /* Return an RSA_METHOD which will use the PKCS#11 provider to * implement the signing operation. */ static RSA_METHOD *pk11_rsa_method(ne_ssl_pkcs11_provider *prov) { RSA_METHOD *m = ne_calloc(sizeof *m); m->name = "neon PKCS#11"; m->rsa_sign = pk11_rsa_sign; m->init = pk11_rsa_init; m->finish = pk11_rsa_finish; /* This is hopefully under complete control of the RSA_METHOD, * otherwise there is nowhere to put this. */ m->app_data = (char *)prov; m->flags = RSA_METHOD_FLAG_NO_CHECK; return m; } #endif static int pk11_find_x509(ne_ssl_pkcs11_provider *prov, pakchois_session_t *pks, unsigned char *certid, unsigned long *cid_len) { struct ck_attribute a[3]; ck_object_class_t class; ck_certificate_type_t type; ck_rv_t rv; ck_object_handle_t obj; unsigned long count; int found = 0; /* Find objects with cert class and X.509 cert type. */ class = CKO_CERTIFICATE; type = CKC_X_509; a[0].type = CKA_CLASS; a[0].value = &class; a[0].value_len = sizeof class; a[1].type = CKA_CERTIFICATE_TYPE; a[1].value = &type; a[1].value_len = sizeof type; rv = pakchois_find_objects_init(pks, a, 2); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: FindObjectsInit failed."); return 0; } while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK && count == 1) { unsigned char value[8192], subject[8192]; a[0].type = CKA_VALUE; a[0].value = value; a[0].value_len = sizeof value; a[1].type = CKA_ID; a[1].value = certid; a[1].value_len = *cid_len; a[2].type = CKA_SUBJECT; a[2].value = subject; a[2].value_len = sizeof subject; if (pakchois_get_attribute_value(pks, obj, a, 3) == CKR_OK) { ne_ssl_client_cert *cc; #ifdef HAVE_GNUTLS cc = ne__ssl_clicert_exkey_import(value, a[0].value_len); #else cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, pk11_rsa_method(prov)); #endif if (cc) { NE_DEBUG(NE_DBG_SSL, "pk11: Imported X.509 cert."); prov->clicert = cc; found = 1; *cid_len = a[1].value_len; break; } } else { NE_DEBUG(NE_DBG_SSL, "pk11: Skipped cert, missing attrs."); } } pakchois_find_objects_final(pks); return found; } #ifdef HAVE_OPENSSL /* No DSA support for OpenSSL (yet, anyway). */ #define KEYTYPE_IS_DSA(kt) (0) #else #define KEYTYPE_IS_DSA(kt) (kt == CKK_DSA) #endif static int pk11_find_pkey(ne_ssl_pkcs11_provider *prov, pakchois_session_t *pks, unsigned char *certid, unsigned long cid_len) { struct ck_attribute a[3]; ck_object_class_t class; ck_rv_t rv; ck_object_handle_t obj; unsigned long count; int found = 0; class = CKO_PRIVATE_KEY; /* Find an object with private key class and a certificate ID * which matches the certificate. */ /* FIXME: also match the cert subject. */ a[0].type = CKA_CLASS; a[0].value = &class; a[0].value_len = sizeof class; a[1].type = CKA_ID; a[1].value = certid; a[1].value_len = cid_len; rv = pakchois_find_objects_init(pks, a, 2); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: FindObjectsInit failed."); /* TODO: error propagation */ return 0; } rv = pakchois_find_objects(pks, &obj, 1, &count); if (rv == CKR_OK && count == 1) { NE_DEBUG(NE_DBG_SSL, "pk11: Found private key."); a[0].type = CKA_KEY_TYPE; a[0].value = &prov->keytype; a[0].value_len = sizeof prov->keytype; if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK && (prov->keytype == CKK_RSA || KEYTYPE_IS_DSA(prov->keytype))) { found = 1; prov->privkey = obj; } else { NE_DEBUG(NE_DBG_SSL, "pk11: Could not determine key type."); } } pakchois_find_objects_final(pks); return found; } static int find_client_cert(ne_ssl_pkcs11_provider *prov, pakchois_session_t *pks) { unsigned char certid[8192]; unsigned long cid_len = sizeof certid; /* TODO: match cert subject too. */ return pk11_find_x509(prov, pks, certid, &cid_len) && pk11_find_pkey(prov, pks, certid, cid_len); } #ifdef HAVE_GNUTLS /* Callback invoked by GnuTLS to provide the signature. The signature * operation is handled here by the PKCS#11 provider. */ static int pk11_sign_callback(gnutls_session_t session, void *userdata, gnutls_certificate_type_t cert_type, const gnutls_datum_t *cert, const gnutls_datum_t *hash, gnutls_datum_t *signature) { ne_ssl_pkcs11_provider *prov = userdata; ck_rv_t rv; struct ck_mechanism mech; unsigned long siglen; if (!prov->session || prov->privkey == CK_INVALID_HANDLE) { NE_DEBUG(NE_DBG_SSL, "pk11: Cannot sign, no session/key."); return GNUTLS_E_NO_CERTIFICATE_FOUND; } mech.mechanism = prov->keytype == CKK_DSA ? CKM_DSA : CKM_RSA_PKCS; mech.parameter = NULL; mech.parameter_len = 0; /* Initialize signing operation; using the private key discovered * earlier. */ rv = pakchois_sign_init(prov->session, &mech, prov->privkey); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: SignInit failed: %lx.", rv); return GNUTLS_E_PK_SIGN_FAILED; } /* Work out how long the signature must be: */ rv = pakchois_sign(prov->session, hash->data, hash->size, NULL, &siglen); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: Sign1 failed."); return GNUTLS_E_PK_SIGN_FAILED; } signature->data = gnutls_malloc(siglen); signature->size = siglen; rv = pakchois_sign(prov->session, hash->data, hash->size, signature->data, &siglen); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: Sign2 failed."); return GNUTLS_E_PK_SIGN_FAILED; } NE_DEBUG(NE_DBG_SSL, "pk11: Signed successfully."); return 0; } #endif static void terminate_string(unsigned char *str, size_t len) { unsigned char *ptr = str + len - 1; while ((*ptr == ' ' || *ptr == '\t' || *ptr == '\0') && ptr >= str) ptr--; if (ptr == str - 1) str[0] = '\0'; else if (ptr == str + len - 1) str[len-1] = '\0'; else ptr[1] = '\0'; } static int pk11_login(ne_ssl_pkcs11_provider *prov, ck_slot_id_t slot_id, pakchois_session_t *pks, struct ck_slot_info *sinfo) { struct ck_token_info tinfo; int attempt = 0; ck_rv_t rv; if (pakchois_get_token_info(prov->module, slot_id, &tinfo) != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: GetTokenInfo failed"); /* TODO: propagate error. */ return -1; } if ((tinfo.flags & CKF_LOGIN_REQUIRED) == 0) { NE_DEBUG(NE_DBG_SSL, "pk11: No login required."); return 0; } /* For a token with a "protected" (out-of-band) authentication * path, calling login with a NULL username is all that is * required. */ if (tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) { if (pakchois_login(pks, CKU_USER, NULL, 0) == CKR_OK) { return 0; } else { NE_DEBUG(NE_DBG_SSL, "pk11: Protected login failed."); /* TODO: error propagation. */ return -1; } } /* Otherwise, PIN entry is necessary for login, so fail if there's * no callback. */ if (!prov->pin_fn) { NE_DEBUG(NE_DBG_SSL, "pk11: No pin callback but login required."); /* TODO: propagate error. */ return -1; } terminate_string(sinfo->slot_description, sizeof sinfo->slot_description); do { char pin[NE_SSL_P11PINLEN]; unsigned int flags = 0; /* If login has been attempted once already, check the token * status again, the flags might change. */ if (attempt) { if (pakchois_get_token_info(prov->module, slot_id, &tinfo) != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: GetTokenInfo failed"); /* TODO: propagate error. */ return -1; } } if (tinfo.flags & CKF_USER_PIN_COUNT_LOW) flags |= NE_SSL_P11PIN_COUNT_LOW; if (tinfo.flags & CKF_USER_PIN_FINAL_TRY) flags |= NE_SSL_P11PIN_FINAL_TRY; terminate_string(tinfo.label, sizeof tinfo.label); if (prov->pin_fn(prov->pin_data, attempt++, (char *)sinfo->slot_description, (char *)tinfo.label, flags, pin)) { return -1; } rv = pakchois_login(pks, CKU_USER, (unsigned char *)pin, strlen(pin)); /* Try to scrub the pin off the stack. Clever compilers will * probably optimize this away, oh well. */ memset(pin, 0, sizeof pin); } while (rv == CKR_PIN_INCORRECT); NE_DEBUG(NE_DBG_SSL, "pk11: Login result = %lu", rv); return (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : -1; } static void pk11_provide(void *userdata, ne_session *sess, const ne_ssl_dname *const *dnames, int dncount) { ne_ssl_pkcs11_provider *prov = userdata; ck_slot_id_t *slots; unsigned long scount, n; if (prov->clicert) { NE_DEBUG(NE_DBG_SSL, "pk11: Using existing clicert."); ne_ssl_set_clicert(sess, prov->clicert); return; } if (pakchois_get_slot_list(prov->module, 1, NULL, &scount) != CKR_OK || scount == 0) { NE_DEBUG(NE_DBG_SSL, "pk11: No slots."); /* TODO: propagate error. */ return; } slots = ne_malloc(scount * sizeof *slots); if (pakchois_get_slot_list(prov->module, 1, slots, &scount) != CKR_OK) { ne_free(slots); NE_DEBUG(NE_DBG_SSL, "pk11: Really, no slots?"); /* TODO: propagate error. */ return; } NE_DEBUG(NE_DBG_SSL, "pk11: Found %ld slots.", scount); for (n = 0; n < scount; n++) { pakchois_session_t *pks; ck_rv_t rv; struct ck_slot_info sinfo; if (pakchois_get_slot_info(prov->module, slots[n], &sinfo) != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: GetSlotInfo failed"); continue; } if ((sinfo.flags & CKF_TOKEN_PRESENT) == 0) { NE_DEBUG(NE_DBG_SSL, "pk11: slot empty, ignoring"); continue; } rv = pakchois_open_session(prov->module, slots[n], CKF_SERIAL_SESSION, NULL, NULL, &pks); if (rv != CKR_OK) { NE_DEBUG(NE_DBG_SSL, "pk11: could not open slot, %ld (%ld: %ld)", rv, n, slots[n]); continue; } if (pk11_login(prov, slots[n], pks, &sinfo) == 0) { if (find_client_cert(prov, pks)) { NE_DEBUG(NE_DBG_SSL, "pk11: Setup complete."); prov->session = pks; ne_ssl_set_clicert(sess, prov->clicert); ne_free(slots); return; } } pakchois_close_session(pks); } ne_free(slots); } static int pk11_init(ne_ssl_pkcs11_provider **provider, pakchois_module_t *module) { ne_ssl_pkcs11_provider *prov; prov = *provider = ne_calloc(sizeof *prov); prov->module = module; prov->privkey = CK_INVALID_HANDLE; return NE_PK11_OK; } int ne_ssl_pkcs11_provider_init(ne_ssl_pkcs11_provider **provider, const char *name) { pakchois_module_t *pm; if (pakchois_module_load(&pm, name) == CKR_OK) { return pk11_init(provider, pm); } else { return NE_PK11_FAILED; } } int ne_ssl_pkcs11_nss_provider_init(ne_ssl_pkcs11_provider **provider, const char *name, const char *directory, const char *cert_prefix, const char *key_prefix, const char *secmod_db) { pakchois_module_t *pm; if (pakchois_module_nssload(&pm, name, directory, cert_prefix, key_prefix, secmod_db) == CKR_OK) { return pk11_init(provider, pm); } else { return NE_PK11_FAILED; } } void ne_ssl_pkcs11_provider_pin(ne_ssl_pkcs11_provider *provider, ne_ssl_pkcs11_pin_fn fn, void *userdata) { provider->pin_fn = fn; provider->pin_data = userdata; } void ne_ssl_set_pkcs11_provider(ne_session *sess, ne_ssl_pkcs11_provider *provider) { #ifdef HAVE_GNUTLS sess->ssl_context->sign_func = pk11_sign_callback; sess->ssl_context->sign_data = provider; #endif ne_ssl_provide_clicert(sess, pk11_provide, provider); } void ne_ssl_pkcs11_provider_destroy(ne_ssl_pkcs11_provider *prov) { if (prov->session) { pakchois_close_session(prov->session); } if (prov->clicert) { ne_ssl_clicert_free(prov->clicert); } pakchois_module_destroy(prov->module); ne_free(prov); } #else /* !HAVE_PAKCHOIS */ int ne_ssl_pkcs11_provider_init(ne_ssl_pkcs11_provider **provider, const char *name) { return NE_PK11_NOTIMPL; } int ne_ssl_pkcs11_nss_provider_init(ne_ssl_pkcs11_provider **provider, const char *name, const char *directory, const char *cert_prefix, const char *key_prefix, const char *secmod_db) { return NE_PK11_NOTIMPL; } void ne_ssl_pkcs11_provider_destroy(ne_ssl_pkcs11_provider *provider) { } void ne_ssl_pkcs11_provider_pin(ne_ssl_pkcs11_provider *provider, ne_ssl_pkcs11_pin_fn fn, void *userdata) { } void ne_ssl_set_pkcs11_provider(ne_session *sess, ne_ssl_pkcs11_provider *provider) { } #endif /* HAVE_PAKCHOIS */ davix-R_0_5_0/deps/libneon/src/ne_pkcs11.h000066400000000000000000000113141257152637300203720ustar00rootroot00000000000000/* PKCS#11 support for neon Copyright (C) 2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_PKCS11_H #define NE_PKCS11_H 1 #include "ne_defs.h" #include "ne_session.h" NE_BEGIN_DECLS typedef struct ne_ssl_pkcs11_provider_s ne_ssl_pkcs11_provider; #define NE_PK11_OK (0) #define NE_PK11_NOTIMPL (-1) #define NE_PK11_FAILED (-2) /* Initialize a PKCS#11 provider of given name. Returns NE_OK on * success, NE_PK11_FAILED if the provider could not be * loaded/initialized, and NE_PK11_NOTIMPL if PKCS#11 is not * supported. On success, *provider is set to non-NULL. */ int ne_ssl_pkcs11_provider_init(ne_ssl_pkcs11_provider **provider, const char *name); /* Initialize a NSS softoken pseudo-PKCS#11 provider of given name * (e.g. "softokn3") to supply a client certificate if requested, * using database in given directory name; the other parameters may be * NULL. Returns NE_OK on success, NE_PK11_FAILED if the provider * could not be loaded/initialized, and NE_PK11_NOTIMPL if PKCS#11 is * not supported. On success, *provider is set to non-NULL. */ int ne_ssl_pkcs11_nss_provider_init(ne_ssl_pkcs11_provider **provider, const char *name, const char *directory, const char *cert_prefix, const char *key_prefix, const char *secmod_db); /* Destroy a PKCS#11 provider object. */ void ne_ssl_pkcs11_provider_destroy(ne_ssl_pkcs11_provider *provider); /* Flags passed to PIN entry callback: */ #define NE_SSL_P11PIN_COUNT_LOW (0x01) /* an incorrect PIN has been * entered. */ #define NE_SSL_P11PIN_FINAL_TRY (0x02) /* token will become locked if * entered PIN is incorrect */ /* Size of buffer passed to PIN entry callback: */ #define NE_SSL_P11PINLEN (256) /* Callback for PKCS#11 PIN entry. The callback provides the PIN code * to unlock the token with label 'token_label' in the slot described * by 'slot_descr'. * * The PIN code, as a NUL-terminated ASCII string, should be copied * into the 'pin' buffer (of fixed length NE_SSL_P11PINLEN), and * return 0 to indicate success. Alternatively, the callback may * return -1 to indicate failure and cancel PIN entry (in which case, * the contents of the 'pin' parameter are ignored). * * When a PIN is required, the callback will be invoked repeatedly * (and indefinitely) until either the returned PIN code is correct, * the callback returns failure, or the token refuses login (e.g. when * the token is locked due to too many incorrect PINs!). For the * first such invocation, the 'attempt' counter will have value zero; * it will increase by one for each subsequent attempt. * * The NE_SSL_P11PIN_COUNT_LOW and/or NE_SSL_P11PIN_FINAL_TRY hints * may be set in the 'flags' argument, if these hints are made * available by the token; not all tokens expose these hints. */ typedef int (*ne_ssl_pkcs11_pin_fn)(void *userdata, int attempt, const char *slot_descr, const char *token_label, unsigned int flags, char *pin); /* Set the PIN entry callback for the given provider. This is * necessary for some (but not all) types of token. For tokens which * implement an out-of-band ("protected") authentication path, the PIN * entry callback will not be invoked. */ void ne_ssl_pkcs11_provider_pin(ne_ssl_pkcs11_provider *provider, ne_ssl_pkcs11_pin_fn fn, void *userdata); /* Set up a given PKCS#11 provider to supply an appropriate client * certificate if requested by the server. A provider may be * configured for use in multiple sessions. */ void ne_ssl_set_pkcs11_provider(ne_session *sess, ne_ssl_pkcs11_provider *provider); NE_END_DECLS #endif /* NE_PKCS11_H */ davix-R_0_5_0/deps/libneon/src/ne_private.h000066400000000000000000000114441257152637300207460ustar00rootroot00000000000000/* HTTP Request Handling Copyright (C) 1999-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* THIS IS NOT A PUBLIC INTERFACE. You CANNOT include this header file * from an application. */ #ifndef NE_PRIVATE_H #define NE_PRIVATE_H #include "ne_request.h" #include "ne_socket.h" #include "ne_ssl.h" struct host_info { /* Type of host represented: */ enum proxy_type { PROXY_NONE = 0, PROXY_HTTP, /* an HTTP proxy */ PROXY_SOCKS /* a SOCKS proxy */ } proxy; unsigned int port; /* If hostname is non-NULL, host is identified by this hostname. */ char *hostname, *hostport; /* If address is non-NULL, the result of resolving ->hostname. */ ne_sock_addr *address; /* If current non-NULL, current network address used in ->address. */ const ne_inet_addr *current; /* If override is non-NULL, the host is identified by this network * address. */ const ne_inet_addr *network; struct host_info *next; }; /* Store every registered callback in a generic container, and cast * the function pointer when calling it. */ struct hook { void (*fn)(void); void *userdata; const char *id; /* non-NULL for accessors. */ struct hook *next; }; #define HAVE_HOOK(st,func) (st->hook->hooks->func != NULL) #define HOOK_FUNC(st, func) (*st->hook->hooks->func) /* Session support. */ struct ne_session_s { /* Connection information */ ne_socket *socket; /* non-zero if connection has been established. */ int connected; /* non-zero if connection has persisted beyond one request. */ int persisted; int is_http11; /* >0 if connected server is known to be * HTTP/1.1 compliant. */ char *scheme; /* Server host details. */ struct host_info server; /* Proxy host details, or NULL if not using a proxy. */ struct host_info *proxies; /* Most recently used proxy server. */ struct host_info *prev_proxy; /* Pointer to the active .server or .proxies as appropriate: */ struct host_info *nexthop; /* Local address to which sockets should be bound. */ const ne_inet_addr *local_addr; /* Settings */ int use_ssl; /* whether a secure connection is required */ int in_connect; /* doing a proxy CONNECT */ int any_proxy_http; /* whether any configured proxy is an HTTP proxy */ enum ne_sock_sversion socks_ver; char *socks_user, *socks_password; int flags[NE_SESSFLAG_LAST]; ne_progress progress_cb; void *progress_ud; ne_notify_status notify_cb; void *notify_ud; int rdtimeout, cotimeout; /* read, connect timeouts. */ struct hook *create_req_hooks, *pre_send_hooks, *post_send_hooks, *post_headers_hooks, *destroy_req_hooks, *destroy_sess_hooks, *close_conn_hooks, *private; char *user_agent; /* full User-Agent: header field */ #ifdef NE_HAVE_SSL ne_ssl_client_cert *client_cert; ne_ssl_certificate *server_cert; ne_ssl_context *ssl_context; int ssl_cc_requested; /* set to non-zero if a client cert was * requested during initial handshake, but * none could be provided. */ #endif /* Server cert verification callback: */ ne_ssl_verify_fn ssl_verify_fn; void *ssl_verify_ud; /* Client cert provider callback: */ ne_ssl_provide_fn ssl_provide_fn; void *ssl_provide_ud; ne_session_status_info status; /* Error string */ char error[512]; }; /* Pushes block of 'count' bytes at 'buf'. Returns non-zero on * error. */ typedef int (*ne_push_fn)(void *userdata, const char *buf, size_t count); /* Do the SSL negotiation. */ NE_PRIVATE int ne__negotiate_ssl(ne_session *sess); /* Set the session error appropriate for SSL verification failures. */ NE_PRIVATE void ne__ssl_set_verify_err(ne_session *sess, int failures); /* Return non-zero if hostname from certificate (cn) matches hostname * used for session (hostname); follows RFC2818 logic. */ NE_PRIVATE int ne__ssl_match_hostname(const char *cn, size_t cnlen, const char *hostname); #endif /* HTTP_PRIVATE_H */ davix-R_0_5_0/deps/libneon/src/ne_privssl.h000066400000000000000000000055321257152637300207770ustar00rootroot00000000000000/* SSL interface definitions internal to neon. Copyright (C) 2003-2005, 2008, 2009, Joe Orton Copyright (C) 2004, Aleix Conchillo Flaque This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* THIS IS NOT A PUBLIC INTERFACE. You CANNOT include this header file * from an application. */ #ifndef NE_PRIVSSL_H #define NE_PRIVSSL_H /* This is the private interface between ne_socket, ne_gnutls and * ne_openssl. */ #include "ne_ssl.h" #include "ne_socket.h" #ifdef HAVE_OPENSSL #include struct ne_ssl_context_s { SSL_CTX *ctx; SSL_SESSION *sess; const char *hostname; /* for SNI */ int failures; /* bitmask of exposed failure bits. */ }; typedef SSL *ne_ssl_socket; /* Create a clicert object from cert DER {der, der_len}, using given * RSA_METHOD for the RSA object. */ NE_PRIVATE ne_ssl_client_cert * ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len, const RSA_METHOD *method); #endif /* HAVE_OPENSSL */ #ifdef HAVE_GNUTLS #include struct ne_ssl_context_s { gnutls_certificate_credentials cred; int verify; /* non-zero if client cert verification required */ const char *hostname; /* for SNI */ /* Session cache. */ union ne_ssl_scache { struct { gnutls_datum key, data; } server; #if defined(HAVE_GNUTLS_SESSION_GET_DATA2) gnutls_datum client; #else struct { char *data; size_t len; } client; #endif } cache; #ifdef HAVE_GNUTLS_SIGN_CALLBACK_SET gnutls_sign_func sign_func; void *sign_data; #endif }; typedef gnutls_session ne_ssl_socket; NE_PRIVATE ne_ssl_client_cert * ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len); #endif /* HAVE_GNUTLS */ #ifdef NE_HAVE_SSL NE_PRIVATE ne_ssl_socket ne__sock_sslsock(ne_socket *sock); /* Process-global initialization of the SSL library; returns non-zero * on error. */ NE_PRIVATE int ne__ssl_init(void); /* Process-global de-initialization of the SSL library. */ NE_PRIVATE void ne__ssl_exit(void); #endif #endif /* NE_PRIVSSL_H */ davix-R_0_5_0/deps/libneon/src/ne_props.c000066400000000000000000000446661257152637300204460ustar00rootroot00000000000000/* WebDAV property manipulation Copyright (C) 2000-2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "ne_alloc.h" #include "ne_xml.h" #include "ne_props.h" #include "ne_basic.h" #include "ne_locks.h" #include "ne_internal.h" /* don't store flat props with a value > 10K */ #define MAX_FLATPROP_LEN (102400) struct ne_propfind_handler_s { ne_session *sess; ne_request *request; int has_props; /* whether we've already written some * props to the body. */ ne_buffer *body; ne_207_parser *parser207; ne_xml_parser *parser; /* Creator/destructor callbacks. */ ne_props_create_complex creator; ne_props_destroy_complex destructor; void *cd_userdata; /* Current propset, or NULL if none being processed. */ ne_prop_result_set *current; ne_buffer *value; /* current flat property value */ int depth; /* nesting depth within a flat property */ ne_props_result callback; void *userdata; }; #define ELM_flatprop (NE_207_STATE_TOP - 1) /* We build up the results of one 'response' element in memory. */ struct prop { char *name, *nspace, *value, *lang; /* Store a ne_propname here too, for convienience. pname.name = * name, pname.nspace = nspace, but they are const'ed in pname. */ ne_propname pname; }; #define NSPACE(x) ((x) ? (x) : "") struct propstat { struct prop *props; int numprops; ne_status status; }; /* Results set. */ struct ne_prop_result_set_s { struct propstat *pstats; int numpstats, counter; void *private; ne_uri uri; }; #define MAX_PROP_COUNTER (1024) static int startelm(void *userdata, int state, const char *name, const char *nspace, const char **atts); static int endelm(void *userdata, int state, const char *name, const char *nspace); /* Handle character data; flat property value. */ static int chardata(void *userdata, int state, const char *data, size_t len) { ne_propfind_handler *hdl = userdata; if (state == ELM_flatprop && hdl->value->length < MAX_FLATPROP_LEN) ne_buffer_append(hdl->value, data, len); return 0; } ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler) { return handler->parser; } ne_request *ne_propfind_get_request(ne_propfind_handler *handler) { return handler->request; } static int propfind(ne_propfind_handler *handler, ne_props_result results, void *userdata) { int ret; ne_request *req = handler->request; /* Register the flat property handler to catch any properties * which the user isn't handling as 'complex'. */ ne_xml_push_handler(handler->parser, startelm, chardata, endelm, handler); handler->callback = results; handler->userdata = userdata; ne_set_request_body_buffer(req, handler->body->data, ne_buffer_size(handler->body)); ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); ne_add_response_body_reader(req, ne_accept_207, ne_xml_parse_v, handler->parser); ret = ne_request_dispatch(req); if (ret == NE_OK && ne_get_status(req)->klass != 2) { ret = NE_ERROR; } else if (ne_xml_failed(handler->parser)) { ne_set_error(handler->sess, "%s", ne_xml_get_error(handler->parser)); ret = NE_ERROR; } return ret; } static void set_body(ne_propfind_handler *hdl, const ne_propname *names) { ne_buffer *body = hdl->body; int n; if (!hdl->has_props) { ne_buffer_czappend(body, "\n"); hdl->has_props = 1; } for (n = 0; names[n].name != NULL; n++) { ne_buffer_concat(body, "<", names[n].name, " xmlns=\"", NSPACE(names[n].nspace), "\"/>\n", NULL); } } int ne_propfind_allprop(ne_propfind_handler *handler, ne_props_result results, void *userdata) { ne_buffer_czappend(handler->body, "\n"); return propfind(handler, results, userdata); } int ne_propfind_named(ne_propfind_handler *handler, const ne_propname *props, ne_props_result results, void *userdata) { set_body(handler, props); ne_buffer_czappend(handler->body, "\n"); return propfind(handler, results, userdata); } /* The easy one... PROPPATCH */ int ne_proppatch(ne_session *sess, const char *uri, const ne_proppatch_operation *items) { ne_request *req = ne_request_create(sess, "PROPPATCH", uri); ne_buffer *body = ne_buffer_create(); int n, ret; /* Create the request body */ ne_buffer_czappend(body, "\n" ""); for (n = 0; items[n].name != NULL; n++) { const char *elm = (items[n].type == ne_propset) ? "set" : "remove"; /* value */ ne_buffer_concat(body, "" "<", items[n].name->name, NULL); if (items[n].name->nspace) { ne_buffer_concat(body, " xmlns=\"", items[n].name->nspace, "\"", NULL); } if (items[n].type == ne_propset) { ne_buffer_concat(body, ">", items[n].value, NULL); } else { ne_buffer_append(body, ">", 1); } ne_buffer_concat(body, "name, ">\n", NULL); } ne_buffer_czappend(body, "\n"); ne_set_request_body_buffer(req, body->data, ne_buffer_size(body)); ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, uri, NE_DEPTH_ZERO); #endif ret = ne_simple_request(sess, req); ne_buffer_destroy(body); return ret; } /* Compare two property names. */ static int pnamecmp(const ne_propname *pn1, const ne_propname *pn2) { if (pn1->nspace == NULL && pn2->nspace != NULL) { return 1; } else if (pn1->nspace != NULL && pn2->nspace == NULL) { return -1; } else if (pn1->nspace == NULL) { return strcmp(pn1->name, pn2->name); } else { return (strcmp(pn1->nspace, pn2->nspace) || strcmp(pn1->name, pn2->name)); } } /* Find property in 'set' with name 'pname'. If found, set pstat_ret * to the containing propstat, likewise prop_ret, and returns zero. * If not found, returns non-zero. */ static int findprop(const ne_prop_result_set *set, const ne_propname *pname, struct propstat **pstat_ret, struct prop **prop_ret) { int ps, p; for (ps = 0; ps < set->numpstats; ps++) { for (p = 0; p < set->pstats[ps].numprops; p++) { struct prop *prop = &set->pstats[ps].props[p]; if (pnamecmp(&prop->pname, pname) == 0) { if (pstat_ret != NULL) *pstat_ret = &set->pstats[ps]; if (prop_ret != NULL) *prop_ret = prop; return 0; } } } return -1; } const char *ne_propset_value(const ne_prop_result_set *set, const ne_propname *pname) { struct prop *prop; if (findprop(set, pname, NULL, &prop)) { return NULL; } else { return prop->value; } } const char *ne_propset_lang(const ne_prop_result_set *set, const ne_propname *pname) { struct prop *prop; if (findprop(set, pname, NULL, &prop)) { return NULL; } else { return prop->lang; } } void *ne_propfind_current_private(ne_propfind_handler *handler) { return handler->current ? handler->current->private : NULL; } void *ne_propset_private(const ne_prop_result_set *set) { return set->private; } int ne_propset_iterate(const ne_prop_result_set *set, ne_propset_iterator iterator, void *userdata) { int ps, p; for (ps = 0; ps < set->numpstats; ps++) { for (p = 0; p < set->pstats[ps].numprops; p++) { struct prop *prop = &set->pstats[ps].props[p]; int ret = iterator(userdata, &prop->pname, prop->value, &set->pstats[ps].status); if (ret) return ret; } } return 0; } const ne_status *ne_propset_status(const ne_prop_result_set *set, const ne_propname *pname) { struct propstat *pstat; if (findprop(set, pname, &pstat, NULL)) { /* TODO: it is tempting to return a dummy status object here * rather than NULL, which says "Property result was not given * by server." but I'm not sure if this is best left to the * client. */ return NULL; } else { return &pstat->status; } } static void *start_response(void *userdata, const ne_uri *uri) { ne_prop_result_set *set = ne_calloc(sizeof(*set)); ne_propfind_handler *hdl = userdata; ne_uri_copy(&set->uri, uri); if (hdl->creator) { set->private = hdl->creator(hdl->cd_userdata, &set->uri); } hdl->current = set; return set; } static void *start_propstat(void *userdata, void *response) { ne_prop_result_set *set = response; ne_propfind_handler *hdl = userdata; struct propstat *pstat; int n; if (++hdl->current->counter == MAX_PROP_COUNTER) { ne_xml_set_error(hdl->parser, _("Response exceeds maximum property count")); return NULL; } n = set->numpstats; set->pstats = ne_realloc(set->pstats, sizeof(struct propstat) * (n+1)); set->numpstats = n+1; pstat = &set->pstats[n]; memset(pstat, 0, sizeof(*pstat)); /* And return this as the new pstat. */ return &set->pstats[n]; } static int startelm(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { ne_propfind_handler *hdl = userdata; struct propstat *pstat = ne_207_get_current_propstat(hdl->parser207); struct prop *prop; int n; const char *lang; /* Just handle all children of propstat and their descendants. */ if ((parent != NE_207_STATE_PROP && parent != ELM_flatprop) || pstat == NULL) return NE_XML_DECLINE; if (parent == ELM_flatprop) { /* collecting the flatprop value. */ hdl->depth++; if (hdl->value->used < MAX_FLATPROP_LEN) { const char **a = atts; ne_buffer_concat(hdl->value, "<", nspace, name, NULL); while (a[0] && hdl->value->used < MAX_FLATPROP_LEN) { const char *nsep = strchr(a[0], ':'), *pfx; /* Resolve the attribute namespace prefix, if any. * Ignore a failure to resolve the namespace prefix. */ pfx = nsep ? ne_xml_resolve_nspace(hdl->parser, a[0], nsep - a[0]) : NULL; if (pfx) { ne_buffer_concat(hdl->value, " ", pfx, nsep + 1, "='", a[1], "'", NULL); } else { ne_buffer_concat(hdl->value, " ", a[0], "='", a[1], "'", NULL); } a += 2; } ne_buffer_czappend(hdl->value, ">"); } return ELM_flatprop; } /* Enforce maximum number of properties per resource to prevent a * memory exhaustion attack by a hostile server. */ if (++hdl->current->counter == MAX_PROP_COUNTER) { ne_xml_set_error(hdl->parser, _("Response exceeds maximum property count")); return NE_XML_ABORT; } /* Add a property to this propstat */ n = pstat->numprops; pstat->props = ne_realloc(pstat->props, sizeof(struct prop) * (n + 1)); pstat->numprops = n+1; /* Fill in the new property. */ prop = &pstat->props[n]; prop->pname.name = prop->name = ne_strdup(name); if (nspace[0] == '\0') { prop->pname.nspace = prop->nspace = NULL; } else { prop->pname.nspace = prop->nspace = ne_strdup(nspace); } prop->value = NULL; NE_DEBUG(NE_DBG_XML, "Got property #%d: {%s}%s.", n, NSPACE(prop->nspace), prop->name); /* This is under discussion at time of writing (April '01), and it * looks like we need to retrieve the xml:lang property from any * element here or above. * * Also, I think we might need attribute namespace handling here. */ lang = ne_xml_get_attr(hdl->parser, atts, NULL, "xml:lang"); if (lang != NULL) { prop->lang = ne_strdup(lang); NE_DEBUG(NE_DBG_XML, "Property language is %s", prop->lang); } else { prop->lang = NULL; } hdl->depth = 0; return ELM_flatprop; } static int endelm(void *userdata, int state, const char *nspace, const char *name) { ne_propfind_handler *hdl = userdata; struct propstat *pstat = ne_207_get_current_propstat(hdl->parser207); int n; if (hdl->depth > 0) { /* nested. */ if (hdl->value->used < MAX_FLATPROP_LEN) ne_buffer_concat(hdl->value, "", NULL); hdl->depth--; } else { /* end of the current property value */ n = pstat->numprops - 1; pstat->props[n].value = ne_buffer_finish(hdl->value); hdl->value = ne_buffer_create(); } return 0; } static void end_propstat(void *userdata, void *pstat_v, const ne_status *status, const char *description) { struct propstat *pstat = pstat_v; /* Nothing to do if no status was given. */ if (!status) return; /* If we get a non-2xx response back here, we wipe the value for * each of the properties in this propstat, so the caller knows to * look at the status instead. It's annoying, since for each prop * we will have done an unnecessary strdup("") above, but there is * no easy way round that given the fact that we don't know * whether we've got an error or not till after we get the * property element. * * Interestingly IIS breaks the 2518 DTD and puts the status * element first in the propstat. This is useful since then we * *do* know whether each subsequent empty prop element means, but * we can't rely on that here. */ if (status->klass != 2) { int n; for (n = 0; n < pstat->numprops; n++) { ne_free(pstat->props[n].value); pstat->props[n].value = NULL; } } /* copy the status structure, and dup the reason phrase. */ pstat->status = *status; pstat->status.reason_phrase = ne_strdup(status->reason_phrase); } /* Frees up a results set */ static void free_propset(ne_propfind_handler *handler, ne_prop_result_set *set) { int n; if (handler->destructor && set->private) { handler->destructor(handler->cd_userdata, set->private); } for (n = 0; n < set->numpstats; n++) { int m; struct propstat *p = &set->pstats[n]; for (m = 0; m < p->numprops; m++) { if (p->props[m].nspace) ne_free(p->props[m].nspace); ne_free(p->props[m].name); if (p->props[m].lang) ne_free(p->props[m].lang); if (p->props[m].value) ne_free(p->props[m].value); p->props[m].nspace = p->props[m].lang = p->props[m].value = NULL; } if (p->status.reason_phrase) ne_free(p->status.reason_phrase); if (p->props) ne_free(p->props); } if (set->pstats) ne_free(set->pstats); ne_uri_free(&set->uri); ne_free(set); } static void end_response(void *userdata, void *resource, const ne_status *status, const char *description) { ne_propfind_handler *handler = userdata; ne_prop_result_set *set = resource; /* Pass back the results for this resource. */ if (handler->callback && set->numpstats > 0) handler->callback(handler->userdata, &set->uri, set); /* Clean up the propset tree we've just built. */ free_propset(handler, set); handler->current = NULL; } ne_propfind_handler * ne_propfind_create(ne_session *sess, const char *uri, int depth) { ne_propfind_handler *ret = ne_calloc(sizeof(ne_propfind_handler)); ne_uri base = {0}; ne_fill_server_uri(sess, &base); base.path = ne_strdup(uri); ret->parser = ne_xml_create(); ret->parser207 = ne_207_create(ret->parser, &base, ret); ret->sess = sess; ret->body = ne_buffer_create(); ret->request = ne_request_create(sess, "PROPFIND", uri); ret->value = ne_buffer_create(); ne_add_depth_header(ret->request, depth); ne_207_set_response_handlers(ret->parser207, start_response, end_response); ne_207_set_propstat_handlers(ret->parser207, start_propstat, end_propstat); /* The start of the request body is fixed: */ ne_buffer_czappend(ret->body, "\n" ""); ne_uri_free(&base); return ret; } /* Destroy a propfind handler */ void ne_propfind_destroy(ne_propfind_handler *handler) { ne_buffer_destroy(handler->value); if (handler->current) free_propset(handler, handler->current); ne_207_destroy(handler->parser207); ne_xml_destroy(handler->parser); ne_buffer_destroy(handler->body); ne_request_destroy(handler->request); ne_free(handler); } int ne_simple_propfind(ne_session *sess, const char *href, int depth, const ne_propname *props, ne_props_result results, void *userdata) { ne_propfind_handler *hdl; int ret; hdl = ne_propfind_create(sess, href, depth); if (props != NULL) { ret = ne_propfind_named(hdl, props, results, userdata); } else { ret = ne_propfind_allprop(hdl, results, userdata); } ne_propfind_destroy(hdl); return ret; } int ne_propnames(ne_session *sess, const char *href, int depth, ne_props_result results, void *userdata) { ne_propfind_handler *hdl; int ret; hdl = ne_propfind_create(sess, href, depth); ne_buffer_czappend(hdl->body, ""); ret = propfind(hdl, results, userdata); ne_propfind_destroy(hdl); return ret; } void ne_propfind_set_private(ne_propfind_handler *hdl, ne_props_create_complex creator, ne_props_destroy_complex destructor, void *userdata) { hdl->creator = creator; hdl->destructor = destructor; hdl->cd_userdata = userdata; } davix-R_0_5_0/deps/libneon/src/ne_props.h000066400000000000000000000234251257152637300204410ustar00rootroot00000000000000/* WebDAV Properties manipulation Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_PROPS_H #define NE_PROPS_H #include "ne_request.h" #include "ne_207.h" NE_BEGIN_DECLS /* There are two interfaces for fetching properties. The first is * 'ne_simple_propfind', which is relatively simple, and easy to use, * but only lets you fetch FLAT properties, i.e. properties which are * just a string of bytes. The complex interface is 'ne_propfind_*', * which is complicated, and hard to use, but lets you parse * structured properties, i.e. properties which have XML content. */ /* The 'ne_simple_propfind' interface. *** * * ne_simple_propfind allows you to fetch a set of properties for a * single resource, or a tree of resources. You set the operation * going by passing these arguments: * * - the session which should be used. * - the URI and the depth of the operation (0, 1, infinite) * - the names of the properties which you want to fetch * - a results callback, and the userdata for the callback. * * For each resource found, the results callback is called, passing * you two things along with the userdata you passed in originally: * * - the URI of the resource (const ne_uri *uri) * - the properties results set (const ne_prop_result_set *results) * */ /* The name of a WebDAV property. 'nspace' may be NULL. */ typedef struct { const char *nspace, *name; } ne_propname; typedef struct ne_prop_result_set_s ne_prop_result_set; /* Get the value of a given property. Will return NULL if there was an * error fetching this property on this resource. Call * ne_propset_result to get the response-status if so. */ const char *ne_propset_value(const ne_prop_result_set *set, const ne_propname *propname); /* Returns the status structure for fetching the given property on * this resource. This function will return NULL if the server did not * return the property (which is a server error). */ const ne_status *ne_propset_status(const ne_prop_result_set *set, const ne_propname *propname); /* Returns the private pointer for the given propset. */ void *ne_propset_private(const ne_prop_result_set *set); /* Return language string of property (may be NULL). */ const char *ne_propset_lang(const ne_prop_result_set *set, const ne_propname *pname); /* ne_propset_iterate iterates over a properties result set, * calling the callback for each property in the set. userdata is * passed as the first argument to the callback. value may be NULL, * indicating an error occurred fetching this property: look at * status for the error in that case. * * If the iterator returns non-zero, ne_propset_iterate will return * immediately with that value. */ typedef int (*ne_propset_iterator)(void *userdata, const ne_propname *pname, const char *value, const ne_status *status); /* Iterate over all the properties in 'set', calling 'iterator' * for each, passing 'userdata' as the first argument to callback. * * Returns: * whatever value iterator returns. */ int ne_propset_iterate(const ne_prop_result_set *set, ne_propset_iterator iterator, void *userdata); /* Callback for handling the results of fetching properties for a * single resource (identified by URI 'uri'). The results are stored * in the result set 'results': use ne_propset_* to examine this * object. */ typedef void (*ne_props_result)(void *userdata, const ne_uri *uri, const ne_prop_result_set *results); /* Fetch properties for a resource (if depth == NE_DEPTH_ZERO), * or a tree of resources (if depth == NE_DEPTH_ONE or _INFINITE). * * Names of the properties required must be given in 'props', * or if props is NULL, *all* properties are fetched. * * 'results' is called for each resource in the response, userdata is * passed as the first argument to the callback. It is important to * note that the callback is called as the response is read off the * socket, so don't do anything silly in it (e.g. sleep(100), or call * any functions which use this session). * * Note that if 'depth' is NE_DEPTH_INFINITY, some servers may refuse * the request. * * Returns NE_*. */ int ne_simple_propfind(ne_session *sess, const char *path, int depth, const ne_propname *props, ne_props_result results, void *userdata); /* The properties of a resource can be manipulated using ne_proppatch. * A single proppatch request may include any number of individual * "set" and "remove" operations, and is defined to have * "all-or-nothing" semantics, so either all the operations succeed, * or none do. */ /* A proppatch operation may either set a property to have a new * value, in which case 'type' must be ne_propset, and 'value' must be * non-NULL; or it can remove a property; in which case 'type' must be * ne_propremove, and 'value' is ignored. In both cases, 'name' must * be set to the name of the property to alter. */ enum ne_proppatch_optype { ne_propset, ne_propremove }; typedef struct { const ne_propname *name; enum ne_proppatch_optype type; const char *value; } ne_proppatch_operation; /* Execute a set of property operations 'ops' on 'path'. 'ops' is an * array terminated by an operation with a NULL 'name' field. Returns * NE_*. */ int ne_proppatch(ne_session *sess, const char *path, const ne_proppatch_operation *ops); /* Retrieve property names for the resources at 'path'. 'results' * callback is called for each resource. Use 'ne_propset_iterate' on * the passed results object to retrieve the list of property names. * */ int ne_propnames(ne_session *sess, const char *path, int depth, ne_props_result results, void *userdata); /* The complex, you-do-all-the-work, property fetch interface: */ struct ne_propfind_handler_s; typedef struct ne_propfind_handler_s ne_propfind_handler; /* Retrieve the 'private' pointer for the current propset for the * given handler, as returned by the ne_props_create_complex callback * installed using 'ne_propfind_set_private'. If this callback was * not registered, this function will return NULL. */ void *ne_propfind_current_private(ne_propfind_handler *handler); /* Create a PROPFIND handler, for the given resource or set of * resources. * * Depth must be one of NE_DEPTH_*. */ ne_propfind_handler * ne_propfind_create(ne_session *sess, const char *path, int depth); /* Return the XML parser for the given handler (only need if you want * to handle complex properties). */ ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler); /* This interface reserves the state integer range 'x' where 0 < x * and x < NE_PROPS_STATE_TOP. */ #define NE_PROPS_STATE_TOP (NE_207_STATE_TOP + 100) /* Return the request object for the given handler. You MUST NOT use * ne_set_request_body_* on this request object. (this call is only * needed if for instance, you want to add extra headers to the * PROPFIND request). The result of using the request pointer after * ne_propfind_destroy(handler) has been called is undefined. */ ne_request *ne_propfind_get_request(ne_propfind_handler *handler); /* A "complex property" has a value which is structured XML. To handle * complex properties, you must set up and register an XML handler * which will understand the elements which make up such properties. * The handler must be registered with the parser returned by * 'ne_propfind_get_parser'. * * To store the parsed value of the property, a 'private' structure is * allocated in each propset (i.e. one per resource). When parsing the * property value elements, for each new resource encountered in the * response, the 'creator' callback is called to retrieve a 'private' * structure for this resource. When the private structure is no longer * needed, the 'destructor' callback is called to deallocate any * memory, if necessary. * * Whilst in XML element callbacks you will have registered to handle * complex properties, you can use the 'ne_propfind_current_private' * call to retrieve the pointer to this private structure. * * To retrieve this 'private' structure from the propset in the * results callback, simply call 'ne_propset_private'. * */ typedef void *(*ne_props_create_complex)(void *userdata, const ne_uri *uri); typedef void (*ne_props_destroy_complex)(void *userdata, void *complex); void ne_propfind_set_private(ne_propfind_handler *handler, ne_props_create_complex creator, ne_props_destroy_complex destructor, void *userdata); /* Fetch all properties. * * Returns NE_*. */ int ne_propfind_allprop(ne_propfind_handler *handler, ne_props_result result, void *userdata); /* Fetch all properties with names listed in array 'names', which is * terminated by a property with a NULL name field. For each resource * encountered, the result callback will be invoked, passing in * 'userdata' as the first argument. * * Returns NE_*. */ int ne_propfind_named(ne_propfind_handler *handler, const ne_propname *names, ne_props_result result, void *userdata); /* Destroy a propfind handler after use. */ void ne_propfind_destroy(ne_propfind_handler *handler); NE_END_DECLS #endif /* NE_PROPS_H */ davix-R_0_5_0/deps/libneon/src/ne_redirect.c000066400000000000000000000071351257152637300210720ustar00rootroot00000000000000/* HTTP-redirect support Copyright (C) 1999-2007, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "ne_session.h" #include "ne_request.h" #include "ne_alloc.h" #include "ne_uri.h" #include "ne_redirect.h" #include "ne_internal.h" #include "ne_string.h" #define REDIRECT_ID "http://www.webdav.org/neon/hooks/http-redirect" struct redirect { char *requri; int valid; /* non-zero if .uri contains a redirect */ ne_uri uri; ne_session *sess; }; static void create(ne_request *req, void *session, const char *method, const char *uri) { struct redirect *red = session; if (red->requri) ne_free(red->requri); red->requri = ne_strdup(uri); } #define REDIR(n) ((n) == 301 || (n) == 302 || (n) == 303 || \ (n) == 307) static int post_send(ne_request *req, void *private, const ne_status *status) { struct redirect *red = private; const char *location = ne_get_response_header(req, "Location"); ne_buffer *path = NULL; int ret; /* Don't do anything for non-redirect status or no Location header. */ if (!REDIR(status->code) || location == NULL) return NE_OK; if (strstr(location, "://") == NULL && location[0] != '/') { char *pnt; path = ne_buffer_create(); ne_buffer_zappend(path, red->requri); pnt = strrchr(path->data, '/'); if (pnt && pnt[1] != '\0') { /* Chop off last path segment. */ pnt[1] = '\0'; ne_buffer_altered(path); } ne_buffer_zappend(path, location); location = path->data; } /* free last uri. */ ne_uri_free(&red->uri); /* Parse the Location header */ if (ne_uri_parse(location, &red->uri) || red->uri.path == NULL) { red->valid = 0; ne_set_error(red->sess, _("Could not parse redirect destination URL")); ret = NE_ERROR; } else { /* got a valid redirect. */ red->valid = 1; ret = NE_REDIRECT; if (!red->uri.host) { /* Not an absoluteURI: breaks 2616 but everybody does it. */ ne_fill_server_uri(red->sess, &red->uri); } } if (path) ne_buffer_destroy(path); return ret; } static void free_redirect(void *cookie) { struct redirect *red = cookie; ne_uri_free(&red->uri); if (red->requri) ne_free(red->requri); ne_free(red); } void ne_redirect_register(ne_session *sess) { struct redirect *red = ne_calloc(sizeof *red); red->sess = sess; ne_hook_create_request(sess, create, red); ne_hook_post_send(sess, post_send, red); ne_hook_destroy_session(sess, free_redirect, red); ne_set_session_private(sess, REDIRECT_ID, red); } const ne_uri *ne_redirect_location(ne_session *sess) { struct redirect *red = ne_get_session_private(sess, REDIRECT_ID); if (red && red->valid) return &red->uri; else return NULL; } davix-R_0_5_0/deps/libneon/src/ne_redirect.h000066400000000000000000000027531257152637300211000ustar00rootroot00000000000000/* HTTP-redirect support Copyright (C) 1999-2002, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_REDIRECT_H #define NE_REDIRECT_H #include "ne_request.h" NE_BEGIN_DECLS /* Register redirect handling for the session: if a valid redirect * (30x) response is given for any request in this session, the * request will fail with the NE_REDIRECT code, and the destination of * the redirect can be retrieved using ne_redirect_location(). */ void ne_redirect_register(ne_session *sess); /* Returns location of last redirect for the session. Returns NULL if * no redirect has been encountered for given session, or the last * redirect encountered could not be parsed. */ const ne_uri *ne_redirect_location(ne_session *sess); NE_END_DECLS #endif /* NE_REDIRECT_H */ davix-R_0_5_0/deps/libneon/src/ne_request.c000066400000000000000000001453441257152637300207660ustar00rootroot00000000000000/* HTTP request/response handling Copyright (C) 1999-2010, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* This is the HTTP client request/response implementation. * The goal of this code is to be modular and simple. */ #include "config.h" #include #include #include #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_internal.h" #include "ne_alloc.h" #include "ne_request.h" #include "ne_string.h" /* for ne_buffer */ #include "ne_utils.h" #include "ne_socket.h" #include "ne_uri.h" #include "ne_private.h" #define SOCK_ERR(req, op, msg) do { ssize_t sret = (op); \ if (sret < 0) return aborted(req, msg, sret); } while (0) #define EOL "\r\n" struct body_reader { ne_block_reader handler; ne_accept_response accept_response; unsigned int use; void *userdata; struct body_reader *next; }; struct field { char *name, *value; size_t vlen; struct field *next; }; /* Maximum number of header fields per response: */ #define MAX_HEADER_FIELDS (100) /* Size of hash table; 43 is the smallest prime for which the common * header names hash uniquely using the *33 hash function. */ #define HH_HASHSIZE (43) /* Hash iteration step: *33 known to be a good hash for ASCII, see RSE. */ #define HH_ITERATE(hash, ch) (((hash)*33 + (unsigned char)(ch)) % HH_HASHSIZE) /* pre-calculated hash values for given header names: */ #define HH_HV_CONNECTION (0x14) #define HH_HV_PROXY_CONNECTION (0x1A) #define HH_HV_CONTENT_LENGTH (0x13) #define HH_HV_TRANSFER_ENCODING (0x07) struct ne_request_s { char *method, *uri; /* method and Request-URI */ ne_buffer *headers; /* request headers */ /* Request body. */ ne_provide_body body_cb; void *body_ud; /* Request body source: file or buffer (if not callback). */ union { struct { int fd; ne_off_t offset, length; ne_off_t remain; /* remaining bytes to send. */ } file; struct { /* length bytes @ buffer = whole body. * remain bytes @ pnt = remaining bytes to send */ const char *buffer, *pnt; size_t length, remain; } buf; } body; ne_off_t body_length; /* length of request body */ /* temporary store for response lines. */ char respbuf[NE_BUFSIZ]; /**** Response ***/ /* The transfer encoding types */ struct ne_response { enum { R_TILLEOF = 0, /* read till eof */ R_NO_BODY, /* implicitly no body (HEAD, 204, 304) */ R_CHUNKED, /* using chunked transfer-encoding */ R_CLENGTH /* using given content-length */ } mode; union { /* clen: used if mode == R_CLENGTH; total and bytes * remaining to be read of response body. */ struct { ne_off_t total, remain; } clen; /* chunk: used if mode == R_CHUNKED; total and bytes * remaining to be read of current chunk */ struct { size_t total, remain; } chunk; } body; ne_off_t progress; /* number of bytes read of response */ } resp; struct hook *private; /* response header fields */ struct field *response_headers[HH_HASHSIZE]; unsigned int current_index; /* response_headers cursor for iterator */ /* List of callbacks which are passed response body blocks */ struct body_reader *body_readers; /*** Miscellaneous ***/ unsigned int method_is_head; unsigned int can_persist; struct timespec expiration_time; int flags[NE_REQFLAG_LAST]; ne_session *session; ne_status status; }; static int open_connection(ne_session *sess); /* Returns hash value for header 'name', converting it to lower-case * in-place. */ static inline unsigned int hash_and_lower(char *name) { char *pnt; unsigned int hash = 0; for (pnt = name; *pnt != '\0'; pnt++) { *pnt = ne_tolower(*pnt); hash = HH_ITERATE(hash,*pnt); } return hash; } /* Abort a request due to an non-recoverable HTTP protocol error, * whilst doing 'doing'. 'code', if non-zero, is the socket error * code, NE_SOCK_*, or if zero, is ignored. */ static int aborted(ne_request *req, const char *doing, ssize_t code) { ne_session *sess = req->session; int ret = NE_ERROR; NE_DEBUG(NE_DBG_HTTP, "Aborted request (%" NE_FMT_SSIZE_T "): %s", code, doing); switch(code) { case NE_SOCK_CLOSED: if (sess->nexthop->proxy != PROXY_NONE) { ne_set_error(sess, _("%s: connection was closed by proxy server"), doing); } else { ne_set_error(sess, _("%s: connection was closed by server"), doing); } break; case NE_SOCK_TIMEOUT: ne_set_error(sess, _("%s: connection timed out"), doing); ret = NE_TIMEOUT; break; case NE_SOCK_ERROR: case NE_SOCK_RESET: case NE_SOCK_TRUNC: ne_set_error(sess, "%s: %s", doing, ne_sock_error(sess->socket)); break; case 0: ne_set_error(sess, "%s", doing); break; } ne_close_connection(sess); return ret; } static void notify_status(ne_session *sess, ne_session_status status) { if (sess->notify_cb) { sess->notify_cb(sess->notify_ud, status, &sess->status); } } static void *get_private(const struct hook *hk, const char *id) { for (; hk != NULL; hk = hk->next) if (strcmp(hk->id, id) == 0) return hk->userdata; return NULL; } void *ne_get_request_private(ne_request *req, const char *id) { return get_private(req->private, id); } void *ne_get_session_private(ne_session *sess, const char *id) { return get_private(sess->private, id); } void ne_set_request_private(ne_request *req, const char *id, void *userdata) { struct hook *hk = ne_malloc(sizeof (struct hook)), *pos; if (req->private != NULL) { for (pos = req->private; pos->next != NULL; pos = pos->next) /* nullop */; pos->next = hk; } else { req->private = hk; } hk->id = id; hk->fn = NULL; hk->userdata = userdata; hk->next = NULL; } static ssize_t body_string_send(void *userdata, char *buffer, size_t count) { ne_request *req = userdata; if (count == 0) { req->body.buf.remain = req->body.buf.length; req->body.buf.pnt = req->body.buf.buffer; } else { /* if body_left == 0 we fall through and return 0. */ if (req->body.buf.remain < count) count = req->body.buf.remain; memcpy(buffer, req->body.buf.pnt, count); req->body.buf.pnt += count; req->body.buf.remain -= count; } return count; } static ssize_t body_fd_send(void *userdata, char *buffer, size_t count) { ne_request *req = userdata; if (count) { ssize_t ret; if (req->body.file.remain == 0) return 0; /* Casts here are necessary for LFS platforms for safe and * warning-free assignment/comparison between 32-bit size_t * and 64-bit off64_t: */ if ((ne_off_t)count > req->body.file.remain) count = (size_t)req->body.file.remain; ret = read(req->body.file.fd, buffer, count); if (ret > 0) { req->body.file.remain -= ret; return ret; } else if (ret == 0) { ne_set_error(req->session, _("Premature EOF in request body file")); } else if (ret < 0) { char err[200]; int errnum = errno; ne_set_error(req->session, _("Failed reading request body file: %s"), ne_strerror(errnum, err, sizeof err)); } return -1; } else { ne_off_t newoff; /* rewind for next send. */ newoff = ne_lseek(req->body.file.fd, req->body.file.offset, SEEK_SET); if (newoff == req->body.file.offset) { req->body.file.remain = req->body.file.length; return 0; } else { char err[200], offstr[20]; if (newoff == -1) { /* errno was set */ ne_strerror(errno, err, sizeof err); } else { strcpy(err, _("offset invalid")); } ne_snprintf(offstr, sizeof offstr, "%" FMT_NE_OFF_T, req->body.file.offset); ne_set_error(req->session, _("Could not seek to offset %s" " of request body file: %s"), offstr, err); return -1; } } } /* For accurate persistent connection handling, for any write() or * read() operation for a new request on an already-open connection, * an EOF or RST error MUST be treated as a persistent connection * timeout, and the request retried on a new connection. Once a * read() operation has succeeded, any subsequent error MUST be * treated as fatal. A 'retry' flag is used; retry=1 represents the * first case, retry=0 the latter. */ /* RETRY_RET() crafts a function return value given the 'retry' flag, * the socket error 'code', and the return value 'acode' from the * aborted() function. */ #define RETRY_RET(retry, code, acode) \ ((((code) == NE_SOCK_CLOSED || (code) == NE_SOCK_RESET || \ (code) == NE_SOCK_TRUNC) && retry) ? NE_RETRY : (acode)) /* Sends the request body; returns 0 on success or an NE_* error code. * If retry is non-zero; will return NE_RETRY on persistent connection * timeout. On error, the session error string is set and the * connection is closed. */ static int send_request_body(ne_request *req, int retry) { ne_session *const sess = req->session; char buffer[NE_BUFSIZ_LARGE]; ssize_t bytes; NE_DEBUG(NE_DBG_CORE, "Sending request body:"); req->session->status.sr.progress = 0; req->session->status.sr.total = req->body_length; notify_status(sess, ne_status_sending); /* tell the source to start again from the beginning. */ if (req->body_cb(req->body_ud, NULL, 0) != 0) { ne_close_connection(sess); return NE_ERROR; } while ((bytes = req->body_cb(req->body_ud, buffer, sizeof buffer)) > 0) { int ret = ne_sock_fullwrite(sess->socket, buffer, bytes); if (ret < 0) { int aret = aborted(req, _("Could not send request body"), ret); return RETRY_RET(retry, ret, aret); } NE_DEBUG(NE_DBG_HTTPBODY, "Body block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n", bytes, (int)bytes, buffer); /* invoke progress callback */ req->session->status.sr.progress += bytes; notify_status(sess, ne_status_sending); } if (bytes == 0) { return NE_OK; } else { NE_DEBUG(NE_DBG_HTTP, "Request body provider failed with " "%" NE_FMT_SSIZE_T "\n", bytes); ne_close_connection(sess); return NE_ERROR; } } /* Lob the User-Agent, connection and host headers in to the request * headers */ static void add_fixed_headers(ne_request *req) { ne_session *const sess = req->session; if (sess->user_agent) { ne_buffer_zappend(req->headers, sess->user_agent); } /* If persistent connections are disabled, just send Connection: * close; otherwise, send Connection: Keep-Alive to pre-1.1 origin * servers to try harder to get a persistent connection, except if * using a proxy as per 2068§19.7.1. Always add TE: trailers. */ if (!sess->flags[NE_SESSFLAG_PERSIST]) { ne_buffer_czappend(req->headers, "Connection: TE, close" EOL); } else if (!sess->is_http11 && !sess->any_proxy_http) { ne_buffer_czappend(req->headers, "Keep-Alive: " EOL "Connection: TE, Keep-Alive" EOL); } else if (!req->session->is_http11 && !sess->any_proxy_http) { ne_buffer_czappend(req->headers, "Keep-Alive: " EOL "Proxy-Connection: Keep-Alive" EOL "Connection: TE" EOL); } else { ne_buffer_czappend(req->headers, "Connection: TE" EOL); } ne_buffer_concat(req->headers, "TE: trailers" EOL "Host: ", req->session->server.hostport, EOL, NULL); } int ne_accept_always(void *userdata, ne_request *req, const ne_status *st) { return 1; } int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st) { return (st->klass == 2); } ne_request *ne_request_create(ne_session *sess, const char *method, const char *path) { ne_request *req = ne_calloc(sizeof *req); req->session = sess; req->headers = ne_buffer_create(); /* Presume the method is idempotent by default. */ req->flags[NE_REQFLAG_IDEMPOTENT] = 1; /* Expect-100 default follows the corresponding session flag. */ req->flags[NE_REQFLAG_EXPECT100] = sess->flags[NE_SESSFLAG_EXPECT100]; /* Add in the fixed headers */ add_fixed_headers(req); /* Set the standard stuff */ req->method = ne_strdup(method); req->method_is_head = (strcmp(method, "HEAD") == 0); /* Only use an absoluteURI here when we might be using an HTTP * proxy, and SSL is in use: some servers can't parse them. */ if (sess->any_proxy_http && !req->session->use_ssl && path[0] == '/') req->uri = ne_concat(req->session->scheme, "://", req->session->server.hostport, path, NULL); else req->uri = ne_strdup(path); { struct hook *hk; for (hk = sess->create_req_hooks; hk != NULL; hk = hk->next) { ne_create_request_fn fn = (ne_create_request_fn)hk->fn; fn(req, hk->userdata, req->method, req->uri); } } req->expiration_time.tv_sec = 0; req->expiration_time.tv_nsec= 0; return req; } /* Set the request body length to 'length' */ static void set_body_length(ne_request *req, ne_off_t length) { req->body_length = length; ne_print_request_header(req, "Content-Length", "%" FMT_NE_OFF_T, length); } void ne_set_request_body_buffer(ne_request *req, const char *buffer, size_t size) { req->body.buf.buffer = buffer; req->body.buf.length = size; req->body_cb = body_string_send; req->body_ud = req; set_body_length(req, size); } void ne_set_request_body_provider(ne_request *req, ne_off_t bodysize, ne_provide_body provider, void *ud) { req->body_cb = provider; req->body_ud = ud; set_body_length(req, bodysize); } void ne_set_request_body_fd(ne_request *req, int fd, ne_off_t offset, ne_off_t length) { req->body.file.fd = fd; req->body.file.offset = offset; req->body.file.length = length; req->body_cb = body_fd_send; req->body_ud = req; set_body_length(req, length); } void ne_set_request_flag(ne_request *req, ne_request_flag flag, int value) { if (flag < NE_SESSFLAG_LAST) { req->flags[flag] = value; } } int ne_get_request_flag(ne_request *req, ne_request_flag flag) { if (flag < NE_REQFLAG_LAST) { return req->flags[flag]; } return -1; } void ne_add_request_header(ne_request *req, const char *name, const char *value) { ne_buffer_concat(req->headers, name, ": ", value, EOL, NULL); } void ne_print_request_header(ne_request *req, const char *name, const char *format, ...) { va_list params; char buf[NE_BUFSIZ]; va_start(params, format); ne_vsnprintf(buf, sizeof buf, format, params); va_end(params); ne_buffer_concat(req->headers, name, ": ", buf, EOL, NULL); } /* Returns the value of the response header 'name', for which the hash * value is 'h', or NULL if the header is not found. */ static inline char *get_response_header_hv(ne_request *req, unsigned int h, const char *name) { struct field *f; for (f = req->response_headers[h]; f; f = f->next) if (strcmp(f->name, name) == 0) return f->value; return NULL; } const char *ne_get_response_header(ne_request *req, const char *name) { char *lcname = ne_strdup(name); unsigned int hash = hash_and_lower(lcname); char *value = get_response_header_hv(req, hash, lcname); ne_free(lcname); return value; } /* The return value of the iterator function is a pointer to the * struct field of the previously returned header. */ void *ne_response_header_iterate(ne_request *req, void *iterator, const char **name, const char **value) { struct field *f = iterator; unsigned int n; if (f == NULL) { n = 0; } else if ((f = f->next) == NULL) { n = req->current_index + 1; } if (f == NULL) { while (n < HH_HASHSIZE && req->response_headers[n] == NULL) n++; if (n == HH_HASHSIZE) return NULL; /* no more headers */ f = req->response_headers[n]; req->current_index = n; } *name = f->name; *value = f->value; return f; } /* Removes the response header 'name', which has hash value 'hash'. */ static void remove_response_header(ne_request *req, const char *name, unsigned int hash) { struct field **ptr = req->response_headers + hash; while (*ptr) { struct field *const f = *ptr; if (strcmp(f->name, name) == 0) { *ptr = f->next; ne_free(f->name); ne_free(f->value); ne_free(f); return; } ptr = &f->next; } } /* Free all stored response headers. */ static void free_response_headers(ne_request *req) { int n; for (n = 0; n < HH_HASHSIZE; n++) { struct field **ptr = req->response_headers + n; while (*ptr) { struct field *const f = *ptr; *ptr = f->next; ne_free(f->name); ne_free(f->value); ne_free(f); } } } void ne_add_response_body_reader(ne_request *req, ne_accept_response acpt, ne_block_reader rdr, void *userdata) { struct body_reader *new = ne_malloc(sizeof *new); new->accept_response = acpt; new->handler = rdr; new->userdata = userdata; new->next = req->body_readers; req->body_readers = new; } void ne_request_destroy(ne_request *req) { struct body_reader *rdr, *next_rdr; struct hook *hk, *next_hk; ne_free(req->uri); ne_free(req->method); for (rdr = req->body_readers; rdr != NULL; rdr = next_rdr) { next_rdr = rdr->next; ne_free(rdr); } free_response_headers(req); ne_buffer_destroy(req->headers); NE_DEBUG(NE_DBG_CORE, "Running destroy hooks."); for (hk = req->session->destroy_req_hooks; hk; hk = next_hk) { ne_destroy_req_fn fn = (ne_destroy_req_fn)hk->fn; next_hk = hk->next; fn(req, hk->userdata); } for (hk = req->private; hk; hk = next_hk) { next_hk = hk->next; ne_free(hk); } if (req->status.reason_phrase) ne_free(req->status.reason_phrase); NE_DEBUG(NE_DBG_CORE, "Request ends."); ne_free(req); } /* Reads a block of the response into BUFFER, which is of size * *BUFLEN. Returns zero on success or non-zero on error. On * success, *BUFLEN is updated to be the number of bytes read into * BUFFER (which will be 0 to indicate the end of the repsonse). On * error, the connection is closed and the session error string is * set. */ static int read_response_block(ne_request *req, struct ne_response *resp, char *buffer, size_t *buflen) { ne_socket *const sock = req->session->socket; size_t willread; ssize_t readlen; switch (resp->mode) { case R_CHUNKED: /* Chunked transfer-encoding: chunk syntax is "SIZE CRLF CHUNK * CRLF SIZE CRLF CHUNK CRLF ..." followed by zero-length * chunk: "CHUNK CRLF 0 CRLF". resp.chunk.remain contains the * number of bytes left to read in the current chunk. */ if (resp->body.chunk.remain == 0) { unsigned long chunk_len; char *ptr; /* Read the chunk size line into a temporary buffer. */ SOCK_ERR(req, ne_sock_readline(sock, req->respbuf, sizeof req->respbuf), _("Could not read chunk size")); NE_DEBUG(NE_DBG_HTTP, "[chunk] < %s", req->respbuf); chunk_len = strtoul(req->respbuf, &ptr, 16); /* limit chunk size to <= UINT_MAX, so it will probably * fit in a size_t. */ if (ptr == req->respbuf || chunk_len == ULONG_MAX || chunk_len > UINT_MAX) { return aborted(req, _("Could not parse chunk size"), 0); } NE_DEBUG(NE_DBG_HTTP, "Got chunk size: %lu", chunk_len); resp->body.chunk.remain = chunk_len; } willread = resp->body.chunk.remain > *buflen ? *buflen : resp->body.chunk.remain; break; case R_CLENGTH: willread = resp->body.clen.remain > (off_t)*buflen ? *buflen : (size_t)resp->body.clen.remain; break; case R_TILLEOF: willread = *buflen; break; case R_NO_BODY: default: willread = 0; break; } if (willread == 0) { *buflen = 0; return 0; } NE_DEBUG(NE_DBG_CORE, "Reading %" NE_FMT_SIZE_T " bytes of response body.\n", willread); readlen = ne_sock_read(sock, buffer, willread); /* EOF is only valid when response body is delimited by it. * Strictly, an SSL truncation should not be treated as an EOF in * any case, but SSL servers are just too buggy. */ if (resp->mode == R_TILLEOF && (readlen == NE_SOCK_CLOSED || readlen == NE_SOCK_TRUNC)) { NE_DEBUG(NE_DBG_HTTP, "Got EOF."); req->can_persist = 0; readlen = 0; } else if (readlen < 0) { return aborted(req, _("Could not read response body"), readlen); } else { NE_DEBUG(NE_DBG_CORE, "Got %" NE_FMT_SSIZE_T " bytes.", readlen); } /* safe to cast: readlen guaranteed to be >= 0 above */ *buflen = (size_t)readlen; NE_DEBUG(NE_DBG_HTTPBODY, "Read block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n", readlen, (int)readlen, buffer); if (resp->mode == R_CHUNKED) { resp->body.chunk.remain -= readlen; if (resp->body.chunk.remain == 0) { char crlfbuf[2]; /* If we've read a whole chunk, read a CRLF */ readlen = ne_sock_fullread(sock, crlfbuf, 2); if (readlen < 0) return aborted(req, _("Could not read chunk delimiter"), readlen); else if (crlfbuf[0] != '\r' || crlfbuf[1] != '\n') return aborted(req, _("Chunk delimiter was invalid"), 0); } } else if (resp->mode == R_CLENGTH) { resp->body.clen.remain -= readlen; } resp->progress += readlen; return NE_OK; } ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen) { struct body_reader *rdr; size_t readlen = buflen; struct ne_response *const resp = &req->resp; if (read_response_block(req, resp, buffer, &readlen)) return -1; if (readlen) { req->session->status.sr.progress += readlen; notify_status(req->session, ne_status_recving); } for (rdr = req->body_readers; rdr!=NULL; rdr=rdr->next) { if (rdr->use && rdr->handler(rdr->userdata, buffer, readlen) != 0) { ne_close_connection(req->session); return -1; } } return readlen; } /* Build the request string, returning the buffer. */ static ne_buffer *build_request(ne_request *req) { struct hook *hk; ne_buffer *buf = ne_buffer_create(); /* Add Request-Line and headers: */ ne_buffer_concat(buf, req->method, " ", req->uri, " HTTP/1.1" EOL, NULL); /* Add custom headers: */ ne_buffer_append(buf, req->headers->data, ne_buffer_size(req->headers)); if (req->body_length && req->flags[NE_REQFLAG_EXPECT100]) { ne_buffer_czappend(buf, "Expect: 100-continue\r\n"); } NE_DEBUG(NE_DBG_CORE, "Running pre_send hooks"); for (hk = req->session->pre_send_hooks; hk!=NULL; hk = hk->next) { ne_pre_send_fn fn = (ne_pre_send_fn)hk->fn; fn(req, hk->userdata, buf); } ne_buffer_czappend(buf, "\r\n"); return buf; } #define MAX_HEADER_LEN (8192) #ifdef NE_DEBUGGING #define DEBUG_DUMP_REQUEST(x) dump_request(x) static void dump_request(const char *request) { char hdr_tmp[MAX_HEADER_LEN]; char hdr_debug[MAX_HEADER_LEN]; memset(hdr_tmp, '\0', sizeof(hdr_tmp)); memset(hdr_debug, '\0', sizeof(hdr_debug)); strcat(hdr_tmp, "> "); strcat(hdr_tmp, request); char* token = strtok(hdr_tmp, "\n"); while (token) { strcat(hdr_debug, token); strcat(hdr_debug, "\n> "); token = strtok(NULL, "\n"); } hdr_debug[strlen(hdr_debug)-2] = '\0'; if (davix_get_log_scope() & NE_DBG_HTTPPLAIN) { /* Display everything mode */ NE_DEBUG(NE_DBG_HTTP, "%s", hdr_debug); } else if (davix_get_log_scope() & NE_DBG_HTTP) { /* Blank out the Authorization paramaters */ char *reqdebug = ne_strdup(hdr_debug), *pnt = reqdebug; while ((pnt = strstr(pnt, "Authorization: ")) != NULL) { for (pnt += 15; *pnt != '\r' && *pnt != '\0'; pnt++) { *pnt = 'x'; } } NE_DEBUG(NE_DBG_HTTP, "%s",reqdebug); ne_free(reqdebug); } } #else #define DEBUG_DUMP_REQUEST(x) #endif /* DEBUGGING */ /* remove trailing EOL from 'buf', where strlen(buf) == *len. *len is * adjusted in accordance with any changes made to the string to * remain equal to strlen(buf). */ static inline void strip_eol(char *buf, ssize_t *len) { char *pnt = buf + *len - 1; while (pnt >= buf && (*pnt == '\r' || *pnt == '\n')) { *pnt-- = '\0'; (*len)--; } } /* Read and parse response status-line into 'status'. 'retry' is non-zero * if an NE_RETRY should be returned if an EOF is received. */ static int read_status_line(ne_request *req, ne_status *status, int retry) { char *buffer = req->respbuf; ssize_t ret; ret = ne_sock_readline(req->session->socket, buffer, sizeof req->respbuf); if (ret <= 0) { int aret = aborted(req, _("Could not read status line"), ret); return RETRY_RET(retry, ret, aret); } strip_eol(buffer, &ret); NE_DEBUG(NE_DBG_HTTP, "< %s", buffer); if (status->reason_phrase) ne_free(status->reason_phrase); memset(status, 0, sizeof *status); /* Hack to allow ShoutCast-style servers, if requested. */ if (req->session->flags[NE_SESSFLAG_ICYPROTO] && strncmp(buffer, "ICY ", 4) == 0 && strlen(buffer) > 8 && buffer[7] == ' ') { status->code = atoi(buffer + 4); status->major_version = 1; status->minor_version = 0; status->reason_phrase = ne_strclean(ne_strdup(buffer + 8)); status->klass = buffer[4] - '0'; NE_DEBUG(NE_DBG_HTTP, "[status-line] ICY protocol; code %d", status->code); } else if (ne_parse_statusline(buffer, status)) { return aborted(req, _("Could not parse response status line"), 0); } return 0; } /* Discard a set of message headers. */ static int discard_headers(ne_request *req) { do { SOCK_ERR(req, ne_sock_readline(req->session->socket, req->respbuf, sizeof req->respbuf), _("Could not read interim response headers")); NE_DEBUG(NE_DBG_HTTP, "[discard] < %s", req->respbuf); } while (strcmp(req->respbuf, EOL) != 0); return NE_OK; } /* Send the request, and read the response Status-Line. Returns: * NE_RETRY connection closed by server; persistent connection * timeout * NE_OK success * NE_* error * On NE_RETRY and NE_* responses, the connection will have been * closed already. */ static int send_request(ne_request *req, const ne_buffer *request) { ne_session *const sess = req->session; ne_status *const status = &req->status; int sentbody = 0; /* zero until body has been sent. */ int ret, retry; /* retry non-zero whilst the request should be retried */ ssize_t sret; /* Send the Request-Line and headers */ NE_DEBUG(NE_DBG_CORE, "Sending request-line and headers:"); /* Open the connection if necessary */ ret = open_connection(sess); if (ret) return ret; /* Allow retry if a persistent connection has been used. */ retry = sess->persisted; sret = ne_sock_fullwrite(req->session->socket, request->data, ne_buffer_size(request)); if (sret < 0) { int aret = aborted(req, _("Could not send request"), sret); return RETRY_RET(retry, sret, aret); } if (!req->flags[NE_REQFLAG_EXPECT100] && req->body_length > 0) { /* Send request body, if not using 100-continue. */ ret = send_request_body(req, retry); if (ret) { return ret; } } NE_DEBUG(NE_DBG_CORE, "Request sent; retry is %d.", retry); /* Loop eating interim 1xx responses (RFC2616 says these MAY be * sent by the server, even if 100-continue is not used). */ while ((ret = read_status_line(req, status, retry)) == NE_OK && status->klass == 1) { NE_DEBUG(NE_DBG_HTTP, "Interim %d response.", status->code); retry = 0; /* successful read() => never retry now. */ /* Discard headers with the interim response. */ if ((ret = discard_headers(req)) != NE_OK) break; if (req->flags[NE_REQFLAG_EXPECT100] && (status->code == 100) && req->body_length > 0 && !sentbody) { /* Send the body after receiving the first 100 Continue */ if ((ret = send_request_body(req, 0)) != NE_OK) break; sentbody = 1; } } return ret; } /* Read a message header from sock into buf, which has size 'buflen'. * * Returns: * NE_RETRY: Success, read a header into buf. * NE_OK: End of headers reached. * NE_ERROR: Error (session error is set, connection closed). */ static int read_message_header(ne_request *req, char *buf, size_t buflen) { ssize_t n; ne_socket *sock = req->session->socket; n = ne_sock_readline(sock, buf, buflen); if (n <= 0) return aborted(req, _("Error reading response headers"), n); strip_eol(buf, &n); NE_DEBUG(NE_DBG_HTTP, "< %s", buf); if (n == 0) { NE_DEBUG(NE_DBG_CORE, "End of headers."); return NE_OK; } buf += n; buflen -= n; while (buflen > 0) { char ch; /* Collect any extra lines into buffer */ SOCK_ERR(req, ne_sock_peek(sock, &ch, 1), _("Error reading response headers")); if (ch != ' ' && ch != '\t') { /* No continuation of this header: stop reading. */ return NE_RETRY; } /* Otherwise, read the next line onto the end of 'buf'. */ n = ne_sock_readline(sock, buf, buflen); if (n <= 0) { return aborted(req, _("Error reading response headers"), n); } NE_DEBUG(NE_DBG_HTTP, "[cont] %s", buf); strip_eol(buf, &n); /* assert(buf[0] == ch), which implies len(buf) > 0. * Otherwise the TCP stack is lying, but we'll be paranoid. * This might be a \t, so replace it with a space to be * friendly to applications (2616 says we MAY do this). */ if (n) buf[0] = ' '; /* ready for the next header. */ buf += n; buflen -= n; } ne_set_error(req->session, _("Response header too long")); return NE_ERROR; } /* Add a respnose header field for the given request, using * precalculated hash value. */ static void add_response_header(ne_request *req, unsigned int hash, char *name, char *value) { struct field **nextf = &req->response_headers[hash]; size_t vlen = strlen(value); while (*nextf) { struct field *const f = *nextf; if (strcmp(f->name, name) == 0) { if (vlen + f->vlen < MAX_HEADER_LEN) { /* merge the header field */ f->value = ne_realloc(f->value, f->vlen + vlen + 3); memcpy(f->value + f->vlen, ", ", 2); memcpy(f->value + f->vlen + 2, value, vlen + 1); f->vlen += vlen + 2; } return; } nextf = &f->next; } (*nextf) = ne_malloc(sizeof **nextf); (*nextf)->name = ne_strdup(name); (*nextf)->value = ne_strdup(value); (*nextf)->vlen = vlen; (*nextf)->next = NULL; } /* Read response headers. Returns NE_* code, sets session error and * closes connection on error. */ static int read_response_headers(ne_request *req) { char hdr[MAX_HEADER_LEN]; int ret, count = 0; while ((ret = read_message_header(req, hdr, sizeof hdr)) == NE_RETRY && ++count < MAX_HEADER_FIELDS) { char *pnt; unsigned int hash = 0; /* Strip any trailing whitespace */ pnt = hdr + strlen(hdr) - 1; while (pnt > hdr && (*pnt == ' ' || *pnt == '\t')) *pnt-- = '\0'; /* Convert the header name to lower case and hash it. */ for (pnt = hdr; (*pnt != '\0' && *pnt != ':' && *pnt != ' ' && *pnt != '\t'); pnt++) { *pnt = ne_tolower(*pnt); hash = HH_ITERATE(hash,*pnt); } /* Skip over any whitespace before the colon. */ while (*pnt == ' ' || *pnt == '\t') *pnt++ = '\0'; /* ignore header lines which lack a ':'. */ if (*pnt != ':') continue; /* NUL-terminate at the colon (when no whitespace before) */ *pnt++ = '\0'; /* Skip any whitespace after the colon... */ while (*pnt == ' ' || *pnt == '\t') pnt++; /* pnt now points to the header value. */ //NE_DEBUG(NE_DBG_HTTP, "Header Name: [%s], Value: [%s]", hdr, pnt); add_response_header(req, hash, hdr, pnt); } if (count == MAX_HEADER_FIELDS) ret = aborted( req, _("Response exceeded maximum number of header fields"), 0); return ret; } /* Perform any necessary DNS lookup for the host given by *info; * returns NE_ code with error string set on error. */ static int lookup_host(ne_session *sess, struct host_info *info) { NE_DEBUG(NE_DBG_CORE, "Doing DNS lookup on %s...", info->hostname); sess->status.lu.hostname = info->hostname; notify_status(sess, ne_status_lookup); info->address = ne_addr_resolve(info->hostname, 0); if (ne_addr_result(info->address)) { char buf[256]; ne_set_error(sess, _("Could not resolve hostname `%s': %s"), info->hostname, ne_addr_error(info->address, buf, sizeof buf)); ne_addr_destroy(info->address); info->address = NULL; return NE_LOOKUP; } else { return NE_OK; } } int ne_begin_request(ne_request *req) { struct body_reader *rdr; ne_buffer *data; const ne_status *const st = &req->status; const char *value; struct hook *hk; int ret, forced_closure = 0; /* If a non-idempotent request is sent on a persisted connection, * then it is impossible to distinguish between a server failure * and a connection timeout if an EOF/RST is received. So don't * do that. */ /* if (!req->flags[NE_REQFLAG_IDEMPOTENT] && req->session->persisted && !req->session->flags[NE_SESSFLAG_CONNAUTH]) { NE_DEBUG(NE_DBG_HTTP, "req: Closing connection for non-idempotent " "request.\n"); ne_close_connection(req->session); } */ /* Build the request string, and send it */ data = build_request(req); if(davix_get_log_scope() & NE_DBG_HTTP){ dump_request(data->data); } ret = send_request(req, data); /* Retry this once after a persistent connection timeout. */ if (ret == NE_RETRY) { NE_DEBUG(NE_DBG_HTTP, "Persistent connection timed out, retrying."); ret = send_request(req, data); } ne_buffer_destroy(data); if (ret != NE_OK) return ret == NE_RETRY ? NE_ERROR : ret; /* Determine whether server claims HTTP/1.1 compliance. */ req->session->is_http11 = (st->major_version == 1 && st->minor_version > 0) || st->major_version > 1; /* Persistent connections supported implicitly in HTTP/1.1 */ if (req->session->is_http11) req->can_persist = 1; ne_set_error(req->session, "%d %s", st->code, st->reason_phrase); /* Empty the response header hash, in case this request was * retried: */ free_response_headers(req); /* Read the headers */ ret = read_response_headers(req); if (ret) return ret; /* check the Connection header */ value = get_response_header_hv(req, HH_HV_CONNECTION, "connection"); if (value) { char *vcopy = ne_strdup(value), *ptr = vcopy; do { char *token = ne_shave(ne_token(&ptr, ','), " \t"); unsigned int hash = hash_and_lower(token); if (strcmp(token, "close") == 0) { req->can_persist = 0; forced_closure = 1; } else if (strcmp(token, "keep-alive") == 0) { req->can_persist = 1; } else if (!req->session->is_http11 && strcmp(token, "connection")) { /* Strip the header per 2616§14.10, last para. Avoid * danger from "Connection: connection". */ remove_response_header(req, token, hash); } } while (ptr); ne_free(vcopy); } /* Support "Proxy-Connection: keep-alive" for compatibility with * some HTTP/1.0 proxies; it is risky to do this, because an * intermediary proxy may not support this HTTP/1.0 extension, but * will not strip the header either. Persistent connection * support is enabled based on the presence of this header if: * a) it is *necessary* to do so due to the use of a connection-auth * scheme, and * b) connection closure was not forced via "Connection: close". */ if (req->session->nexthop->proxy == PROXY_HTTP && !req->session->is_http11 && !forced_closure && req->session->flags[NE_SESSFLAG_CONNAUTH]) { value = get_response_header_hv(req, HH_HV_PROXY_CONNECTION, "proxy-connection"); if (value && ne_strcasecmp(value, "keep-alive") == 0) { NE_DEBUG(NE_DBG_HTTP, "req: Using persistent connection " "for HTTP/1.0 proxy requiring conn-auth hack.\n"); req->can_persist = 1; } } /* Decide which method determines the response message-length per * 2616§4.4 (multipart/byteranges is not supported): */ #ifdef NE_HAVE_SSL /* Special case for CONNECT handling: the response has no body, * and the connection can persist. */ if (req->session->in_connect && st->klass == 2) { req->resp.mode = R_NO_BODY; req->can_persist = 1; } else #endif /* HEAD requests and 204, 304 responses have no response body, * regardless of what headers are present. */ if (req->method_is_head || st->code == 204 || st->code == 304) { req->resp.mode = R_NO_BODY; } /* Broken intermediaries exist which use "transfer-encoding: identity" * to mean "no transfer-coding". So that case must be ignored. */ else if ((value = get_response_header_hv(req, HH_HV_TRANSFER_ENCODING, "transfer-encoding")) != NULL && ne_strcasecmp(value, "identity") != 0) { /* Otherwise, fail iff an unknown transfer-coding is used. */ if (ne_strcasecmp(value, "chunked") == 0) { req->resp.mode = R_CHUNKED; req->resp.body.chunk.remain = 0; } else { return aborted(req, _("Unknown transfer-coding in response"), 0); } } else if ((value = get_response_header_hv(req, HH_HV_CONTENT_LENGTH, "content-length")) != NULL) { char *endptr = NULL; ne_off_t len = ne_strtoff(value, &endptr, 10); if (*value && len != NE_OFFT_MAX && len >= 0 && endptr && *endptr == '\0') { req->resp.mode = R_CLENGTH; req->resp.body.clen.total = req->resp.body.clen.remain = len; } else { /* fail for an invalid content-length header. */ return aborted(req, _("Invalid Content-Length in response"), 0); } } else { req->resp.mode = R_TILLEOF; /* otherwise: read-till-eof mode */ } NE_DEBUG(NE_DBG_CORE, "Running post_headers hooks"); for (hk = req->session->post_headers_hooks; hk != NULL; hk = hk->next) { ne_post_headers_fn fn = (ne_post_headers_fn)hk->fn; fn(req, hk->userdata, &req->status); } /* Prepare for reading the response entity-body. Call each of the * body readers and ask them whether they want to accept this * response or not. */ for (rdr = req->body_readers; rdr != NULL; rdr=rdr->next) { rdr->use = rdr->accept_response(rdr->userdata, req, st); } req->session->status.sr.progress = 0; req->session->status.sr.total = req->resp.mode == R_CLENGTH ? req->resp.body.clen.total : -1; notify_status(req->session, ne_status_recving); return NE_OK; } int ne_end_request(ne_request *req) { struct hook *hk; int ret; /* Read headers in chunked trailers */ if (req->resp.mode == R_CHUNKED) { ret = read_response_headers(req); if (ret) return ret; } else { ret = NE_OK; } NE_DEBUG(NE_DBG_CORE, "Running post_send hooks"); for (hk = req->session->post_send_hooks; ret == NE_OK && hk != NULL; hk = hk->next) { ne_post_send_fn fn = (ne_post_send_fn)hk->fn; ret = fn(req, hk->userdata, &req->status); } /* Close the connection if persistent connections are disabled or * not supported by the server. */ if (!req->session->flags[NE_SESSFLAG_PERSIST] || !req->can_persist) ne_close_connection(req->session); else req->session->persisted = 1; return ret; } int ne_abort_request(ne_request* req){ if(req->session) ne_close_connection(req->session); return 0; } int ne_read_response_to_fd(ne_request *req, int fd) { ssize_t len; while ((len = ne_read_response_block(req, req->respbuf, sizeof req->respbuf)) > 0) { const char *block = req->respbuf; do { ssize_t ret = write(fd, block, len); if (ret == -1 && errno == EINTR) { continue; } else if (ret < 0) { char err[200]; ne_strerror(errno, err, sizeof err); ne_set_error(ne_get_session(req), _("Could not write to file: %s"), err); return NE_ERROR; } else { len -= ret; block += ret; } } while (len > 0); } return len == 0 ? NE_OK : NE_ERROR; } int ne_discard_response(ne_request *req) { ssize_t len; do { len = ne_read_response_block(req, req->respbuf, sizeof req->respbuf); } while (len > 0); return len == 0 ? NE_OK : NE_ERROR; } int ne_request_dispatch(ne_request *req) { int ret; do { ret = ne_begin_request(req); if (ret == NE_OK) ret = ne_discard_response(req); if (ret == NE_OK) ret = ne_end_request(req); } while (ret == NE_RETRY); NE_DEBUG(NE_DBG_HTTP | NE_DBG_FLUSH, "Request ends, status %d class %dxx, error line:\n%s\n", req->status.code, req->status.klass, req->session->error); return ret; } const ne_status *ne_get_status(const ne_request *req) { return &req->status; } ne_session *ne_get_session(const ne_request *req) { return req->session; } #ifdef NE_HAVE_SSL /* Create a CONNECT tunnel through the proxy server. * Returns HTTP_* */ static int proxy_tunnel(ne_session *sess) { /* Hack up an HTTP CONNECT request... */ ne_request *req; int ret = NE_OK; char ruri[200]; /* Can't use server.hostport here; Request-URI must include `:port' */ ne_snprintf(ruri, sizeof ruri, "%s:%u", sess->server.hostname, sess->server.port); req = ne_request_create(sess, "CONNECT", ruri); sess->in_connect = 1; ret = ne_request_dispatch(req); sess->in_connect = 0; sess->persisted = 0; /* don't treat this is a persistent connection. */ if (ret != NE_OK || !sess->connected || req->status.klass != 2) { char *err = ne_strdup(sess->error); ne_set_error(sess, _("Could not create SSL connection " "through proxy server: %s"), err); ne_free(err); if (ret == NE_OK) ret = NE_ERROR; } ne_request_destroy(req); return ret; } #endif /* Return the first resolved address for the given host. */ static const ne_inet_addr *resolve_first(struct host_info *host) { return host->network ? host->network : ne_addr_first(host->address); } /* Return the next resolved address for the given host or NULL if * there are no more addresses. */ static const ne_inet_addr *resolve_next(struct host_info *host) { return host->network ? NULL : ne_addr_next(host->address); } /* Make new TCP connection to server at 'host' of type 'name'. Note * that once a connection to a particular network address has * succeeded, that address will be used first for the next attempt to * connect. */ static int do_connect(ne_session *sess, struct host_info *host) { int ret; /* Resolve hostname if necessary. */ if (host->address == NULL && host->network == NULL) { ret = lookup_host(sess, host); if (ret) return ret; } if ((sess->socket = ne_sock_create()) == NULL) { ne_set_error(sess, _("Could not create socket")); return NE_ERROR; } if (sess->cotimeout) ne_sock_connect_timeout(sess->socket, sess->cotimeout); if (sess->local_addr) ne_sock_prebind(sess->socket, sess->local_addr, 0); if (host->current == NULL) host->current = resolve_first(host); sess->status.ci.hostname = host->hostname; struct timespec deadline_timeout; if(sess->rdtimeout > 0){ ne_gettime(&deadline_timeout); deadline_timeout.tv_sec += sess->rdtimeout; } do { sess->status.ci.address = host->current; notify_status(sess, ne_status_connecting); #ifdef NE_DEBUGGING if (ne_debug_mask & NE_DBG_HTTP) { char buf[150]; NE_DEBUG(NE_DBG_HTTP, "req: Connecting to %s:%u", ne_iaddr_print(host->current, buf, sizeof buf), host->port); } #endif ret = ne_sock_connect(sess->socket, host->current, host->port); if(ret && sess->rdtimeout > 0){ struct timespec current_time; ne_gettime(¤t_time); if(current_time.tv_sec > deadline_timeout.tv_sec){ ret= NE_SOCK_TIMEOUT; break; } } } while (ret && /* try the next address... */ (host->current = resolve_next(host)) != NULL); if (ret) { const char *msg; if (host->proxy == PROXY_NONE) msg = _("Could not connect to server"); else msg = _("Could not connect to proxy server"); ne_set_error(sess, "%s: %s", msg, ne_sock_error(sess->socket)); ne_sock_close(sess->socket); return ret == NE_SOCK_TIMEOUT ? NE_TIMEOUT : NE_CONNECT; } if (sess->rdtimeout) ne_sock_read_timeout(sess->socket, sess->rdtimeout); notify_status(sess, ne_status_connected); sess->nexthop = host; sess->connected = 1; /* clear persistent connection flag. */ sess->persisted = 0; return NE_OK; } /* For a SOCKSv4 proxy only, the IP address of the origin server (in * addition to the proxy) must be known, and must be an IPv4 address. * Returns NE_*; connection closed and error string set on error. */ static int socks_origin_lookup(ne_session *sess) { const ne_inet_addr *ia; int ret; ret = lookup_host(sess, &sess->server); if (ret) { /* lookup_host already set the error string. */ ne_close_connection(sess); return ret; } /* Find the first IPv4 address available for the server. */ for (ia = ne_addr_first(sess->server.address); ia && ne_iaddr_typeof(ia) == ne_iaddr_ipv6; ia = ne_addr_next(sess->server.address)) { /* noop */ } /* ... if any */ if (ia == NULL) { ne_set_error(sess, _("Could not find IPv4 address of " "hostname %s for SOCKS v4 proxy"), sess->server.hostname); ne_close_connection(sess); return NE_LOOKUP; } sess->server.current = ia; return ret; } static int open_connection(ne_session *sess) { int ret; if (sess->connected) return NE_OK; if (!sess->proxies) { ret = do_connect(sess, &sess->server); if (ret) { sess->nexthop = NULL; return ret; } } else { struct host_info *hi; /* Attempt to re-use proxy to avoid iterating through * unnecessarily. */ if (sess->prev_proxy) ret = do_connect(sess, sess->prev_proxy); else ret = NE_ERROR; /* Otherwise, try everything - but omitting prev_proxy if that * has already been tried. */ for (hi = sess->proxies; hi && ret; hi = hi->next) { if (hi != sess->prev_proxy) ret = do_connect(sess, hi); } if (ret == NE_OK && sess->nexthop->proxy == PROXY_SOCKS) { /* Special-case for SOCKS v4 proxies, which require the * client to resolve the origin server IP address. */ if (sess->socks_ver == NE_SOCK_SOCKSV4) { ret = socks_origin_lookup(sess); } if (ret == NE_OK) { /* Perform the SOCKS handshake, instructing the proxy * to set up the connection to the origin server. */ ret = ne_sock_proxy(sess->socket, sess->socks_ver, sess->server.current, sess->server.hostname, sess->server.port, sess->socks_user, sess->socks_password); if (ret) { ne_set_error(sess, _("Could not establish connection from " "SOCKS proxy (%s:%u): %s"), sess->nexthop->hostname, sess->nexthop->port, ne_sock_error(sess->socket)); ne_close_connection(sess); ret = NE_ERROR; } } } if (ret != NE_OK) { sess->nexthop = NULL; sess->prev_proxy = NULL; return ret; } /* Success - make this proxy stick. */ sess->prev_proxy = hi; } #ifdef NE_HAVE_SSL /* Negotiate SSL layer if required. */ if (sess->use_ssl && !sess->in_connect) { /* Set up CONNECT tunnel if using an HTTP proxy. */ if (sess->nexthop->proxy == PROXY_HTTP) ret = proxy_tunnel(sess); if (ret == NE_OK) { ret = ne__negotiate_ssl(sess); if (ret != NE_OK) ne_close_connection(sess); } } #endif return ret; } davix-R_0_5_0/deps/libneon/src/ne_request.h000066400000000000000000000343041257152637300207640ustar00rootroot00000000000000/* HTTP Request Handling Copyright (C) 1999-2006, 2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_REQUEST_H #define NE_REQUEST_H #include #include "ne_utils.h" /* For ne_status */ #include "ne_string.h" /* For ne_buffer */ #include "ne_session.h" NE_BEGIN_DECLS #define NE_OK (0) /* Success */ #define NE_ERROR (1) /* Generic error; use ne_get_error(session) for message */ #define NE_LOOKUP (2) /* Server or proxy hostname lookup failed */ #define NE_AUTH (3) /* User authentication failed on server */ #define NE_PROXYAUTH (4) /* User authentication failed on proxy */ #define NE_CONNECT (5) /* Could not connect to server */ #define NE_TIMEOUT (6) /* Connection timed out */ #define NE_FAILED (7) /* The precondition failed */ #define NE_RETRY (8) /* Retry request (ne_end_request ONLY) */ #define NE_REDIRECT (9) /* See ne_redirect.h */ /* Opaque object representing a single HTTP request. */ typedef struct ne_request_s ne_request; /***** Request Handling *****/ /* Create a request in session 'sess', with given method and path. * 'path' must conform to the 'abs_path' grammar in RFC2396, with an * optional "? query" part, and MUST be URI-escaped by the caller. */ ne_request *ne_request_create(ne_session *sess, const char *method, const char *path); /* The request body will be taken from 'size' bytes of 'buffer'. */ void ne_set_request_body_buffer(ne_request *req, const char *buffer, size_t size); /* The request body will be taken from 'length' bytes read from the * file descriptor 'fd', starting from file offset 'offset'. */ void ne_set_request_body_fd(ne_request *req, int fd, ne_off_t offset, ne_off_t length); /* "Pull"-based request body provider: a callback which is invoked to * provide blocks of request body on demand. * * Before each time the body is provided, the callback will be called * once with buflen == 0. The body may have to be provided >1 time * per request (for authentication retries etc.). * * For a call with buflen == 0, the callback must return zero on success * or non-zero on error; the session error string must be set on error. * For a call with buflen > 0, the callback must return: * <0 : error, abort request; session error string must be set. * 0 : ignore 'buffer' contents, end of body. * 0 < x <= buflen : buffer contains x bytes of body data. */ typedef ssize_t (*ne_provide_body)(void *userdata, char *buffer, size_t buflen); /* Install a callback which is invoked as needed to provide the * request body, a block at a time. The total size of the request * body is 'length'; the callback must ensure that it returns no more * than 'length' bytes in total. */ void ne_set_request_body_provider(ne_request *req, ne_off_t length, ne_provide_body provider, void *userdata); /* Handling response bodies; two callbacks must be provided: * * 1) 'acceptance' callback: determines whether you want to handle the * response body given the response-status information, e.g., if you * only want 2xx responses, say so here. * * 2) 'reader' callback: passed blocks of the response-body as they * arrive, if the acceptance callback returned non-zero. */ /* 'acceptance' callback type. Return non-zero to accept the response, * else zero to ignore it. */ typedef int (*ne_accept_response)(void *userdata, ne_request *req, const ne_status *st); /* An 'acceptance' callback which only accepts 2xx-class responses. * Ignores userdata. */ int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st); /* An acceptance callback which accepts all responses. Ignores * userdata. */ int ne_accept_always(void *userdata, ne_request *req, const ne_status *st); /* Callback for reading a block of data. Returns zero on success, or * non-zero on error. If returning an error, the response will be * aborted and the callback will not be invoked again. The request * dispatch (or ne_read_response_block call) will fail with NE_ERROR; * the session error string should have been set by the callback. */ typedef int (*ne_block_reader)(void *userdata, const char *buf, size_t len); /* Add a response reader for the given request, with the given * acceptance function. userdata is passed as the first argument to * the acceptance + reader callbacks. * * The acceptance callback is called once each time the request is * sent: it may be sent >1 time because of authentication retries etc. * For each time the acceptance callback is called, if it returns * non-zero, blocks of the response body will be passed to the reader * callback as the response is read. After all the response body has * been read, the callback will be called with a 'len' argument of * zero. */ void ne_add_response_body_reader(ne_request *req, ne_accept_response accpt, ne_block_reader reader, void *userdata); /* Retrieve the value of the response header field with given name; * returns NULL if no response header with given name was found. The * return value is valid only until the next call to either * ne_request_destroy or ne_begin_request for this request. */ const char *ne_get_response_header(ne_request *req, const char *name); /* Iterator interface for response headers: if passed a NULL cursor, * returns the first header; if passed a non-NULL cursor pointer, * returns the next header. The return value is a cursor pointer: if * it is non-NULL, *name and *value are set to the name and value of * the header field. If the return value is NULL, no more headers are * found, *name and *value are undefined. * * The order in which response headers is returned is undefined. Both * the cursor and name/value pointers are valid only until the next * call to either ne_request_destroy or ne_begin_request for this * request. */ void *ne_response_header_iterate(ne_request *req, void *cursor, const char **name, const char **value); /* Adds a header to the request with given name and value. */ void ne_add_request_header(ne_request *req, const char *name, const char *value); /* Adds a header to the request with given name, using printf-like * format arguments for the value. */ void ne_print_request_header(ne_request *req, const char *name, const char *format, ...) ne_attribute((format(printf, 3, 4))); /* ne_request_dispatch: Sends the given request, and reads the * response. Returns: * - NE_OK if the request was sent and response read successfully * - NE_AUTH, NE_PROXYAUTH for a server or proxy server authentication error * - NE_CONNECT if connection could not be established * - NE_TIMEOUT if an timeout occurred sending or reading from the server * - NE_ERROR for other fatal dispatch errors * On any error, the session error string is set. On success or * authentication error, the actual response-status can be retrieved using * ne_get_status(). */ int ne_request_dispatch(ne_request *req); /* Returns a pointer to the response status information for the given * request; pointer is valid until request object is destroyed. */ const ne_status *ne_get_status(const ne_request *req) ne_attribute((const)); /* Returns pointer to session associated with request. */ ne_session *ne_get_session(const ne_request *req) ne_attribute((const)); /* Destroy memory associated with request pointer */ void ne_request_destroy(ne_request *req); /* "Caller-pulls" request interface. This is an ALTERNATIVE interface * to ne_request_dispatch: either use that, or do all this yourself: * * caller must call: * 1. ne_begin_request (fail if returns non-NE_OK) * 2. while(ne_read_response_block(...) > 0) ... loop ...; * (fail if ne_read_response_block returns <0) * 3. ne_end_request * * ne_end_request and ne_begin_request both return an NE_* code; if * ne_end_request returns NE_RETRY, you must restart the loop from (1) * above. */ int ne_begin_request(ne_request *req); int ne_end_request(ne_request *req); /* * * Abort open connexion in unstable state * * */ int ne_abort_request(ne_request* req); /* Read a block of the response into the passed buffer of size 'buflen'. * * Returns: * <0 - error, stop reading. * 0 - end of response * >0 - number of bytes read into buffer. */ ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen); /* Read response blocks until end of response; exactly equivalent to * calling ne_read_response_block() until it returns 0. Returns * non-zero on error. */ int ne_discard_response(ne_request *req); /* Read response blocks until end of response, writing content to the * given file descriptor. Returns NE_ERROR on error. */ int ne_read_response_to_fd(ne_request *req, int fd); /* Defined request flags: */ typedef enum ne_request_flag_e { NE_REQFLAG_EXPECT100 = 0, /* enable this flag to enable use of the * "Expect: 100-continue" for the * request. */ NE_REQFLAG_IDEMPOTENT, /* disable this flag if the request uses a * non-idempotent method such as POST. */ NE_REQFLAG_LAST /* enum sentinel value */ } ne_request_flag; /* Set a new value for a particular request flag. */ void ne_set_request_flag(ne_request *req, ne_request_flag flag, int value); /* Return 0 if the given flag is not set, >0 it is set, or -1 if the * flag is not supported. */ int ne_get_request_flag(ne_request *req, ne_request_flag flag); /**** Request hooks handling *****/ typedef void (*ne_free_hooks)(void *cookie); /* Hook called when a request is created; passed the request method, * and the string used as the Request-URI (note that this may be a * absolute URI if a proxy is in use, an absolute path, a "*", etc). * A create_request hook is called exactly once per request. */ typedef void (*ne_create_request_fn)(ne_request *req, void *userdata, const char *method, const char *requri); void ne_hook_create_request(ne_session *sess, ne_create_request_fn fn, void *userdata); /* Hook called before the request is sent. 'header' is the raw HTTP * header before the trailing CRLF is added; more headers can be added * here. A pre_send hook may be called >1 time per request if the * request is retried due to a post_send hook returning NE_RETRY. */ typedef void (*ne_pre_send_fn)(ne_request *req, void *userdata, ne_buffer *header); void ne_hook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata); /* Hook called directly after the response headers have been read, but * before the resposnse body has been read. 'status' is the response * status-code. A post_header hook may be called >1 time per request * if the request is retried due to a post_send hook returning * NE_RETRY. */ typedef void (*ne_post_headers_fn)(ne_request *req, void *userdata, const ne_status *status); void ne_hook_post_headers(ne_session *sess, ne_post_headers_fn fn, void *userdata); /* Hook called after the request is dispatched (request sent, and * the entire response read). If an error occurred reading the response, * this hook will not run. May return: * NE_OK everything is okay * NE_RETRY try sending the request again. * anything else signifies an error, and the request is failed. The return * code is passed back the _dispatch caller, so the session error must * also be set appropriately (ne_set_error). */ typedef int (*ne_post_send_fn)(ne_request *req, void *userdata, const ne_status *status); void ne_hook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata); /* Hook called when the function is destroyed. */ typedef void (*ne_destroy_req_fn)(ne_request *req, void *userdata); void ne_hook_destroy_request(ne_session *sess, ne_destroy_req_fn fn, void *userdata); typedef void (*ne_destroy_sess_fn)(void *userdata); /* Hook called when the session is about to be destroyed. */ void ne_hook_destroy_session(ne_session *sess, ne_destroy_sess_fn fn, void *userdata); typedef void (*ne_close_conn_fn)(void *userdata); /* Hook called when the connection is closed; note that this hook * may be called *AFTER* the destroy_session hook. */ void ne_hook_close_conn(ne_session *sess, ne_close_conn_fn fn, void *userdata); /* The ne_unhook_* functions remove a hook registered with the given * session. If a hook is found which was registered with a given * function 'fn', and userdata pointer 'userdata', then it will be * removed from the hooks list. * * It is unsafe to use any of these functions from a hook function to * unregister itself, except for ne_unhook_destroy_request. */ void ne_unhook_create_request(ne_session *sess, ne_create_request_fn fn, void *userdata); void ne_unhook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata); void ne_unhook_post_headers(ne_session *sess, ne_post_headers_fn fn, void *userdata); void ne_unhook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata); void ne_unhook_destroy_request(ne_session *sess, ne_destroy_req_fn fn, void *userdata); void ne_unhook_destroy_session(ne_session *sess, ne_destroy_sess_fn fn, void *userdata); void ne_unhook_close_conn(ne_session *sess, ne_close_conn_fn fn, void *userdata); /* Store an opaque context for the request, 'priv' is returned by a * call to ne_request_get_private with the same ID. */ void ne_set_request_private(ne_request *req, const char *id, void *priv); void *ne_get_request_private(ne_request *req, const char *id); NE_END_DECLS #endif /* NE_REQUEST_H */ davix-R_0_5_0/deps/libneon/src/ne_session.c000066400000000000000000000467711257152637300207650ustar00rootroot00000000000000/* HTTP session handling Copyright (C) 1999-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_LIBPROXY #include #endif #include "ne_session.h" #include "ne_alloc.h" #include "ne_utils.h" #include "ne_internal.h" #include "ne_string.h" #include "ne_dates.h" #include "ne_private.h" /* Destroy a a list of hooks. */ static void destroy_hooks(struct hook *hooks) { struct hook *nexthk; while (hooks) { nexthk = hooks->next; ne_free(hooks); hooks = nexthk; } } static void free_hostinfo(struct host_info *hi) { if (hi->hostname) ne_free(hi->hostname); if (hi->hostport) ne_free(hi->hostport); if (hi->address) ne_addr_destroy(hi->address); } /* Destroy the sess->proxies array. */ static void free_proxies(ne_session *sess) { struct host_info *hi, *nexthi; for (hi = sess->proxies; hi; hi = nexthi) { nexthi = hi->next; free_hostinfo(hi); ne_free(hi); } sess->any_proxy_http = 0; } void ne_session_destroy(ne_session *sess) { struct hook *hk; NE_DEBUG(NE_DBG_CORE, "sess: Destroying session."); /* Run the destroy hooks. */ for (hk = sess->destroy_sess_hooks; hk != NULL; hk = hk->next) { ne_destroy_sess_fn fn = (ne_destroy_sess_fn)hk->fn; fn(hk->userdata); } /* Close the connection; note that the notifier callback could * still be invoked here. */ if (sess->connected) { ne_close_connection(sess); } destroy_hooks(sess->create_req_hooks); destroy_hooks(sess->pre_send_hooks); destroy_hooks(sess->post_headers_hooks); destroy_hooks(sess->post_send_hooks); destroy_hooks(sess->destroy_req_hooks); destroy_hooks(sess->destroy_sess_hooks); destroy_hooks(sess->close_conn_hooks); destroy_hooks(sess->private); ne_free(sess->scheme); free_hostinfo(&sess->server); free_proxies(sess); if (sess->user_agent) ne_free(sess->user_agent); if (sess->socks_user) ne_free(sess->socks_user); if (sess->socks_password) ne_free(sess->socks_password); #ifdef NE_HAVE_SSL if (sess->ssl_context) ne_ssl_context_destroy(sess->ssl_context); if (sess->server_cert) ne_ssl_cert_free(sess->server_cert); if (sess->client_cert) ne_ssl_clicert_free(sess->client_cert); #endif ne_free(sess); } int ne_version_pre_http11(ne_session *s) { return !s->is_http11; } /* Stores the "hostname[:port]" segment */ static void set_hostport(struct host_info *host, unsigned int defaultport) { size_t len = strlen(host->hostname); host->hostport = ne_malloc(len + 10); strcpy(host->hostport, host->hostname); if (host->port != defaultport) ne_snprintf(host->hostport + len, 9, ":%u", host->port); } /* Stores the hostname/port in *info, setting up the "hostport" * segment correctly. */ static void set_hostinfo(struct host_info *hi, enum proxy_type type, const char *hostname, unsigned int port) { hi->hostname = ne_strdup(hostname); hi->port = port; hi->proxy = type; } ne_session *ne_session_create(const char *scheme, const char *hostname, unsigned int port) { ne_session *sess = ne_calloc(sizeof *sess); NE_DEBUG(NE_DBG_HTTP, "HTTP session to %s://%s:%d begins.", scheme, hostname, port); strcpy(sess->error, "Unknown error."); /* use SSL if scheme is https */ sess->use_ssl = !strcmp(scheme, "https"); /* set the hostname/port */ set_hostinfo(&sess->server, PROXY_NONE, hostname, port); set_hostport(&sess->server, sess->use_ssl?443:80); #ifdef NE_HAVE_SSL if (sess->use_ssl) { ne_inet_addr *ia; sess->ssl_context = ne_ssl_context_create(0); sess->flags[NE_SESSFLAG_SSLv2] = 1; /* If the hostname parses as an IP address, don't * enable SNI by default. */ ia = ne_iaddr_parse(hostname, ne_iaddr_ipv4); if (ia == NULL) ia = ne_iaddr_parse(hostname, ne_iaddr_ipv6); if (ia) { ne_iaddr_free(ia); } else { sess->flags[NE_SESSFLAG_TLS_SNI] = 1; } NE_DEBUG(NE_DBG_SSL, "ssl: SNI %s by default.", sess->flags[NE_SESSFLAG_TLS_SNI] ? "enabled" : "disabled"); } #endif sess->scheme = ne_strdup(scheme); /* Set flags which default to on: */ sess->flags[NE_SESSFLAG_PERSIST] = 1; return sess; } void ne_session_proxy(ne_session *sess, const char *hostname, unsigned int port) { free_proxies(sess); sess->proxies = ne_calloc(sizeof *sess->proxies); sess->any_proxy_http = 1; set_hostinfo(sess->proxies, PROXY_HTTP, hostname, port); } void ne_session_socks_proxy(ne_session *sess, enum ne_sock_sversion vers, const char *hostname, unsigned int port, const char *username, const char *password) { free_proxies(sess); sess->proxies = ne_calloc(sizeof *sess->proxies); set_hostinfo(sess->proxies, PROXY_SOCKS, hostname, port); sess->socks_ver = vers; if (username) sess->socks_user = ne_strdup(username); if (password) sess->socks_password = ne_strdup(password); } void ne_session_system_proxy(ne_session *sess, unsigned int flags) { #ifdef HAVE_LIBPROXY pxProxyFactory *pxf = px_proxy_factory_new(); struct host_info *hi, **lasthi; char *url, **proxies; ne_uri uri; unsigned n; free_proxies(sess); /* Create URI for session to pass off to libproxy */ memset(&uri, 0, sizeof uri); ne_fill_server_uri(sess, &uri); uri.path = "/"; /* make valid URI structure. */ url = ne_uri_unparse(&uri); uri.path = NULL; /* Get list of pseudo-URIs from libproxy: */ proxies = px_proxy_factory_get_proxies(pxf, url); for (n = 0, lasthi = &sess->proxies; proxies[n]; n++) { enum proxy_type ptype; ne_uri_free(&uri); NE_DEBUG(NE_DBG_HTTP, "sess: libproxy #%u=%s", n, proxies[n]); if (ne_uri_parse(proxies[n], &uri)) continue; if (!uri.scheme) continue; if (ne_strcasecmp(uri.scheme, "http") == 0) ptype = PROXY_HTTP; else if (ne_strcasecmp(uri.scheme, "socks") == 0) ptype = PROXY_SOCKS; else if (ne_strcasecmp(uri.scheme, "direct") == 0) ptype = PROXY_NONE; else continue; /* Hostname/port required for http/socks schemes. */ if (ptype != PROXY_NONE && !(uri.host && uri.port)) continue; /* Do nothing if libproxy returned only a single "direct://" * entry -- a single "direct" (noop) proxy is equivalent to * having none. */ if (n == 0 && proxies[1] == NULL && ptype == PROXY_NONE) break; NE_DEBUG(NE_DBG_HTTP, "sess: Got proxy %s://%s:%d", uri.scheme, uri.host ? uri.host : "(none)", uri.port); hi = *lasthi = ne_calloc(sizeof *hi); if (ptype == PROXY_NONE) { /* A "direct" URI requires an attempt to connect directly to * the origin server, so dup the server details. */ set_hostinfo(hi, ptype, sess->server.hostname, sess->server.port); } else { /* SOCKS/HTTP proxy. */ set_hostinfo(hi, ptype, uri.host, uri.port); if (ptype == PROXY_HTTP) sess->any_proxy_http = 1; else if (ptype == PROXY_SOCKS) sess->socks_ver = NE_SOCK_SOCKSV5; } lasthi = &hi->next; } /* Free up the proxies array: */ for (n = 0; proxies[n]; n++) free(proxies[n]); free(proxies[n]); ne_free(url); ne_uri_free(&uri); px_proxy_factory_free(pxf); #endif } void ne_set_addrlist(ne_session *sess, const ne_inet_addr **addrs, size_t n) { struct host_info *hi, **lasthi; size_t i; free_proxies(sess); lasthi = &sess->proxies; for (i = 0; i < n; i++) { *lasthi = hi = ne_calloc(sizeof *hi); hi->proxy = PROXY_NONE; hi->network = addrs[i]; hi->port = sess->server.port; lasthi = &hi->next; } } void ne_set_localaddr(ne_session *sess, const ne_inet_addr *addr) { sess->local_addr = addr; } void ne_set_error(ne_session *sess, const char *format, ...) { va_list params; va_start(params, format); ne_vsnprintf(sess->error, sizeof sess->error, format, params); va_end(params); } void ne_set_session_flag(ne_session *sess, ne_session_flag flag, int value) { if (flag < NE_SESSFLAG_LAST) { sess->flags[flag] = value; #ifdef NE_HAVE_SSL if (flag == NE_SESSFLAG_SSLv2 && sess->ssl_context) { ne_ssl_context_set_flag(sess->ssl_context, NE_SSL_CTX_SSLv2, value); } #endif } } int ne_get_session_flag(ne_session *sess, ne_session_flag flag) { if (flag < NE_SESSFLAG_LAST) { return sess->flags[flag]; } return -1; } static void progress_notifier(void *userdata, ne_session_status status, const ne_session_status_info *info) { ne_session *sess = userdata; if (status == ne_status_sending || status == ne_status_recving) { sess->progress_cb(sess->progress_ud, info->sr.progress, info->sr.total); } } void ne_set_progress(ne_session *sess, ne_progress progress, void *userdata) { if (progress) { sess->progress_cb = progress; sess->progress_ud = userdata; ne_set_notifier(sess, progress_notifier, sess); } else { ne_set_notifier(sess, NULL, NULL); } } void ne_set_notifier(ne_session *sess, ne_notify_status status, void *userdata) { sess->notify_cb = status; sess->notify_ud = userdata; } void ne_set_read_timeout(ne_session *sess, int timeout) { sess->rdtimeout = timeout; } void ne_set_connect_timeout(ne_session *sess, int timeout) { sess->cotimeout = timeout; } #define UAHDR "User-Agent: " #define AGENT " neon/" NEON_VERSION "\r\n" void ne_set_useragent(ne_session *sess, const char *token) { if (sess->user_agent) ne_free(sess->user_agent); sess->user_agent = ne_malloc(strlen(UAHDR) + strlen(AGENT) + strlen(token) + 1); #ifdef HAVE_STPCPY strcpy(stpcpy(stpcpy(sess->user_agent, UAHDR), token), AGENT); #else strcat(strcat(strcpy(sess->user_agent, UAHDR), token), AGENT); #endif } const char *ne_get_server_hostport(ne_session *sess) { return sess->server.hostport; } const char *ne_get_scheme(ne_session *sess) { return sess->scheme; } void ne_fill_server_uri(ne_session *sess, ne_uri *uri) { uri->host = ne_strdup(sess->server.hostname); uri->port = sess->server.port; uri->scheme = ne_strdup(sess->scheme); } void ne_fill_proxy_uri(ne_session *sess, ne_uri *uri) { if (sess->proxies) { struct host_info *hi = sess->nexthop ? sess->nexthop : sess->proxies; if (hi->proxy == PROXY_HTTP) { uri->host = ne_strdup(hi->hostname); uri->port = hi->port; } } } const char *ne_get_error(ne_session *sess) { if(sess) return sess->error; return NULL; } void ne_close_connection(ne_session *sess) { if (sess->connected) { struct hook *hk; NE_DEBUG(NE_DBG_SOCKET, "sess: Closing connection."); if (sess->notify_cb) { sess->status.cd.hostname = sess->nexthop->hostname; sess->notify_cb(sess->notify_ud, ne_status_disconnected, &sess->status); } /* Run the close_conn hooks. */ for (hk = sess->close_conn_hooks; hk != NULL; hk = hk->next) { ne_close_conn_fn fn = (ne_close_conn_fn)hk->fn; fn(hk->userdata); } ne_sock_close(sess->socket); sess->socket = NULL; NE_DEBUG(NE_DBG_SOCKET, "sess: Connection closed."); } else { NE_DEBUG(NE_DBG_SOCKET, "sess: Not closing closed connection."); } sess->connected = 0; } void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdata) { sess->ssl_verify_fn = fn; sess->ssl_verify_ud = userdata; } void ne_ssl_provide_clicert(ne_session *sess, ne_ssl_provide_fn fn, void *userdata) { sess->ssl_provide_fn = fn; sess->ssl_provide_ud = userdata; } void ne_ssl_trust_cert(ne_session *sess, const ne_ssl_certificate *cert) { #ifdef NE_HAVE_SSL if (sess->ssl_context) { ne_ssl_context_trustcert(sess->ssl_context, cert); } #endif } int ne_ssl_truse_add_ca_path(ne_session* sess, const char* path){ #ifdef NE_HAVE_SSL if (sess->ssl_context) { return ne_ssl_context_trust_add_ca_path(sess->ssl_context, path); } #endif return -1; } void ne_ssl_cert_validity(const ne_ssl_certificate *cert, char *from, char *until) { #ifdef NE_HAVE_SSL time_t tf, tu; char *date; ne_ssl_cert_validity_time(cert, &tf, &tu); if (from) { if (tf != (time_t) -1) { date = ne_rfc1123_date(tf); ne_strnzcpy(from, date, NE_SSL_VDATELEN); ne_free(date); } else { ne_strnzcpy(from, _("[invalid date]"), NE_SSL_VDATELEN); } } if (until) { if (tu != (time_t) -1) { date = ne_rfc1123_date(tu); ne_strnzcpy(until, date, NE_SSL_VDATELEN); ne_free(date); } else { ne_strnzcpy(until, _("[invalid date]"), NE_SSL_VDATELEN); } } #endif } #ifdef NE_HAVE_SSL void ne__ssl_set_verify_err(ne_session *sess, int failures) { static const struct { int bit; const char *str; } reasons[] = { { NE_SSL_NOTYETVALID, N_("certificate is not yet valid") }, { NE_SSL_EXPIRED, N_("certificate has expired") }, { NE_SSL_IDMISMATCH, N_("certificate issued for a different hostname") }, { NE_SSL_UNTRUSTED, N_("issuer is not trusted") }, { NE_SSL_BADCHAIN, N_("bad certificate chain") }, { NE_SSL_REVOKED, N_("certificate has been revoked") }, { 0, NULL } }; int n, flag = 0; strcpy(sess->error, _("Server certificate verification failed: ")); for (n = 0; reasons[n].bit; n++) { if (failures & reasons[n].bit) { if (flag) strncat(sess->error, ", ", sizeof sess->error - 1); strncat(sess->error, _(reasons[n].str), sizeof sess->error - 1); flag = 1; } } } /* This doesn't actually implement complete RFC 2818 logic; omits * "f*.example.com" support for simplicity. */ int ne__ssl_match_hostname(const char *cn, size_t cnlen, const char *hostname) { const char *dot; NE_DEBUG(NE_DBG_SSL, "ssl: Match common name '%s' against '%s'", cn, hostname); if (strncmp(cn, "*.", 2) == 0 && cnlen > 2 && (dot = strchr(hostname, '.')) != NULL) { ne_inet_addr *ia; /* Prevent wildcard CN matches against anything which can be * parsed as an IP address (i.e. a CN of "*.1.1.1" should not * be match 8.1.1.1). draft-saintandre-tls-server-id-check * will require some more significant changes to cert ID * verification which will probably obviate this check, but * this is a desirable policy tightening in the mean time. */ ia = ne_iaddr_parse(hostname, ne_iaddr_ipv4); if (ia == NULL) ia = ne_iaddr_parse(hostname, ne_iaddr_ipv6); if (ia) { NE_DEBUG(NE_DBG_SSL, "ssl: Denying wildcard match for numeric " "IP address.\n"); ne_iaddr_free(ia); return 0; } hostname = dot + 1; cn += 2; cnlen -= 2; } return cnlen == strlen(hostname) && !ne_strcasecmp(cn, hostname); } #endif /* NE_HAVE_SSL */ typedef void (*void_fn)(void); #define ADD_HOOK(hooks, fn, ud) add_hook(&(hooks), NULL, (void_fn)(fn), (ud)) static void add_hook(struct hook **hooks, const char *id, void_fn fn, void *ud) { struct hook *hk = ne_malloc(sizeof (struct hook)), *pos; if (*hooks != NULL) { for (pos = *hooks; pos->next != NULL; pos = pos->next) /* nullop */; pos->next = hk; } else { *hooks = hk; } hk->id = id; hk->fn = fn; hk->userdata = ud; hk->next = NULL; } void ne_hook_create_request(ne_session *sess, ne_create_request_fn fn, void *userdata) { ADD_HOOK(sess->create_req_hooks, fn, userdata); } void ne_hook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata) { ADD_HOOK(sess->pre_send_hooks, fn, userdata); } void ne_hook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata) { ADD_HOOK(sess->post_send_hooks, fn, userdata); } void ne_hook_post_headers(ne_session *sess, ne_post_headers_fn fn, void *userdata) { ADD_HOOK(sess->post_headers_hooks, fn, userdata); } void ne_hook_destroy_request(ne_session *sess, ne_destroy_req_fn fn, void *userdata) { ADD_HOOK(sess->destroy_req_hooks, fn, userdata); } void ne_hook_destroy_session(ne_session *sess, ne_destroy_sess_fn fn, void *userdata) { ADD_HOOK(sess->destroy_sess_hooks, fn, userdata); } void ne_hook_close_conn(ne_session *sess, ne_close_conn_fn fn, void *userdata) { ADD_HOOK(sess->close_conn_hooks, fn, userdata); } void ne_set_session_private(ne_session *sess, const char *id, void *userdata) { add_hook(&sess->private, id, NULL, userdata); } static void remove_hook(struct hook **hooks, void_fn fn, void *ud) { struct hook **p = hooks; while (*p) { if ((*p)->fn == fn && (*p)->userdata == ud) { struct hook *next = (*p)->next; ne_free(*p); (*p) = next; break; } p = &(*p)->next; } } #define REMOVE_HOOK(hooks, fn, ud) remove_hook(&hooks, (void_fn)fn, ud) void ne_unhook_create_request(ne_session *sess, ne_create_request_fn fn, void *userdata) { REMOVE_HOOK(sess->create_req_hooks, fn, userdata); } void ne_unhook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata) { REMOVE_HOOK(sess->pre_send_hooks, fn, userdata); } void ne_unhook_post_headers(ne_session *sess, ne_post_headers_fn fn, void *userdata) { REMOVE_HOOK(sess->post_headers_hooks, fn, userdata); } void ne_unhook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata) { REMOVE_HOOK(sess->post_send_hooks, fn, userdata); } void ne_unhook_destroy_request(ne_session *sess, ne_destroy_req_fn fn, void *userdata) { REMOVE_HOOK(sess->destroy_req_hooks, fn, userdata); } void ne_unhook_destroy_session(ne_session *sess, ne_destroy_sess_fn fn, void *userdata) { REMOVE_HOOK(sess->destroy_sess_hooks, fn, userdata); } void ne_unhook_close_conn(ne_session *sess, ne_close_conn_fn fn, void *userdata) { REMOVE_HOOK(sess->close_conn_hooks, fn, userdata); } davix-R_0_5_0/deps/libneon/src/ne_session.h000066400000000000000000000354141257152637300207620ustar00rootroot00000000000000/* HTTP session handling Copyright (C) 1999-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_SESSION_H #define NE_SESSION_H 1 #include #include "ne_ssl.h" #include "ne_uri.h" /* for ne_uri */ #include "ne_defs.h" #include "ne_socket.h" NE_BEGIN_DECLS typedef struct ne_session_s ne_session; /* Create a session to the given server, using the given scheme. If * "https" is passed as the scheme, SSL will be used to connect to the * server. */ ne_session *ne_session_create(const char *scheme, const char *hostname, unsigned int port); /* Finish an HTTP session */ void ne_session_destroy(ne_session *sess); /* Prematurely force the connection to be closed for the given * session. */ void ne_close_connection(ne_session *sess); /* Set the proxy server to be used for the session. This function * will override (remove) any proxy servers previously configured, and * must be called before any requests are created using this * session. */ void ne_session_proxy(ne_session *sess, const char *hostname, unsigned int port); /* Configure a SOCKS proxy server which will be used for the session. * The SOCKS protocol version 'vers' will be used to contact the * proxy at given 'hostname' and 'port'. * * If SOCKSv4 or v4a are used, username must be non-NULL. For v5, * username may be NULL, in which case, password is ignored. If * username is non-NULL, password must also be non-NULL. * * This function will override (remove) any proxy servers previously * configured, and must be called before any requests are created * using this session. */ void ne_session_socks_proxy(ne_session *sess, enum ne_sock_sversion vers, const char *hostname, unsigned int port, const char *username, const char *password); /* Configure use of proxy servers from any system-wide default sources * which are configured at build time. This function will override * (remove) any proxy servers previously configured, and must be * called before any requests are created using this session. The * 'flags' parameter must be zero. */ void ne_session_system_proxy(ne_session *sess, unsigned int flags); /* Defined session flags: */ typedef enum ne_session_flag_e { NE_SESSFLAG_PERSIST = 0, /* disable this flag to prevent use of * persistent connections. */ NE_SESSFLAG_ICYPROTO, /* enable this flag to enable support for * non-HTTP ShoutCast-style "ICY" responses. */ NE_SESSFLAG_SSLv2, /* disable this flag to disable support for * SSLv2, if supported by the SSL library. */ NE_SESSFLAG_RFC4918, /* enable this flag to enable support for * RFC4918-only WebDAV features; losing * backwards-compatibility with RFC2518 * servers. */ NE_SESSFLAG_CONNAUTH, /* enable this flag if an awful, broken, * RFC-violating, connection-based HTTP * authentication scheme is in use. */ NE_SESSFLAG_TLS_SNI, /* disable this flag to disable use of the * TLS Server Name Indication extension. */ NE_SESSFLAG_EXPECT100, /* enable this flag to enable the flag * NE_REQFLAG_EXPECT100 for new requests. */ NE_SESSFLAG_LAST /* enum sentinel value */ } ne_session_flag; /* Set a new value for a particular session flag. */ void ne_set_session_flag(ne_session *sess, ne_session_flag flag, int value); /* Return 0 if the given flag is not set, >0 it is set, or -1 if the * flag is not supported. */ int ne_get_session_flag(ne_session *sess, ne_session_flag flag); /* Bypass the normal name resolution; force the use of specific set of * addresses for this session, addrs[0]...addrs[n-1]. The 'addrs' * array and pointed-to objects must remain valid until the session is * destroyed. This function will override (remove) any proxy servers * previously configured, and must be called before any requests are * created using this session. */ void ne_set_addrlist(ne_session *sess, const ne_inet_addr **addrs, size_t n); /* Bind connections to the specified local address. If the address * determined for the remote host has a different family (type) to * 'addr', 'addr' will be ignored. The 'addr' object must remain * valid until the session is destroyed. */ void ne_set_localaddr(ne_session *sess, const ne_inet_addr *addr); /* DEPRECATED: Progress callback. */ typedef void (*ne_progress)(void *userdata, ne_off_t progress, ne_off_t total); /* DEPRECATED API: Set a progress callback for the session; this is * deprecated in favour of ne_set_notifier(). The progress callback * is invoked for after each block of the request and response body to * indicate request and response progress (there is no way to * distinguish between the two using this interface alone). * If progress is NULL, any existing callback is deregistered and will * no longer be invoked. * * NOTE: Use of this interface is mutually exclusive with the use of * ne_set_notifier(). A call to ne_set_progress() removes the * notifier callback, and vice versa. */ void ne_set_progress(ne_session *sess, ne_progress progress, void *userdata); /* Store an opaque context for the session, 'priv' is returned by a * call to ne_session_get_private with the same ID. */ void ne_set_session_private(ne_session *sess, const char *id, void *priv); void *ne_get_session_private(ne_session *sess, const char *id); /* Status event type. NOTE: More event types may be added in * subsequent releases, so callers must ignore unknown status types * for forwards-compatibility. */ typedef enum { ne_status_lookup = 0, /* looking up hostname */ ne_status_connecting, /* connecting to host */ ne_status_connected, /* connected to host */ ne_status_sending, /* sending a request body */ ne_status_recving, /* receiving a response body */ ne_status_disconnected /* disconnected from host */ } ne_session_status; /* Status event information union; the relevant structure within * corresponds to the event type. WARNING: the size of this union is * not limited by ABI constraint; it may be extended with additional * members of different size, or existing members may be extended. */ typedef union ne_session_status_info_u { struct /* ne_status_lookup */ { /* The hostname which is being resolved: */ const char *hostname; } lu; struct /* ne_status_connecting */ { /* The hostname and network address to which a connection * attempt is being made: */ const char *hostname; const ne_inet_addr *address; } ci; struct /* ne_status_connected, ne_status_disconnected */ { /* The hostname to which a connection has just been * established or closed: */ const char *hostname; } cd; struct /* ne_status_sending and ne_status_recving */ { /* Request/response body transfer progress; if total == -1, * the total size is unknown; otherwise, total gives the total * number of bytes which will be transferred. progress gives * the number of bytes transferred so far. */ ne_off_t progress, total; } sr; } ne_session_status_info; /* Callback invoked to notify a new session status event, given by the * 'status' argument. On invocation, the contents of exactly one of * the structures in the info union will be valid, as indicated * above. */ typedef void (*ne_notify_status)(void *userdata, ne_session_status status, const ne_session_status_info *info); /* Set a status notification callback for the session, to report * session status events. Only one notification callback per session * can be registered; the most recent of successive calls to this * function takes effect. If status is NULL, any existing callback * is deregistered and will no longer be invoked. * * NOTE: Use of this interface is mutually exclusive with the use of * ne_set_progress(). A call to ne_set_notifier() removes the * progress callback, and vice versa. */ void ne_set_notifier(ne_session *sess, ne_notify_status status, void *userdata); /* Certificate verification failures. */ /* NE_SSL_NOTYETVALID: the certificate is not yet valid. */ #define NE_SSL_NOTYETVALID (0x01) /* NE_SSL_EXPIRED: the certificate has expired. */ #define NE_SSL_EXPIRED (0x02) /* NE_SSL_IDMISMATCH: the hostname for which the certificate was * issued does not match the hostname of the server; this could mean * that the connection is being intercepted. */ #define NE_SSL_IDMISMATCH (0x04) /* NE_SSL_UNTRUSTED: the certificate authority which signed the server * certificate is not trusted: there is no indicatation the server is * who they claim to be: */ #define NE_SSL_UNTRUSTED (0x08) /* NE_SSL_BADCHAIN: the certificate chain contained a certificate * other than the server cert which failed verification for a reason * other than lack of trust; for example, due to a CA cert being * outside its validity period. */ #define NE_SSL_BADCHAIN (0x10) /* N.B.: 0x20 is reserved. */ /* NE_SSL_REVOKED: the server certificate has been revoked by the * issuing authority. */ #define NE_SSL_REVOKED (0x40) /* For purposes of forwards-compatibility, the bitmask of all * currently exposed failure bits is given as NE_SSL_FAILMASK. If the * expression (failures & ~NE_SSL_FAILMASK) is non-zero a failure type * is present which the application does not recognize but must treat * as a verification failure nonetheless. */ #define NE_SSL_FAILMASK (0x5f) /* A callback which is used when server certificate verification is * needed. The reasons for verification failure are given in the * 'failures' parameter, which is a binary OR of one or more of the * above NE_SSL_* values. failures is guaranteed to be non-zero. The * callback must return zero to accept the certificate: a non-zero * return value will fail the SSL negotiation. */ typedef int (*ne_ssl_verify_fn)(void *userdata, int failures, const ne_ssl_certificate *cert); /* Install a callback to handle server certificate verification. This * is required when the CA certificate is not known for the server * certificate, or the server cert has other verification problems. */ void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdata); /* Use the given client certificate for the session. The client cert * MUST be in the decrypted state, otherwise behaviour is undefined. * The 'clicert' object is duplicated internally so can be destroyed * by the caller. */ void ne_ssl_set_clicert(ne_session *sess, const ne_ssl_client_cert *clicert); /* Indicate that the certificate 'cert' is trusted; the 'cert' object * is duplicated internally so can be destroyed by the caller. This * function has no effect for non-SSL sessions. */ void ne_ssl_trust_cert(ne_session *sess, const ne_ssl_certificate *cert); /* If the SSL library provided a default set of CA certificates, trust * this set of CAs. */ void ne_ssl_trust_default_ca(ne_session *sess); /* load all the CA certificates in the directory 'path' and considers * them as trusted * return 0 if success */ int ne_ssl_truse_add_ca_path(ne_session* sess, const char* path); /* Callback used to load a client certificate on demand. If dncount * is > 0, the 'dnames' array dnames[0] through dnames[dncount-1] * gives the list of CA names which the server indicated were * acceptable. The callback should load an appropriate client * certificate and then pass it to 'ne_ssl_set_clicert'. */ typedef void (*ne_ssl_provide_fn)(void *userdata, ne_session *sess, const ne_ssl_dname *const *dnames, int dncount); /* Register a function to be called when the server requests a client * certificate. */ void ne_ssl_provide_clicert(ne_session *sess, ne_ssl_provide_fn fn, void *userdata); /* Set the timeout (in seconds) used when reading from a socket. The * timeout value must be greater than zero. */ void ne_set_read_timeout(ne_session *sess, int timeout); /* Set the timeout (in seconds) used when making a connection. The * timeout value must be greater than zero. */ void ne_set_connect_timeout(ne_session *sess, int timeout); /* Sets the user-agent string. neon/VERSION will be appended, to make * the full header "User-Agent: product neon/VERSION". * If this function is not called, the User-Agent header is not sent. * The product string must follow the RFC2616 format, i.e. * product = token ["/" product-version] * product-version = token * where token is any alpha-numeric-y string [a-zA-Z0-9]* */ void ne_set_useragent(ne_session *sess, const char *product); /* Returns non-zero if next-hop server does not claim compliance to * HTTP/1.1 or later. */ int ne_version_pre_http11(ne_session *sess); /* Returns the 'hostport' URI segment for the end-server, e.g. * "my.server.com:8080". */ const char *ne_get_server_hostport(ne_session *sess); /* Returns the URL scheme being used for the current session, omitting * the trailing ':'; e.g. "http" or "https". */ const char *ne_get_scheme(ne_session *sess); /* Sets the host, scheme, and port fields of the given URI structure * to that of the configured server and scheme for the session; host * and scheme are malloc-allocated. No other fields in the URI * structure are changed. */ void ne_fill_server_uri(ne_session *sess, ne_uri *uri); /* If a proxy is configured, sets the host and port fields in the * given URI structure to that of the proxy. If multiple proxies are * configured, the active is used if any, otherwise the first. The * hostname is malloc-allocated. No other fields in the URI structure * are changed; if no proxy is configured or a non-HTTP proxy is in * use, no fields are changed. */ void ne_fill_proxy_uri(ne_session *sess, ne_uri *uri); /* Set the error string for the session; takes printf-like format * string. */ void ne_set_error(ne_session *sess, const char *format, ...) ne_attribute((format (printf, 2, 3))); /* Retrieve the error string for the session */ const char *ne_get_error(ne_session *sess); NE_END_DECLS #endif /* NE_SESSION_H */ davix-R_0_5_0/deps/libneon/src/ne_socket.c000066400000000000000000001531071257152637300205620ustar00rootroot00000000000000/* Socket handling routines Copyright (C) 1998-2009, Joe Orton Copyright (C) 2004 Aleix Conchillo Flaque This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* portions were originally under GPL in Mutt, http://www.mutt.org/ Relicensed under LGPL for neon, http://www.webdav.org/neon/ */ #include "config.h" #include #ifdef HAVE_SYS_TIME_H #include #endif #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef NE_USE_POLL #include #elif defined(HAVE_SYS_SELECT_H) #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETINET_TCP_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef WIN32 #include #include #ifdef USE_GETADDRINFO #include #include #endif #endif #if defined(HAVE_OPENSSL) && defined(HAVE_LIMITS_H) #include /* for INT_MAX */ #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SIGNAL_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_SOCKS_H #include #endif #ifdef HAVE_OPENSSL #include #include #include /* for PKCS12_PBE_add */ #include #include /* for OPENSSL_VERSION_NUMBER */ #endif #ifdef HAVE_GNUTLS #include #endif #define NE_INET_ADDR_DEFINED /* A slightly ugly hack: change the ne_inet_addr definition to be the * real address type used. The API only exposes ne_inet_addr as a * pointer to an opaque object, so this should be well-defined * behaviour. It avoids the hassle of a real wrapper ne_inet_addr * structure, or losing type-safety by using void *. */ #ifdef USE_GETADDRINFO typedef struct addrinfo ne_inet_addr; #else typedef struct in_addr ne_inet_addr; #endif #include "ne_privssl.h" /* MUST come after ne_inet_addr is defined */ /* To avoid doing AAAA queries unless absolutely necessary, either use * AI_ADDRCONFIG where available, or a run-time check for working IPv6 * support; the latter is only known to work on Linux. */ #if defined(USE_GETADDRINFO) && !defined(USE_GAI_ADDRCONFIG) && defined(__linux__) #define USE_CHECK_IPV6 #endif // Use always non blocking socket #ifndef USE_NONBLOCKING_CONNECT #define USE_NONBLOCKING_CONNECT #endif #include "ne_internal.h" #include "ne_utils.h" #include "ne_string.h" #include "ne_socket.h" #include "ne_alloc.h" #include "ne_sspi.h" #if defined(__BEOS__) && !defined(BONE_VERSION) /* pre-BONE */ #define ne_close(s) closesocket(s) #define ne_errno errno #elif defined(WIN32) #define ne_close(s) closesocket(s) #define ne_errno WSAGetLastError() #else /* really Unix! */ #define ne_close(s) close(s) #define ne_errno errno #endif #ifdef WIN32 #define NE_ISRESET(e) ((e) == WSAECONNABORTED || (e) == WSAETIMEDOUT || \ (e) == WSAECONNRESET || (e) == WSAENETRESET) #define NE_ISCLOSED(e) ((e) == WSAESHUTDOWN || (e) == WSAENOTCONN) #define NE_ISINTR(e) (0) #define NE_ISINPROGRESS(e) ((e) == WSAEWOULDBLOCK) /* says MSDN */ #else /* Unix */ /* Also treat ECONNABORTED and ENOTCONN as "connection reset" errors; * both can be returned by Winsock-based sockets layers e.g. CygWin */ #ifndef ECONNABORTED #define ECONNABORTED ECONNRESET #endif #ifndef ENOTCONN #define ENOTCONN ECONNRESET #endif #define NE_ISRESET(e) ((e) == ECONNRESET || (e) == ECONNABORTED || (e) == ENOTCONN) #define NE_ISCLOSED(e) ((e) == EPIPE) #define NE_ISINTR(e) (((e) == EINTR) || ((e) == EAGAIN)) #define NE_ISINPROGRESS(e) ((e) == EINPROGRESS) #endif /* Socket read timeout */ #define SOCKET_READ_TIMEOUT 120 /* Critical I/O functions on a socket: useful abstraction for easily * handling SSL I/O alongside raw socket I/O. */ struct iofns { /* Read up to 'len' bytes into 'buf' from socket. Return <0 on * error or EOF, or >0; number of bytes read. */ ssize_t (*sread)(ne_socket *s, char *buf, size_t len); /* Write up to 'len' bytes from 'buf' to socket. Return number of * bytes written on success, or <0 on error. */ ssize_t (*swrite)(ne_socket *s, const char *buf, size_t len); /* Wait up to 'n' seconds for socket to become readable. Returns * 0 when readable, otherwise NE_SOCK_TIMEOUT or NE_SOCK_ERROR. */ int (*readable)(ne_socket *s, int n); /* Write up to 'count' blocks described by 'vector' to socket. * Return number of bytes written on success, or <0 on error. */ ssize_t (*swritev)(ne_socket *s, const struct ne_iovec *vector, int count); }; static const ne_inet_addr dummy_laddr; struct ne_socket_s { int fd; unsigned int lport; const ne_inet_addr *laddr; void *progress_ud; int rdtimeout, cotimeout; /* timeouts */ const struct iofns *ops; #ifdef NE_HAVE_SSL ne_ssl_socket ssl; #endif /* The read buffer: ->buffer stores byte which have been read; as * these are consumed and passed back to the caller, bufpos * advances through ->buffer. ->bufavail gives the number of * bytes which remain to be consumed in ->buffer (from ->bufpos), * and is hence always <= RDBUFSIZ. */ char *bufpos; size_t bufavail; #define RDBUFSIZ 4096 char buffer[RDBUFSIZ]; /* Error string. */ char error[192]; }; /* ne_sock_addr represents an Internet address. */ struct ne_sock_addr_s { #ifdef USE_GETADDRINFO struct addrinfo *result, *cursor; #else struct in_addr *addrs; size_t cursor, count; #endif int errnum; }; /* set_error: set socket error string to 'str'. */ #define set_error(s, str) ne_strnzcpy((s)->error, (str), sizeof (s)->error) /* set_strerror: set socket error to system error string for 'errnum' */ #ifdef WIN32 /* Print system error message to given buffer. */ static void print_error(int errnum, char *buffer, size_t buflen) { if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) errnum, 0, buffer, buflen, NULL) == 0) ne_snprintf(buffer, buflen, "Socket error %d", errnum); } #define set_strerror(s, e) print_error((e), (s)->error, sizeof (s)->error) #else /* not WIN32 */ #define set_strerror(s, e) ne_strerror((e), (s)->error, sizeof (s)->error) #endif #ifdef HAVE_OPENSSL /* Seed the SSL PRNG, if necessary; returns non-zero on failure. */ static int seed_ssl_prng(void) { /* Check whether the PRNG has already been seeded. */ if (RAND_status() == 1) return 0; #if defined(EGD_PATH) NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from " EGD_PATH "..."); if (RAND_egd(EGD_PATH) != -1) return 0; #elif defined(ENABLE_EGD) { static const char *paths[] = { "/var/run/egd-pool", "/dev/egd-pool", "/etc/egd-pool", "/etc/entropy" }; size_t n; for (n = 0; n < sizeof(paths) / sizeof(char *); n++) { NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from %s...", paths[n]); if (RAND_egd(paths[n]) != -1) return 0; } } #endif /* EGD_PATH */ NE_DEBUG(NE_DBG_SOCKET, "No entropy source found; could not seed PRNG."); return -1; } #endif /* HAVE_OPENSSL */ #ifdef USE_CHECK_IPV6 static int ipv6_disabled = 0; /* On Linux kernels, IPv6 is typically built as a loadable module, and * socket(AF_INET6, ...) will fail if this module is not loaded, so * the slow AAAA lookups can be avoided for this common case. */ static void init_ipv6(void) { int fd = socket(AF_INET6, SOCK_STREAM, 0); if (fd < 0) ipv6_disabled = 1; else close(fd); } #elif defined(AF_INET6) #define ipv6_disabled (0) #else #define ipv6_disabled (1) #endif /* If init_state is N where > 0, ne_sock_init has been called N times; * if == 0, library is not initialized; if < 0, library initialization * has failed. */ static int init_state = 0; int ne_sock_init(void) { #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; int err; #endif if (init_state > 0) { init_state++; return 0; } else if (init_state < 0) { return -1; } #ifdef WIN32 wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return init_state = -1; } #ifdef HAVE_SSPI if (ne_sspi_init() < 0) { return init_state = -1; } #endif #endif #ifdef NE_HAVE_SOCKS SOCKSinit("neon"); #endif #if defined(HAVE_SIGNAL) //(void) signal(SIGPIPE, SIG_IGN); struct sigaction sa; memset( &sa, 0, sizeof(sa) ); sa.sa_handler = SIG_IGN; sigaction( SIGPIPE, &sa, NULL); #endif #ifdef USE_CHECK_IPV6 init_ipv6(); #endif #ifdef NE_HAVE_SSL if (ne__ssl_init()) { return init_state = -1; } #endif init_state = 1; return 0; } void ne_sock_exit(void) { if (init_state > 0 && --init_state == 0) { #ifdef WIN32 WSACleanup(); #endif #ifdef NE_HAVE_SSL ne__ssl_exit(); #endif #ifdef HAVE_SSPI ne_sspi_deinit(); #endif } } /* Await readability (rdwr = 0) or writability (rdwr != 0) for socket * fd for secs seconds. Returns <0 on error, zero on timeout, >0 if * data is available. */ static int raw_poll(int fdno, int rdwr, int secs) { int ret; #ifdef NE_USE_POLL struct pollfd fds; int time_left = (secs > 0)?(secs):(-1); fds.fd = fdno; fds.events = rdwr == 0 ? POLLIN : POLLOUT; fds.revents = 0; do { ret = poll(&fds, 1, 1000); if( ret < 0 && !NE_ISINTR(ne_errno)){ break; // error } } while (ret <= 0 && --time_left); #else fd_set rdfds, wrfds; struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL); /* Init the fd set */ FD_ZERO(&rdfds); FD_ZERO(&wrfds); /* Note that (amazingly) the FD_SET macro does not expand * correctly on Netware if not inside a compound statement * block. */ if (rdwr == 0) { FD_SET(fdno, &rdfds); } else { FD_SET(fdno, &wrfds); } if (tvp) { tvp->tv_sec = secs; tvp->tv_usec = 0; } do { ret = select(fdno + 1, &rdfds, &wrfds, NULL, tvp); } while (ret < 0 && NE_ISINTR(ne_errno)); #endif return ret; } int ne_sock_block(ne_socket *sock, int n) { if (sock->bufavail) return 0; return sock->ops->readable(sock, n); } /* Cast address object AD to type 'sockaddr_TY' */ #define SACAST(ty, ad) ((struct sockaddr_##ty *)(ad)) ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t buflen) { ssize_t bytes; #if 0 NE_DEBUG(NE_DBG_SOCKET, "buf: at %d, %d avail [%s]", sock->bufpos - sock->buffer, sock->bufavail, sock->bufpos); #endif if (sock->bufavail > 0) { /* Deliver buffered data. */ if (buflen > sock->bufavail) buflen = sock->bufavail; memcpy(buffer, sock->bufpos, buflen); sock->bufpos += buflen; sock->bufavail -= buflen; return buflen; } else if (buflen >= sizeof sock->buffer) { /* No need for read buffer. */ return sock->ops->sread(sock, buffer, buflen); } else { /* Fill read buffer. */ bytes = sock->ops->sread(sock, sock->buffer, sizeof sock->buffer); if (bytes <= 0) return bytes; if (buflen > (size_t)bytes) buflen = bytes; memcpy(buffer, sock->buffer, buflen); sock->bufpos = sock->buffer + buflen; sock->bufavail = bytes - buflen; return buflen; } } ssize_t ne_sock_peek(ne_socket *sock, char *buffer, size_t buflen) { ssize_t bytes; if (sock->bufavail) { /* just return buffered data. */ bytes = sock->bufavail; } else { /* fill the buffer. */ bytes = sock->ops->sread(sock, sock->buffer, sizeof sock->buffer); if (bytes <= 0) return bytes; sock->bufpos = sock->buffer; sock->bufavail = bytes; } if (buflen > (size_t)bytes) buflen = bytes; memcpy(buffer, sock->bufpos, buflen); return buflen; } /* Await data on raw fd in socket. */ static int readable_raw(ne_socket *sock, int secs) { int ret = raw_poll(sock->fd, 0, secs); if (ret < 0) { set_strerror(sock, ne_errno); return NE_SOCK_ERROR; } return (ret == 0) ? NE_SOCK_TIMEOUT : 0; } static ssize_t read_raw(ne_socket *sock, char *buffer, size_t len) { ssize_t ret; ret = readable_raw(sock, sock->rdtimeout); if (ret) return ret; do { ret = recv(sock->fd, buffer, len, 0); } while (ret == -1 && NE_ISINTR(ne_errno)); if (ret == 0) { set_error(sock, _("Connection closed")); ret = NE_SOCK_CLOSED; } else if (ret < 0) { int errnum = ne_errno; ret = NE_ISRESET(errnum) ? NE_SOCK_RESET : NE_SOCK_ERROR; set_strerror(sock, errnum); } return ret; } #define MAP_ERR(e) (NE_ISCLOSED(e) ? NE_SOCK_CLOSED : \ (NE_ISRESET(e) ? NE_SOCK_RESET : NE_SOCK_ERROR)) static ssize_t write_raw(ne_socket *sock, const char *data, size_t length) { ssize_t ret; #ifdef __QNX__ /* Test failures seen on QNX over loopback, if passing large * buffer lengths to send(). */ if (length > 8192) length = 8192; #endif do { // no signal protection #if (defined HAVE_SIGNAL) && (defined MSG_NOSIGNAL) ret = send(sock->fd, data, length, MSG_NOSIGNAL); #else ret = send(sock->fd, data, length, 0); #endif } while (ret == -1 && NE_ISINTR(ne_errno)); if (ret < 0) { int errnum = ne_errno; set_strerror(sock, errnum); return MAP_ERR(errnum); } return ret; } static ssize_t writev_raw(ne_socket *sock, const struct ne_iovec *vector, int count) { ssize_t ret; #ifdef WIN32 LPWSABUF wasvector = (LPWSABUF)ne_malloc(count * sizeof(WSABUF)); DWORD total; int i; for (i = 0; i < count; i++){ wasvector[i].buf = vector[i].base; wasvector[i].len = vector[i].len; } ret = WSASend(sock->fd, wasvector, count, &total, 0, NULL, NULL); if (ret == 0) ret = total; ne_free(wasvector); #else const struct iovec *vec = (const struct iovec *) vector; do { ret = writev(sock->fd, vec, count); } while (ret == -1 && NE_ISINTR(ne_errno)); #endif if (ret < 0) { int errnum = ne_errno; set_strerror(sock, errnum); return MAP_ERR(errnum); } return ret; } #ifdef NE_HAVE_SSL static ssize_t writev_dummy(ne_socket *sock, const struct ne_iovec *vector, int count) { return sock->ops->swrite(sock, vector[0].base, vector[0].len); } #endif static const struct iofns iofns_raw = { read_raw, write_raw, readable_raw, writev_raw }; #ifdef HAVE_OPENSSL /* OpenSSL I/O function implementations. */ static int readable_ossl(ne_socket *sock, int secs) { if (SSL_pending(sock->ssl)) return 0; return readable_raw(sock, secs); } /* SSL error handling, according to SSL_get_error(3). */ static int error_ossl(ne_socket *sock, int sret) { int errnum = SSL_get_error(sock->ssl, sret); unsigned long err; if (errnum == SSL_ERROR_ZERO_RETURN) { set_error(sock, _("Connection closed")); return NE_SOCK_CLOSED; } /* for all other errors, look at the OpenSSL error stack */ err = ERR_get_error(); if (err == 0) { /* Empty error stack, presume this is a system call error: */ if (sret == 0) { /* EOF without close_notify, possible truncation */ set_error(sock, _("Secure connection truncated")); return NE_SOCK_TRUNC; } else { /* Other socket error. */ errnum = ne_errno; set_strerror(sock, errnum); return MAP_ERR(errnum); } } if (ERR_reason_error_string(err)) { ne_snprintf(sock->error, sizeof sock->error, _("SSL error: %s"), ERR_reason_error_string(err)); } else { ne_snprintf(sock->error, sizeof sock->error, _("SSL error code %d/%d/%lu"), sret, errnum, err); } /* make sure the error stack is now empty. */ ERR_clear_error(); return NE_SOCK_ERROR; } /* Work around OpenSSL's use of 'int' rather than 'size_t', to prevent * accidentally passing a negative number, etc. */ #define CAST2INT(n) (((n) > INT_MAX) ? INT_MAX : (n)) static ssize_t read_ossl(ne_socket *sock, char *buffer, size_t len) { int ret; ret = readable_ossl(sock, sock->rdtimeout); if (ret) return ret; ret = SSL_read(sock->ssl, buffer, CAST2INT(len)); if (ret <= 0) ret = error_ossl(sock, ret); return ret; } static ssize_t write_ossl(ne_socket *sock, const char *data, size_t len) { int ret, ilen = CAST2INT(len); ret = SSL_write(sock->ssl, data, ilen); /* ssl.h says SSL_MODE_ENABLE_PARTIAL_WRITE must be enabled to * have SSL_write return < length... so, SSL_write should never * return < length. */ if (ret != ilen) return error_ossl(sock, ret); return ret; } static const struct iofns iofns_ssl = { read_ossl, write_ossl, readable_ossl, writev_dummy }; #elif defined(HAVE_GNUTLS) /* Return zero if an alert value can be ignored. */ static int check_alert(ne_socket *sock, ssize_t ret) { const char *alert; if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED) { alert = gnutls_alert_get_name(gnutls_alert_get(sock->ssl)); NE_DEBUG(NE_DBG_SOCKET, "TLS warning alert: %s", alert); return 0; } else if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { alert = gnutls_alert_get_name(gnutls_alert_get(sock->ssl)); NE_DEBUG(NE_DBG_SOCKET, "TLS fatal alert: %s", alert); return -1; } return ret; } static int readable_gnutls(ne_socket *sock, int secs) { if (gnutls_record_check_pending(sock->ssl)) { return 0; } return readable_raw(sock, secs); } static ssize_t error_gnutls(ne_socket *sock, ssize_t sret) { ssize_t ret; switch (sret) { case 0: ret = NE_SOCK_CLOSED; set_error(sock, _("Connection closed")); break; case GNUTLS_E_FATAL_ALERT_RECEIVED: ret = NE_SOCK_ERROR; ne_snprintf(sock->error, sizeof sock->error, _("SSL alert received: %s"), gnutls_alert_get_name(gnutls_alert_get(sock->ssl))); break; case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: /* It's not exactly an API guarantee but this error will * always mean a premature EOF. */ ret = NE_SOCK_TRUNC; set_error(sock, _("Secure connection truncated")); break; case GNUTLS_E_PUSH_ERROR: ret = NE_SOCK_RESET; set_error(sock, ("SSL socket write failed")); break; case GNUTLS_E_PULL_ERROR: ret = NE_SOCK_RESET; set_error(sock, _("SSL socket read failed")); break; default: ret = NE_SOCK_ERROR; ne_snprintf(sock->error, sizeof sock->error, _("SSL error: %s"), gnutls_strerror(sret)); } return ret; } #define RETRY_GNUTLS(sock, ret) ((ret < 0) \ && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN \ || check_alert(sock, ret) == 0)) static ssize_t read_gnutls(ne_socket *sock, char *buffer, size_t len) { ssize_t ret; unsigned reneg = 1; /* number of allowed rehandshakes */ ret = readable_gnutls(sock, sock->rdtimeout); if (ret) return ret; do { do { ret = gnutls_record_recv(sock->ssl, buffer, len); } while (RETRY_GNUTLS(sock, ret)); } while (ret == GNUTLS_E_REHANDSHAKE && reneg-- && (ret = gnutls_handshake(sock->ssl)) == GNUTLS_E_SUCCESS); if (ret <= 0) ret = error_gnutls(sock, ret); return ret; } static ssize_t write_gnutls(ne_socket *sock, const char *data, size_t len) { ssize_t ret; do { ret = gnutls_record_send(sock->ssl, data, len); } while (RETRY_GNUTLS(sock, ret)); if (ret < 0) return error_gnutls(sock, ret); return ret; } static const struct iofns iofns_ssl = { read_gnutls, write_gnutls, readable_gnutls, writev_dummy }; #endif int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t len) { ssize_t ret; do { ret = sock->ops->swrite(sock, data, len); if (ret > 0) { data += ret; len -= ret; } } while (ret > 0 && len > 0); return ret < 0 ? ret : 0; } int ne_sock_fullwritev(ne_socket *sock, const struct ne_iovec *vector, int count) { ssize_t ret; do { ret = sock->ops->swritev(sock, vector, count); if (ret > 0) { while (count && (size_t)ret >= vector[0].len) { ret -= vector[0].len; count--; vector++; } if (ret && count) { /* Partial buffer sent; send the rest. */ ret = ne_sock_fullwrite(sock, (char *)vector[0].base + ret, vector[0].len - ret); count--; vector++; } } } while (count && ret >= 0); return ret < 0 ? ret : 0; } ssize_t ne_sock_readline(ne_socket *sock, char *buf, size_t buflen) { char *lf; size_t len; if(!sock) return NE_SOCK_CLOSED; if ((lf = memchr(sock->bufpos, '\n', sock->bufavail)) == NULL && sock->bufavail < RDBUFSIZ) { /* The buffered data does not contain a complete line: move it * to the beginning of the buffer. */ if (sock->bufavail) memmove(sock->buffer, sock->bufpos, sock->bufavail); sock->bufpos = sock->buffer; /* Loop filling the buffer whilst no newline is found in the data * buffered so far, and there is still buffer space available */ do { /* Read more data onto end of buffer. */ ssize_t ret = sock->ops->sread(sock, sock->buffer + sock->bufavail, RDBUFSIZ - sock->bufavail); if (ret < 0) return ret; sock->bufavail += ret; } while ((lf = memchr(sock->buffer, '\n', sock->bufavail)) == NULL && sock->bufavail < RDBUFSIZ); } if (lf) len = lf - sock->bufpos + 1; else len = buflen; /* fall into "line too long" error... */ if ((len + 1) > buflen) { set_error(sock, _("Line too long")); return NE_SOCK_ERROR; } memcpy(buf, sock->bufpos, len); buf[len] = '\0'; /* consume the line from buffer: */ sock->bufavail -= len; sock->bufpos += len; return len; } ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t buflen) { ssize_t len; while (buflen > 0) { len = ne_sock_read(sock, buffer, buflen); if (len < 0) return len; buflen -= len; buffer += len; } return 0; } #ifndef INADDR_NONE #define INADDR_NONE ((in_addr_t) -1) #endif #if !defined(USE_GETADDRINFO) && !defined(WIN32) && !HAVE_DECL_H_ERRNO /* Ancient versions of netdb.h don't export h_errno. */ extern int h_errno; #endif /* This implemementation does not attempt to support IPv6 using * gethostbyname2 et al. */ ne_sock_addr *ne_addr_resolve(const char *hostname, int flags) { ne_sock_addr *addr = ne_calloc(sizeof *addr); #ifdef USE_GETADDRINFO struct addrinfo hints = {0}; char *pnt; hints.ai_socktype = SOCK_STREAM; #ifdef AF_INET6 if (hostname[0] == '[' && ((pnt = strchr(hostname, ']')) != NULL)) { char *hn = ne_strdup(hostname + 1); hn[pnt - hostname - 1] = '\0'; #ifdef AI_NUMERICHOST /* added in the RFC2553 API */ hints.ai_flags = AI_NUMERICHOST; #endif hints.ai_family = AF_INET6; addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result); ne_free(hn); } else #endif /* AF_INET6 */ { #ifdef USE_GAI_ADDRCONFIG /* added in the RFC3493 API */ hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_UNSPEC; addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result); #else hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC; addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result); #endif } #else /* Use gethostbyname() */ in_addr_t laddr; struct hostent *hp; laddr = inet_addr(hostname); if (laddr == INADDR_NONE) { hp = gethostbyname(hostname); if (hp == NULL) { #ifdef WIN32 addr->errnum = WSAGetLastError(); #else addr->errnum = h_errno; #endif } else if (hp->h_length != sizeof(struct in_addr)) { /* fail gracefully if somebody set RES_USE_INET6 */ addr->errnum = NO_RECOVERY; } else { size_t n; /* count addresses */ for (n = 0; hp->h_addr_list[n] != NULL; n++) /* noop */; addr->count = n; addr->addrs = ne_malloc(n * sizeof *addr->addrs); for (n = 0; n < addr->count; n++) memcpy(&addr->addrs[n], hp->h_addr_list[n], hp->h_length); } } else { addr->addrs = ne_malloc(sizeof *addr->addrs); addr->count = 1; memcpy(addr->addrs, &laddr, sizeof *addr->addrs); } #endif return addr; } int ne_addr_result(const ne_sock_addr *addr) { return addr->errnum; } const ne_inet_addr *ne_addr_first(ne_sock_addr *addr) { #ifdef USE_GETADDRINFO addr->cursor = addr->result->ai_next; return addr->result; #else addr->cursor = 0; return &addr->addrs[0]; #endif } const ne_inet_addr *ne_addr_next(ne_sock_addr *addr) { #ifdef USE_GETADDRINFO struct addrinfo *ret = addr->cursor; if (addr->cursor) addr->cursor = addr->cursor->ai_next; #else struct in_addr *ret; if (++addr->cursor < addr->count) ret = &addr->addrs[addr->cursor]; else ret = NULL; #endif return ret; } char *ne_addr_error(const ne_sock_addr *addr, char *buf, size_t bufsiz) { #ifdef WIN32 print_error(addr->errnum, buf, bufsiz); #else const char *err; #ifdef USE_GETADDRINFO /* override horrible generic "Name or service not known" error. */ if (addr->errnum == EAI_NONAME) err = _("Host not found"); else err = gai_strerror(addr->errnum); #elif defined(HAVE_HSTRERROR) err = hstrerror(addr->errnum); #else err = _("Host not found"); #endif ne_strnzcpy(buf, err, bufsiz); #endif /* WIN32 */ return buf; } char *ne_iaddr_print(const ne_inet_addr *ia, char *buf, size_t bufsiz) { #if defined(USE_GETADDRINFO) && defined(HAVE_INET_NTOP) const char *ret; #ifdef AF_INET6 if (ia->ai_family == AF_INET6) { struct sockaddr_in6 *in6 = SACAST(in6, ia->ai_addr); ret = inet_ntop(AF_INET6, &in6->sin6_addr, buf, bufsiz); } else #endif if (ia->ai_family == AF_INET) { struct sockaddr_in *in = SACAST(in, ia->ai_addr); ret = inet_ntop(AF_INET, &in->sin_addr, buf, bufsiz); } else ret = NULL; if (ret == NULL) ne_strnzcpy(buf, "[IP address]", bufsiz); #elif defined(USE_GETADDRINFO) && defined(NI_NUMERICHOST) /* use getnameinfo instead for Win32, which lacks inet_ntop: */ if (getnameinfo(ia->ai_addr, ia->ai_addrlen, buf, bufsiz, NULL, 0, NI_NUMERICHOST)) ne_strnzcpy(buf, "[IP address]", bufsiz); #else /* USE_GETADDRINFO */ ne_strnzcpy(buf, inet_ntoa(*ia), bufsiz); #endif return buf; } unsigned char *ne_iaddr_raw(const ne_inet_addr *ia, unsigned char *buf) { #ifdef USE_GETADDRINFO #ifdef AF_INET6 if (ia->ai_family == AF_INET6) { struct sockaddr_in6 *in6 = SACAST(in6, ia->ai_addr); return memcpy(buf, in6->sin6_addr.s6_addr, sizeof in6->sin6_addr.s6_addr); } else #endif /* AF_INET6 */ { struct sockaddr_in *in = SACAST(in, ia->ai_addr); return memcpy(buf, &in->sin_addr.s_addr, sizeof in->sin_addr.s_addr); } #else /* !USE_GETADDRINFO */ return memcpy(buf, &ia->s_addr, sizeof ia->s_addr); #endif } ne_inet_addr *ne_iaddr_parse(const char *addr, ne_iaddr_type type) { #if defined(USE_GETADDRINFO) && defined(HAVE_INET_PTON) char dst[sizeof(struct in6_addr)]; int af = type == ne_iaddr_ipv6 ? AF_INET6 : AF_INET; if (inet_pton(af, addr, dst) != 1) { return NULL; } return ne_iaddr_make(type, (unsigned char *)dst); #elif defined(USE_GETADDRINFO) && !defined(HAVE_INET_PTON) /* For Windows, which lacks inet_pton(). */ struct addrinfo *ai, *rv, hints; memset(&hints, 0, sizeof hints); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; hints.ai_family = type == ne_iaddr_ipv6 ? AF_INET6 : AF_INET; if (getaddrinfo(addr, NULL, &hints, &ai)) { return NULL; } /* Copy the returned addrinfo, since it needs to be ne_free()-able * later; must only call freeaddrinfo() on ai. */ rv = ne_calloc(sizeof *rv); memcpy(rv, ai, sizeof *rv); rv->ai_next = NULL; rv->ai_canonname = NULL; rv->ai_addr = ne_calloc(ai->ai_addrlen); memcpy(rv->ai_addr, ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai); return rv; #else /* !USE_GETADDRINFO */ struct in_addr a; if (type == ne_iaddr_ipv6) { return NULL; } #ifdef WIN32 /* inet_addr() is broken because INADDR_NONE is a valid * broadcast address, so only use it on Windows. */ a.s_addr = inet_addr(addr); if (a.s_addr == INADDR_NONE) { return NULL; } #else /* !WIN32 */ if (inet_aton(addr, &a) == 0) { return NULL; } #endif return ne_iaddr_make(ne_iaddr_ipv4, (unsigned char *)&a.s_addr); #endif /* !USE_GETADDRINFO */ } int ne_iaddr_reverse(const ne_inet_addr *ia, char *buf, size_t bufsiz) { #ifdef USE_GETADDRINFO return getnameinfo(ia->ai_addr, ia->ai_addrlen, buf, bufsiz, NULL, 0, 0); #else struct hostent *hp; hp = gethostbyaddr(ia, sizeof *ia, AF_INET); if (hp && hp->h_name) { ne_strnzcpy(buf, hp->h_name, bufsiz); return 0; } return -1; #endif } void ne_addr_destroy(ne_sock_addr *addr) { #ifdef USE_GETADDRINFO if (addr->result) freeaddrinfo(addr->result); #else if (addr->addrs) ne_free(addr->addrs); #endif ne_free(addr); } /* Perform a connect() for given fd, handling EINTR retries. Returns * zero on success or -1 on failure, in which case, ne_errno is set * appropriately. */ static int raw_connect(int fd, const struct sockaddr *sa, size_t salen) { int ret; do { ret = connect(fd, sa, salen); } while (ret < 0 && NE_ISINTR(ne_errno)); return ret; } /* Perform a connect() for fd to address sa of length salen, with a * timeout if supported on this platform. Returns zero on success or * NE_SOCK_* on failure, with sock->error set appropriately. */ static int timed_connect(ne_socket *sock, int fd, const struct sockaddr *sa, size_t salen) { int ret; #ifdef USE_NONBLOCKING_CONNECT if (sock->cotimeout) { int errnum, flags; /* Get flags and then set O_NONBLOCK. */ flags = fcntl(fd, F_GETFL); if (flags & O_NONBLOCK) { /* This socket was created using SOCK_NONBLOCK... flip the * bit for restoring flags later. */ flags &= ~O_NONBLOCK; } else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { set_strerror(sock, errno); return NE_SOCK_ERROR; } ret = raw_connect(fd, sa, salen); if (ret == -1) { errnum = ne_errno; if (NE_ISINPROGRESS(errnum)) { ret = raw_poll(fd, 1, sock->cotimeout); if (ret > 0) { /* poll got data */ socklen_t len = sizeof(errnum); /* Check whether there is a pending error for the * socket. Per Stevens UNPv1§15.4, Solaris will * return a pending error via errno by failing the * getsockopt() call. */ errnum = 0; if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &errnum, &len)) errnum = errno; if (errnum == 0) { ret = 0; } else { set_strerror(sock, errnum); ret = NE_SOCK_ERROR; } } else if (ret == 0) { /* poll timed out */ set_error(sock, _("Connection timed out")); ret = NE_SOCK_TIMEOUT; } else /* poll failed */ { set_strerror(sock, errno); ret = NE_SOCK_ERROR; } } else /* non-EINPROGRESS error from connect() */ { set_strerror(sock, errnum); ret = NE_SOCK_ERROR; } } /* Reset to old flags: */ if (fcntl(fd, F_SETFL, flags) == -1) { set_strerror(sock, errno); ret = NE_SOCK_ERROR; } } else #endif /* USE_NONBLOCKING_CONNECT */ { ret = raw_connect(fd, sa, salen); if (ret < 0) { set_strerror(sock, errno); ret = NE_SOCK_ERROR; } } return ret; } /* Connect socket to address 'addr' on given 'port'. Returns zero on * success or NE_SOCK_* on failure with sock->error set * appropriately. */ static int connect_socket(ne_socket *sock, int fd, const ne_inet_addr *addr, unsigned int port) { #ifdef USE_GETADDRINFO #ifdef AF_INET6 /* fill in the _family field for AIX 4.3, which forgets to do so. */ if (addr->ai_family == AF_INET6) { struct sockaddr_in6 in6; memcpy(&in6, addr->ai_addr, sizeof in6); in6.sin6_port = port; in6.sin6_family = AF_INET6; return timed_connect(sock, fd, (struct sockaddr *)&in6, sizeof in6); } else #endif if (addr->ai_family == AF_INET) { struct sockaddr_in in; memcpy(&in, addr->ai_addr, sizeof in); in.sin_port = port; in.sin_family = AF_INET; return timed_connect(sock, fd, (struct sockaddr *)&in, sizeof in); } else { set_strerror(sock, EINVAL); return NE_SOCK_ERROR; } #else struct sockaddr_in sa = {0}; sa.sin_family = AF_INET; sa.sin_port = port; sa.sin_addr = *addr; return timed_connect(sock, fd, (struct sockaddr *)&sa, sizeof sa); #endif } ne_socket *ne_sock_create(void) { ne_socket *sock = ne_calloc(sizeof *sock); sock->rdtimeout = SOCKET_READ_TIMEOUT; sock->cotimeout = 0; sock->bufpos = sock->buffer; sock->ops = &iofns_raw; sock->fd = -1; return sock; } #ifdef USE_GETADDRINFO #define ia_family(a) ((a)->ai_family) #define ia_proto(a) ((a)->ai_protocol) #else #define ia_family(a) AF_INET #define ia_proto(a) 0 #endif void ne_sock_prebind(ne_socket *sock, const ne_inet_addr *addr, unsigned int port) { sock->lport = port; sock->laddr = addr ? addr : &dummy_laddr; } /* Bind socket 'fd' to address/port 'addr' and 'port', for subsequent * connect() to address of family 'peer_family'. */ static int do_bind(int fd, int peer_family, const ne_inet_addr *addr, unsigned int port) { #if defined(HAVE_SETSOCKOPT) && defined(SO_REUSEADDR) && defined(SOL_SOCKET) { int flag = 1; (void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof flag); /* An error here is not fatal, so ignore it. */ } #endif #if defined(USE_GETADDRINFO) && defined(AF_INET6) /* Use a sockaddr_in6 if an AF_INET6 local address is specifed, or * if no address is specified and the peer address is AF_INET6: */ if ((addr != &dummy_laddr && addr->ai_family == AF_INET6) || (addr == &dummy_laddr && peer_family == AF_INET6)) { struct sockaddr_in6 in6; if (addr == &dummy_laddr) memset(&in6, 0, sizeof in6); else memcpy(&in6, addr->ai_addr, sizeof in6); in6.sin6_port = htons(port); /* fill in the _family field for AIX 4.3, which forgets to do so. */ in6.sin6_family = AF_INET6; return bind(fd, (struct sockaddr *)&in6, sizeof in6); } else #endif { struct sockaddr_in in; if (addr == &dummy_laddr) memset(&in, 0, sizeof in); else { #ifdef USE_GETADDRINFO memcpy(&in, addr->ai_addr, sizeof in); #else in.sin_addr = *addr; #endif } in.sin_port = htons(port); in.sin_family = AF_INET; return bind(fd, (struct sockaddr *)&in, sizeof in); } } #ifdef SOCK_CLOEXEC /* sock_cloexec is initialized to SOCK_CLOEXEC and cleared to zero if * a socket() call ever fails with EINVAL. */ static int sock_cloexec = SOCK_CLOEXEC; #define RETRY_ON_EINVAL #else #define sock_cloexec 0 #endif int ne_sock_connect(ne_socket *sock, const ne_inet_addr *addr, unsigned int port) { int fd, ret; int type = SOCK_STREAM | sock_cloexec; #if defined(RETRY_ON_EINVAL) && defined(SOCK_NONBLOCK) \ && defined(USE_NONBLOCKING_CONNECT) /* If the SOCK_NONBLOCK flag is defined, and the retry-on-EINVAL * logic is enabled, and the socket has a configured timeout, then * also use the SOCK_NONBLOCK flag to save enabling O_NONBLOCK * later. */ if (sock->cotimeout && sock_cloexec) { type |= SOCK_NONBLOCK; } #endif /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo * implementations do not set ai_socktype, e.g. RHL6.2. */ fd = socket(ia_family(addr), type, ia_proto(addr)); #ifdef RETRY_ON_EINVAL /* Handle forwards compat for new glibc on an older kernels; clear * the sock_cloexec flag and retry the call: */ if (fd < 0 && sock_cloexec && errno == EINVAL) { sock_cloexec = 0; fd = socket(ia_family(addr), SOCK_STREAM, ia_proto(addr)); } #endif if (fd < 0) { set_strerror(sock, ne_errno); return -1; } #if !defined(NE_USE_POLL) && !defined(WIN32) if (fd > FD_SETSIZE) { ne_close(fd); set_error(sock, _("Socket descriptor number exceeds FD_SETSIZE")); return NE_SOCK_ERROR; } #endif #if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) \ && defined(FD_CLOEXEC) /* Set the FD_CLOEXEC bit for the new fd, if the socket was not * created with the CLOEXEC bit already set. */ if (!sock_cloexec && (ret = fcntl(fd, F_GETFD)) >= 0) { fcntl(fd, F_SETFD, ret | FD_CLOEXEC); /* ignore failure; not a critical error. */ } #endif if (sock->laddr && (sock->laddr == &dummy_laddr || ia_family(sock->laddr) == ia_family(addr))) { ret = do_bind(fd, ia_family(addr), sock->laddr, sock->lport); if (ret < 0) { int errnum = errno; ne_close(fd); set_strerror(sock, errnum); return NE_SOCK_ERROR; } } #if defined(HAVE_SETSOCKOPT) && (defined(TCP_NODELAY) || defined(WIN32)) { /* Disable the Nagle algorithm. */ int flag = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag); } #endif ret = connect_socket(sock, fd, addr, htons(port)); if (ret == 0) sock->fd = fd; else ne_close(fd); return ret; } ne_inet_addr *ne_sock_peer(ne_socket *sock, unsigned int *port) { union saun { struct sockaddr sa; struct sockaddr_in sin; #if defined(USE_GETADDRINFO) && defined(AF_INET6) struct sockaddr_in6 sin6; #endif } saun; socklen_t len = sizeof saun; ne_inet_addr *ia; struct sockaddr *sad = (struct sockaddr *)&saun; if (getpeername(sock->fd, sad, &len) != 0) { set_strerror(sock, errno); return NULL; } #if !defined(USE_GETADDRINFO) || !defined(AF_INET6) if (sad->sa_family != AF_INET) { set_error(sock, _("Socket family not supported")); return NULL; } #endif ia = ne_calloc(sizeof *ia); #ifdef USE_GETADDRINFO ia->ai_addr = ne_malloc(sizeof *ia); ia->ai_addrlen = len; memcpy(ia->ai_addr, sad, len); ia->ai_family = saun.sa.sa_family; #else memcpy(ia, &saun.sin.sin_addr.s_addr, sizeof *ia); #endif #if defined(USE_GETADDRINFO) && defined(AF_INET6) *port = ntohs(saun.sa.sa_family == AF_INET ? saun.sin.sin_port : saun.sin6.sin6_port); #else *port = ntohs(saun.sin.sin_port); #endif return ia; } ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw) { ne_inet_addr *ia; #if !defined(AF_INET6) || !defined(USE_GETADDRINFO) /* fail if IPv6 address is given if IPv6 is not supported. */ if (type == ne_iaddr_ipv6) return NULL; #endif ia = ne_calloc(sizeof *ia); #ifdef USE_GETADDRINFO /* ai_protocol and ai_socktype aren't used by connect_socket() so * ignore them here. (for now) */ if (type == ne_iaddr_ipv4) { struct sockaddr_in *in4 = ne_calloc(sizeof *in4); ia->ai_family = AF_INET; ia->ai_addr = (struct sockaddr *)in4; ia->ai_addrlen = sizeof *in4; in4->sin_family = AF_INET; memcpy(&in4->sin_addr.s_addr, raw, sizeof in4->sin_addr.s_addr); } #ifdef AF_INET6 else { struct sockaddr_in6 *in6 = ne_calloc(sizeof *in6); ia->ai_family = AF_INET6; ia->ai_addr = (struct sockaddr *)in6; ia->ai_addrlen = sizeof *in6; in6->sin6_family = AF_INET6; memcpy(&in6->sin6_addr, raw, sizeof in6->sin6_addr.s6_addr); } #endif #else /* !USE_GETADDRINFO */ memcpy(&ia->s_addr, raw, sizeof ia->s_addr); #endif return ia; } ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia) { #if defined(USE_GETADDRINFO) && defined(AF_INET6) return ia->ai_family == AF_INET6 ? ne_iaddr_ipv6 : ne_iaddr_ipv4; #else return ne_iaddr_ipv4; #endif } int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2) { #ifdef USE_GETADDRINFO if (i1->ai_family != i2->ai_family) return i2->ai_family - i1->ai_family; if (i1->ai_family == AF_INET) { struct sockaddr_in *in1 = SACAST(in, i1->ai_addr), *in2 = SACAST(in, i2->ai_addr); return memcmp(&in1->sin_addr.s_addr, &in2->sin_addr.s_addr, sizeof in1->sin_addr.s_addr); } #ifdef AF_INET6 else if (i1->ai_family == AF_INET6) { struct sockaddr_in6 *in1 = SACAST(in6, i1->ai_addr), *in2 = SACAST(in6, i2->ai_addr); return memcmp(in1->sin6_addr.s6_addr, in2->sin6_addr.s6_addr, sizeof in1->sin6_addr.s6_addr); } #endif /* AF_INET6 */ else return -1; #else return memcmp(&i1->s_addr, &i2->s_addr, sizeof i1->s_addr); #endif /* USE_GETADDRINFO */ } void ne_iaddr_free(ne_inet_addr *addr) { #ifdef USE_GETADDRINFO ne_free(addr->ai_addr); #endif ne_free(addr); } int ne_sock_accept(ne_socket *sock, int listener) { int fd = accept(listener, NULL, NULL); if (fd < 0) return -1; sock->fd = fd; return 0; } int ne_sock_fd(const ne_socket *sock) { return sock->fd; } void ne_sock_read_timeout(ne_socket *sock, int timeout) { sock->rdtimeout = timeout; } void ne_sock_connect_timeout(ne_socket *sock, int timeout) { sock->cotimeout = timeout; } #ifdef NE_HAVE_SSL #ifdef HAVE_GNUTLS /* Dumb server session cache implementation for GNUTLS; holds a single * session. */ /* Copy datum 'src' to 'dest'. */ static void copy_datum(gnutls_datum *dest, gnutls_datum *src) { dest->size = src->size; dest->data = memcpy(gnutls_malloc(src->size), src->data, src->size); } /* Callback to store a session 'data' with id 'key'. */ static int store_sess(void *userdata, gnutls_datum key, gnutls_datum data) { ne_ssl_context *ctx = userdata; if (ctx->cache.server.key.data) { gnutls_free(ctx->cache.server.key.data); gnutls_free(ctx->cache.server.data.data); } copy_datum(&ctx->cache.server.key, &key); copy_datum(&ctx->cache.server.data, &data); return 0; } /* Returns non-zero if d1 and d2 are the same datum. */ static int match_datum(gnutls_datum *d1, gnutls_datum *d2) { return d1->size == d2->size && memcmp(d1->data, d2->data, d1->size) == 0; } /* Callback to retrieve a session of id 'key'. */ static gnutls_datum retrieve_sess(void *userdata, gnutls_datum key) { ne_ssl_context *ctx = userdata; gnutls_datum ret = { NULL, 0 }; if (match_datum(&ctx->cache.server.key, &key)) { copy_datum(&ret, &ctx->cache.server.data); } return ret; } /* Callback to remove a session of id 'key'; stub needed but * implementation seems unnecessary. */ static int remove_sess(void *userdata, gnutls_datum key) { return -1; } #endif int ne_sock_accept_ssl(ne_socket *sock, ne_ssl_context *ctx) { int ret; ne_ssl_socket ssl; #if defined(HAVE_OPENSSL) ssl = SSL_new(ctx->ctx); SSL_set_fd(ssl, sock->fd); sock->ssl = ssl; ret = SSL_accept(ssl); if (ret != 1) { return error_ossl(sock, ret); } if (SSL_session_reused(ssl)) { NE_DEBUG(NE_DBG_SSL, "ssl: Server reused session."); } #elif defined(HAVE_GNUTLS) gnutls_init(&ssl, GNUTLS_SERVER); gnutls_credentials_set(ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred); gnutls_set_default_priority(ssl); /* Set up dummy session cache. */ gnutls_db_set_store_function(ssl, store_sess); gnutls_db_set_retrieve_function(ssl, retrieve_sess); gnutls_db_set_remove_function(ssl, remove_sess); gnutls_db_set_ptr(ssl, ctx); if (ctx->verify) gnutls_certificate_server_set_request(ssl, GNUTLS_CERT_REQUEST); sock->ssl = ssl; gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr)(long)sock->fd); ret = gnutls_handshake(ssl); if (ret < 0) { return error_gnutls(sock, ret); } if (ctx->verify && gnutls_certificate_verify_peers(ssl)) { set_error(sock, _("Client certificate verification failed")); return NE_SOCK_ERROR; } #endif sock->ops = &iofns_ssl; return 0; } int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata) { int ret = -1; #if defined(HAVE_OPENSSL) SSL *ssl; if (seed_ssl_prng()) { set_error(sock, _("SSL disabled due to lack of entropy")); return NE_SOCK_ERROR; } /* If runtime library version differs from compile-time version * number in major/minor/fix level, abort soon. */ // disabled -> harmfull in case of version mismatch /* if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & 0xFFFFF000) { set_error(sock, _("SSL disabled due to library version mismatch")); return NE_SOCK_ERROR; }*/ sock->ssl = ssl = SSL_new(ctx->ctx); if (!ssl) { set_error(sock, _("Could not create SSL structure")); return NE_SOCK_ERROR; } // check sock->fd, if it's blocking set to non-blocking just for SSL_conect long old_flags, new_flags = 0; time_t timeout; if (sock->cotimeout) timeout = time(0) + sock->cotimeout; // keep the old flags so we can reset them later new_flags = old_flags = fcntl(sock->fd, F_GETFL); if(!(new_flags & O_NONBLOCK)){ new_flags |= O_NONBLOCK; if(fcntl(sock->fd, F_SETFL, new_flags) == -1){ set_strerror(sock, errno); return NE_SOCK_ERROR; } } SSL_set_app_data(ssl, userdata); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); SSL_set_fd(ssl, sock->fd); sock->ops = &iofns_ssl; #ifdef SSL_set_tlsext_host_name if (ctx->hostname) { /* Try to enable SNI, but ignore failure (should only fail for * >255 char hostnames, which are probably not legal * anyway). */ if (SSL_set_tlsext_host_name(ssl, ctx->hostname) != 1) { ERR_clear_error(); } } #endif if (ctx->sess) SSL_set_session(ssl, ctx->sess); /* ret = SSL_connect(ssl); if (ret != 1) { error_ossl(sock, ret); SSL_free(ssl); sock->ssl = NULL; return NE_SOCK_ERROR; } */ // non-blocking SSL handshake int ready = 0; int expired = 0; int errsv = 0; struct timeval tv; while((ret = SSL_connect(ssl)) != 1){ fd_set fds; FD_ZERO(&fds); FD_SET(sock->fd, &fds); do{ tv.tv_sec = 1; tv.tv_usec = 0; switch(SSL_get_error(ssl, ret)){ case SSL_ERROR_WANT_WRITE: ready = select(sock->fd +1, NULL, &fds, NULL, &tv); break; case SSL_ERROR_WANT_READ: ready = select(sock->fd +1, &fds, NULL, NULL, &tv); break; case SSL_ERROR_WANT_X509_LOOKUP: ready = select(sock->fd +1, &fds, &fds, NULL, &tv); break; case SSL_ERROR_NONE: case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_ACCEPT: case SSL_ERROR_SYSCALL: break; case SSL_ERROR_SSL:{ int ssl_err_code = ERR_get_error(); char* ssl_err_message = ERR_reason_error_string(ssl_err_code); ERR_clear_error(); set_error(sock, _(ssl_err_message)); return NE_SOCK_ERROR; } default: set_error(sock, _("Unknown error during SSL handshake")); return NE_SOCK_ERROR; } if(ready == -1) errsv = errno; if(time(0) > timeout){ expired = 1; break; } }while((ready == 0) || (errsv == EINTR) || (errsv == EWOULDBLOCK)); // loop until there is something in the socket or timed out if(expired){ error_ossl(sock, ret); SSL_free(ssl); sock->ssl = NULL; set_error(sock, _("Connection timed out during SSL handshake")); return NE_SOCK_ERROR; } } // reset flags if needed if(new_flags != old_flags){ if(fcntl(sock->fd, F_SETFL, old_flags) == -1){ set_strerror(sock, errno); return NE_SOCK_ERROR; } } #elif defined(HAVE_GNUTLS) /* DH and RSA params are set in ne_ssl_context_create */ gnutls_init(&sock->ssl, GNUTLS_CLIENT); gnutls_set_default_priority(sock->ssl); gnutls_session_set_ptr(sock->ssl, userdata); gnutls_credentials_set(sock->ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred); #ifdef HAVE_GNUTLS_SIGN_CALLBACK_SET if (ctx->sign_func) gnutls_sign_callback_set(sock->ssl, ctx->sign_func, ctx->sign_data); #endif if (ctx->hostname) { gnutls_server_name_set(sock->ssl, GNUTLS_NAME_DNS, ctx->hostname, strlen(ctx->hostname)); } gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr)(long)sock->fd); if (ctx->cache.client.data) { #if defined(HAVE_GNUTLS_SESSION_GET_DATA2) gnutls_session_set_data(sock->ssl, ctx->cache.client.data, ctx->cache.client.size); #else gnutls_session_set_data(sock->ssl, ctx->cache.client.data, ctx->cache.client.len); #endif } sock->ops = &iofns_ssl; do { ret = gnutls_handshake(sock->ssl); } while (RETRY_GNUTLS(sock, ret)); if (ret < 0) { error_gnutls(sock, ret); return NE_SOCK_ERROR; } if (!gnutls_session_is_resumed(sock->ssl)) { /* New session. The old method of using the _get_data * function seems to be broken with 1.3.0 and later*/ #if defined(HAVE_GNUTLS_SESSION_GET_DATA2) gnutls_session_get_data2(sock->ssl, &ctx->cache.client); #else ctx->cache.client.len = 0; if (gnutls_session_get_data(sock->ssl, NULL, &ctx->cache.client.len) == 0) { ctx->cache.client.data = ne_malloc(ctx->cache.client.len); gnutls_session_get_data(sock->ssl, ctx->cache.client.data, &ctx->cache.client.len); } #endif } #endif return 0; } ne_ssl_socket ne__sock_sslsock(ne_socket *sock) { return sock->ssl; } #endif int ne_sock_sessid(ne_socket *sock, unsigned char *buf, size_t *buflen) { #ifdef NE_HAVE_SSL #ifdef HAVE_GNUTLS if (sock->ssl) { return gnutls_session_get_id(sock->ssl, buf, buflen); } else { return -1; } #else SSL_SESSION *sess; if (!sock->ssl) { return -1; } sess = SSL_get0_session(sock->ssl); if (!buf) { *buflen = sess->session_id_length; return 0; } if (*buflen < sess->session_id_length) { return -1; } *buflen = sess->session_id_length; memcpy(buf, sess->session_id, *buflen); return 0; #endif #else return -1; #endif } char *ne_sock_cipher(ne_socket *sock) { #ifdef NE_HAVE_SSL if (sock->ssl) { #ifdef HAVE_OPENSSL const char *name = SSL_get_cipher(sock->ssl); return ne_strdup(name); #elif defined(HAVE_GNUTLS) const char *name = gnutls_cipher_get_name(gnutls_cipher_get(sock->ssl)); return ne_strdup(name); #endif } else #endif /* NE_HAVE_SSL */ { return NULL; } } const char *ne_sock_error(const ne_socket *sock) { return sock->error; } void ne_sock_set_error(ne_socket *sock, const char *format, ...) { va_list params; va_start(params, format); ne_vsnprintf(sock->error, sizeof sock->error, format, params); va_end(params); } int ne_sock_close(ne_socket *sock) { int ret; /* Per API description - for an SSL connection, simply send the * close_notify but do not wait for the peer's response. */ #if defined(HAVE_OPENSSL) if (sock->ssl) { SSL_shutdown(sock->ssl); SSL_free(sock->ssl); } #elif defined(HAVE_GNUTLS) if (sock->ssl) { do { ret = gnutls_bye(sock->ssl, GNUTLS_SHUT_WR); } while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)); gnutls_deinit(sock->ssl); } #endif if (sock->fd < 0) ret = 0; else ret = ne_close(sock->fd); ne_free(sock); return ret; } davix-R_0_5_0/deps/libneon/src/ne_socket.h000066400000000000000000000275441257152637300205740ustar00rootroot00000000000000/* socket handling interface Copyright (C) 1999-2010, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_SOCKET_H #define NE_SOCKET_H #include #ifdef WIN32 #include /* for size_t */ #endif #include "ne_defs.h" #include "ne_ssl.h" /* for ne_ssl_context */ NE_BEGIN_DECLS #define NE_SOCK_ERROR (-1) /* Read/Write timed out */ #define NE_SOCK_TIMEOUT (-2) /* Socket was closed */ #define NE_SOCK_CLOSED (-3) /* Connection was reset (e.g. server crashed) */ #define NE_SOCK_RESET (-4) /* Secure connection was closed without proper SSL shutdown. */ #define NE_SOCK_TRUNC (-5) /* ne_socket represents a TCP socket. */ typedef struct ne_socket_s ne_socket; /* ne_sock_addr represents an address object. */ typedef struct ne_sock_addr_s ne_sock_addr; #ifndef NE_INET_ADDR_DEFINED typedef struct ne_inet_addr_s ne_inet_addr; #endif /* Perform process-global initialization of any libraries in use. * Returns non-zero on error. */ int ne_sock_init(void); /* Perform process-global shutdown of any libraries in use. This * function only has effect when it has been called an equal number of * times to ne_sock_init() for the process. */ void ne_sock_exit(void); /* Resolve the given hostname. 'flags' must be zero. Hex * string IPv6 addresses (e.g. `::1') may be enclosed in brackets * (e.g. `[::1]'). */ ne_sock_addr *ne_addr_resolve(const char *hostname, int flags); /* Returns zero if name resolution was successful, non-zero on * error. */ int ne_addr_result(const ne_sock_addr *addr); /* Returns the first network address associated with the 'addr' * object. Undefined behaviour if ne_addr_result returns non-zero for * 'addr'; otherwise, never returns NULL. */ const ne_inet_addr *ne_addr_first(ne_sock_addr *addr); /* Returns the next network address associated with the 'addr' object, * or NULL if there are no more. */ const ne_inet_addr *ne_addr_next(ne_sock_addr *addr); /* NB: the pointers returned by ne_addr_first and ne_addr_next are * valid until ne_addr_destroy is called for the corresponding * ne_sock_addr object. They must not be passed to ne_iaddr_free. */ /* If name resolution fails, copies the error string into 'buffer', * which is of size 'bufsiz'. 'buffer' is returned. */ char *ne_addr_error(const ne_sock_addr *addr, char *buffer, size_t bufsiz); /* Destroys an address object created by ne_addr_resolve. */ void ne_addr_destroy(ne_sock_addr *addr); /* Network address type; IPv4 or IPv6 */ typedef enum { ne_iaddr_ipv4 = 0, ne_iaddr_ipv6 } ne_iaddr_type; /* Create a network address object from raw byte representation (in * network byte order) of given type. 'raw' must be four bytes for an * IPv4 address, 16 bytes for an IPv6 address. May return NULL if * address type is not supported. */ ne_inet_addr *ne_iaddr_make(ne_iaddr_type type, const unsigned char *raw); /* Compare two network address objects i1 and i2; returns zero if they * are equivalent or non-zero otherwise. */ int ne_iaddr_cmp(const ne_inet_addr *i1, const ne_inet_addr *i2); /* Return the type of the given network address object. */ ne_iaddr_type ne_iaddr_typeof(const ne_inet_addr *ia); /* Print the string representation of network address 'ia' into the * buffer 'buffer', which is of length 'bufsiz'. Returns 'buffer'. */ char *ne_iaddr_print(const ne_inet_addr *ia, char *buffer, size_t bufsiz); /* Dump the raw byte representation (in network byte order) of address * 'ia' into the buffer 'buffer', which must be of a suitable length * (4 bytes for an IPv4 address, 16 bytes for an IPv6 address). * Returns 'buffer'. */ unsigned char *ne_iaddr_raw(const ne_inet_addr *ia, unsigned char *buffer); /* Perform the reverse name lookup on network address 'ia', placing * the returned name in the 'buf' buffer (of length 'bufsiz') if * successful. Returns zero on success, or non-zero on error. */ int ne_iaddr_reverse(const ne_inet_addr *ia, char *buf, size_t bufsiz); /* Convert network address string 'addr' (for example, "127.0.0.1") * into a network address object. Returns NULL on parse error. If * non-NULL, return value must be freed using ne_iaddr_free. */ ne_inet_addr *ne_iaddr_parse(const char *addr, ne_iaddr_type type); /* Destroy a network address object created using ne_iaddr_make or * ne_iaddr_parse. */ void ne_iaddr_free(ne_inet_addr *addr); /* Create a socket object; returns NULL on error. */ ne_socket *ne_sock_create(void); /* Specify an address to which the local end of the socket will be * bound during a subsequent ne_sock_connect() call. If the address * passed to ne_sock_connect() is of a different type (family) to * 'addr', 'addr' is ignored. Either 'addr' may be NULL, to use the * given port with unspecified address, or 'port' may be 0, to use the * given address with an unspecified port. * * (Note: This function is not equivalent to a BSD socket bind(), it * only takes effect during the _connect() call). */ void ne_sock_prebind(ne_socket *sock, const ne_inet_addr *addr, unsigned int port); /* Connect the socket to server at address 'addr' on port 'port'. * Returns zero on success, NE_SOCK_TIMEOUT if a timeout occurs when a * non-zero connect timeout is configured (and is supported), or * NE_SOCK_ERROR on failure. */ int ne_sock_connect(ne_socket *sock, const ne_inet_addr *addr, unsigned int port); /* Read up to 'count' bytes from socket into 'buffer'. Returns: * NE_SOCK_* on error, * >0 length of data read into buffer (may be less than 'count') */ ssize_t ne_sock_read(ne_socket *sock, char *buffer, size_t count); /* Read up to 'count' bytes into 'buffer', leaving the data available * in the socket buffer to be returned by a subsequent call to * ne_sock_read or ne_sock_peek. Returns: * NE_SOCK_* on error, * >0 length of data read into buffer. */ ssize_t ne_sock_peek(ne_socket *sock, char *buffer, size_t count); /* Block for up to 'n' seconds until data becomes available for reading * from the socket. Returns: * NE_SOCK_* on error, * NE_SOCK_TIMEOUT if no data arrives in 'n' seconds, * 0 if data arrived on the socket. */ int ne_sock_block(ne_socket *sock, int n); /* Write 'count' bytes of 'data' to the socket. Guarantees to either * write all the bytes or to fail. Returns 0 on success, or NE_SOCK_* * on error. */ int ne_sock_fullwrite(ne_socket *sock, const char *data, size_t count); /* I/O vector. */ struct ne_iovec { void *base; size_t len; }; /* Writes 'count' blocks described by 'vector' to the socket. * Guarantees to either write all the bytes or to fail. Count must be * greater than zero and smaller than the system-defined maximum * vector limit. Returns 0 on success, or NE_SOCK_* on error. */ int ne_sock_fullwritev(ne_socket *sock, const struct ne_iovec *vector, int count); /* Read an LF-terminated line into 'buffer', and NUL-terminate it. * At most 'len' bytes are read (including the NUL terminator). * Returns: * NE_SOCK_* on error, * >0 number of bytes read (including NUL terminator) */ ssize_t ne_sock_readline(ne_socket *sock, char *buffer, size_t len); /* Read exactly 'len' bytes into buffer, or fail; returns 0 on * success, NE_SOCK_* on error. */ ssize_t ne_sock_fullread(ne_socket *sock, char *buffer, size_t len); /* Accepts a connection from listening socket 'fd' and places the * socket in 'sock'. Returns zero on success or -1 on failure. */ int ne_sock_accept(ne_socket *sock, int fd); /* Returns the file descriptor used for socket 'sock'. */ int ne_sock_fd(const ne_socket *sock); /* Return address of peer, or NULL on error. The returned address * must be destroyed by caller using ne_iaddr_free. */ ne_inet_addr *ne_sock_peer(ne_socket *sock, unsigned int *port); /* Close the socket and destroy the socket object. If SSL is in use * for the socket, a closure alert is sent to initiate a clean * shutdown, but this function does not wait for the peer's response. * Returns zero on success, or non-zero on failure. */ int ne_sock_close(ne_socket *sock); /* Return current error string for socket. */ const char *ne_sock_error(const ne_socket *sock); /* Set the error string for the socket; takes printf-like format * string. */ void ne_sock_set_error(ne_socket *sock, const char *format, ...) ne_attribute((format (printf, 2, 3))); /* Set read timeout for socket, in seconds; must be a non-zero * positive integer. */ void ne_sock_read_timeout(ne_socket *sock, int timeout); /* Set connect timeout for socket, in seconds; must be a positive * integer. If a timeout of 'zero' is used then then no explicit * timeout handling will be used for ne_sock_connect(), and the * connect call will only timeout as dictated by the TCP stack. */ void ne_sock_connect_timeout(ne_socket *sock, int timeout); /* Negotiate an SSL connection on socket as an SSL server, using given * SSL context. */ int ne_sock_accept_ssl(ne_socket *sock, ne_ssl_context *ctx); /* Negotiate an SSL connection on socket as an SSL client, using given * SSL context. The 'userdata' parameter is associated with the * underlying SSL library's socket structure for use in callbacks. * Returns zero on success, or non-zero on error. */ int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata); /* Retrieve the session ID of the current SSL session. If 'buf' is * non-NULL, on success, copies at most *buflen bytes to 'buf' and * sets *buflen to the exact number of bytes copied. If 'buf' is * NULL, on success, sets *buflen to the length of the session ID. * Returns zero on success, non-zero on error. */ int ne_sock_sessid(ne_socket *sock, unsigned char *buf, size_t *buflen); /* Return human-readable name of SSL/TLS cipher used for connection, * or NULL if none. The format of this string is not intended to be * fixed or parseable, but is informational only. Return value is * NUL-terminated malloc-allocated string if not NULL, which must be * freed by the caller. */ char *ne_sock_cipher(ne_socket *sock); /* SOCKS proxy protocol version: */ enum ne_sock_sversion { NE_SOCK_SOCKSV4 = 0, NE_SOCK_SOCKSV4A, NE_SOCK_SOCKSV5 }; /* Given a socket 'sock' which is connected to a SOCKS proxy, initiate * a connection to a destination server using that proxy, specified * either by network address or hostname, at given port 'port'. * * If 'vers' is NE_SOCKS_V4, addr must be an IPv4 address; hostname * and password are ignored; username must be non-NULL. * * If 'vers' is NE_SOCKS_V4A, hostname must be non-NULL; addr is * ignored; password is ignored; username must be non-NULL. * * If 'vers' is NE_SOCKS_V5, addr may be NULL, in which case hostname * must be non-NULL. addr if non-NULL may be an IPv4 or IPv6 address; * username may be NULL, in which case password is ignored. If * username is non-NULL password must also be non-NULL. * * Returns 0 on success, or NE_SOCK_* on failure - in which case, the * socket error string is set. On failure, the socket must be closed * by the caller. */ int ne_sock_proxy(ne_socket *sock, enum ne_sock_sversion vers, const ne_inet_addr *addr, const char *hostname, unsigned int port, const char *username, const char *password); NE_END_DECLS #endif /* NE_SOCKET_H */ davix-R_0_5_0/deps/libneon/src/ne_socks.c000066400000000000000000000233311257152637300204070ustar00rootroot00000000000000/* SOCKS proxy support for neon Copyright (C) 2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include "ne_internal.h" #include "ne_string.h" #include "ne_socket.h" #include "ne_utils.h" #include /* SOCKS protocol reference: v4: http://www.ufasoft.com/doc/socks4_protocol.htm v4a http://www.smartftp.com/Products/SmartFTP/RFC/socks4a.protocol v5: http://tools.ietf.org/html/rfc1928 ...v5 auth: http://tools.ietf.org/html/rfc1929 */ #define V5_REPLY_OK 0 #define V5_REPLY_FAIL 1 #define V5_REPLY_DISALLOW 2 #define V5_REPLY_NET_UNREACH 3 #define V5_REPLY_HOST_UNREACH 4 #define V5_REPLY_CONN_REFUSED 5 #define V5_REPLY_TTL_EXPIRED 6 #define V5_REPLY_CMD_UNSUPPORTED 7 #define V5_REPLY_TYPE_UNSUPPORTED 8 #define V5_VERSION 0x05 #define V5_ADDR_IPV4 0x01 #define V5_ADDR_FQDN 0x03 #define V5_ADDR_IPV6 0x04 #define V5_CMD_CONNECT 0x01 #define V5_AUTH_NONE 0x00 #define V5_AUTH_USER 0x02 #define V5_AUTH_NOMETH 0xFF /* Fail with given V5 error code in given context. */ static int v5fail(ne_socket *sock, unsigned int code, const char *context) { const char *err; switch (code) { case V5_REPLY_FAIL: err = _("failure"); break; case V5_REPLY_DISALLOW: err = _("connection not permitted"); break; case V5_REPLY_NET_UNREACH: err = _("network unreachable"); break; case V5_REPLY_HOST_UNREACH: err = _("host unreachable"); break; case V5_REPLY_TTL_EXPIRED: err = _("TTL expired"); break; case V5_REPLY_CMD_UNSUPPORTED: err = _("command not supported"); break; case V5_REPLY_TYPE_UNSUPPORTED: err = _("address type not supported"); break; default: ne_sock_set_error(sock, _("%s: unrecognized error (%u)"), context, code); return NE_SOCK_ERROR; } ne_sock_set_error(sock, "%s: %s", context, err); return NE_SOCK_ERROR; } /* Fail with given error string. */ static int fail(ne_socket *sock, const char *error) { ne_sock_set_error(sock, "%s", error); return NE_SOCK_ERROR; } /* Fail with given NE_SOCK_* error code and given context. */ static int sofail(ne_socket *sock, ssize_t ret, const char *context) { char *err = ne_strdup(ne_sock_error(sock)); ne_sock_set_error(sock, "%s: %s", context, err); ne_free(err); return NE_SOCK_ERROR; } /* SOCKSv5 proxy. */ static int v5_proxy(ne_socket *sock, const ne_inet_addr *addr, const char *hostname, unsigned int port, const char *username, const char *password) { unsigned char msg[1024], *p; unsigned int len; int ret; ssize_t n; p = msg; *p++ = V5_VERSION; *p++ = 2; /* Two supported auth protocols; none and user. */ *p++ = V5_AUTH_NONE; *p++ = V5_AUTH_USER; ret = ne_sock_fullwrite(sock, (char *)msg, p - msg); if (ret) { return sofail(sock, ret, _("Could not send message to proxy")); } n = ne_sock_fullread(sock, (char *)msg, 2); if (n) { return sofail(sock, ret, _("Could not read initial response from proxy")); } else if (msg[0] != V5_VERSION) { return fail(sock, _("Invalid version in proxy response")); } /* Authenticate, if necessary. */ switch (msg[1]) { case V5_AUTH_NONE: break; case V5_AUTH_USER: p = msg; *p++ = 0x01; len = strlen(username) & 0xff; *p++ = len; memcpy(p, username, len); p += len; len = strlen(password) & 0xff; *p++ = len; memcpy(p, password, len); p += len; ret = ne_sock_fullwrite(sock, (char *)msg, p - msg); if (ret) { return sofail(sock, ret, _("Could not send login message")); } n = ne_sock_fullread(sock, (char *)msg, 2); if (n) { return sofail(sock, ret, _("Could not read login reply")); } else if (msg[0] != 1) { return fail(sock, _("Invalid version in login reply")); } else if (msg[1] != 0) { return fail(sock, _("Authentication failed")); } break; case V5_AUTH_NOMETH: return fail(sock, _("No acceptable authentication method")); default: return fail(sock, _("Unexpected authentication method chosen")); } /* Send the CONNECT command. */ p = msg; *p++ = V5_VERSION; *p++ = V5_CMD_CONNECT; *p++ = 0; /* reserved */ if (addr) { unsigned char raw[16]; if (ne_iaddr_typeof(addr) == ne_iaddr_ipv4) { len = 4; *p++ = V5_ADDR_IPV4; } else { len = 16; *p++ = V5_ADDR_IPV6; } memcpy(p, ne_iaddr_raw(addr, raw), len); p += len; } else { len = strlen(hostname) & 0xff; *p++ = V5_ADDR_FQDN; *p++ = len; memcpy(p, hostname, len); p += len; } *p++ = (port >> 8) & 0xff; *p++ = port & 0xff; ret = ne_sock_fullwrite(sock, (char *)msg, p - msg); if (ret) { return sofail(sock, ret, _("Could not send connect request")); } n = ne_sock_fullread(sock, (char *)msg, 4); if (n) { return sofail(sock, n, _("Could not read connect reply")); } if (msg[0] != V5_VERSION) { return fail(sock, _("Invalid version in connect reply")); } if (msg[1] != V5_REPLY_OK) { return v5fail(sock, msg[1], _("Could not connect")); } switch (msg[3]) { case V5_ADDR_IPV4: len = 4; break; case V5_ADDR_IPV6: len = 16; break; case V5_ADDR_FQDN: n = ne_sock_read(sock, (char *)msg, 1); if (n != 1) { return sofail(sock, n, _("Could not read FQDN length in connect reply")); } len = msg[0]; break; default: return fail(sock, _("Unknown address type in connect reply")); } n = ne_sock_fullread(sock, (char *)msg, len + 2); if (n) { return sofail(sock, n, _("Could not read address in connect reply")); } return 0; } #define V4_VERSION 0x04 #define V4_CMD_STREAM 0x01 #define V4_REP_OK 0x5a /* request granted */ #define V4_REP_FAIL 0x5b /* request rejected or failed */ #define V4_REP_NOIDENT 0x5c /* request failed, could connect to identd */ #define V4_REP_IDFAIL 0x5d /* request failed, identd denial */ /* Fail for given SOCKSv4 error code. */ static int v4fail(ne_socket *sock, unsigned int code, const char *context) { const char *err; switch (code) { case V4_REP_FAIL: err = _("request rejected or failed"); break; case V4_REP_NOIDENT: err = _("could not establish connection to identd"); break; case V4_REP_IDFAIL: err = _("rejected due to identd user mismatch"); break; default: ne_sock_set_error(sock, _("%s: unrecognized failure (%u)"), context, code); return NE_SOCK_ERROR; } ne_sock_set_error(sock, "%s: %s", context, err); return NE_SOCK_ERROR; } /* SOCKS v4 or v4A proxy. */ static int v4_proxy(ne_socket *sock, enum ne_sock_sversion vers, const ne_inet_addr *addr, const char *hostname, unsigned int port, const char *username) { unsigned char msg[1024], raw[16], *p; ssize_t n; int ret; p = msg; *p++ = V4_VERSION; *p++ = V4_CMD_STREAM; *p++ = (port >> 8) & 0xff; *p++ = port & 0xff; if (vers == NE_SOCK_SOCKSV4A) { /* A bogus address is used to signify use of the hostname, * 0.0.0.X where X != 0. */ memcpy(p, "\x00\x00\x00\xff", 4); } else { /* API precondition that addr is IPv4; if it's not this will * just copy out the first four bytes of the v6 address; * garbage in => garbage out. */ memcpy(p, ne_iaddr_raw(addr, raw), 4); } p += 4; if (username) { unsigned int len = strlen(username) & 0xff; memcpy(p, username, len); p += len; } *p++ = '\0'; if (vers == NE_SOCK_SOCKSV4A) { unsigned int len = strlen(hostname) & 0xff; memcpy(p, hostname, len); p += len; *p++ = '\0'; } ret = ne_sock_fullwrite(sock, (char *)msg, p - msg); if (ret) { return sofail(sock, ret, _("Could not send message to proxy")); } n = ne_sock_fullread(sock, (char *)msg, 8); if (n) { return sofail(sock, ret, _("Could not read response from proxy")); } if (msg[1] != V4_REP_OK) { return v4fail(sock, ret, _("Could not connect")); } return 0; } int ne_sock_proxy(ne_socket *sock, enum ne_sock_sversion vers, const ne_inet_addr *addr, const char *hostname, unsigned int port, const char *username, const char *password) { if (vers == NE_SOCK_SOCKSV5) { return v5_proxy(sock, addr, hostname, port, username, password); } else { return v4_proxy(sock, vers, addr, hostname, port, username); } } davix-R_0_5_0/deps/libneon/src/ne_ssl.h000066400000000000000000000206671257152637300201040ustar00rootroot00000000000000/* SSL/TLS abstraction layer for neon Copyright (C) 2003-2006, 2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* ne_ssl.h defines an interface for loading and accessing the * properties of SSL certificates. */ #ifndef NE_SSL_H #define NE_SSL_H 1 #include #include "ne_defs.h" NE_BEGIN_DECLS /// /* A "distinguished name"; a unique name for some entity. */ typedef struct ne_ssl_dname_s ne_ssl_dname; /* Returns a single-line string representation of a distinguished * name, intended to be human-readable (e.g. "Acme Ltd., Norfolk, * GB"). Return value is a UTF-8-encoded malloc-allocated string and * must be free'd by the caller. */ char *ne_ssl_readable_dname(const ne_ssl_dname *dn); /* Returns zero if 'dn1' and 'dn2' refer to same name, or non-zero if * they are different. */ int ne_ssl_dname_cmp(const ne_ssl_dname *dn1, const ne_ssl_dname *dn2); /* An SSL certificate. */ typedef struct ne_ssl_certificate_s ne_ssl_certificate; /* Read a certificate from a file in PEM format; returns NULL if the * certificate could not be parsed. */ ne_ssl_certificate *ne_ssl_cert_read(const char *filename); /* Write a certificate to a file in PEM format; returns non-zero if * the certificate could not be written. */ int ne_ssl_cert_write(const ne_ssl_certificate *cert, const char *filename); /* Export a certificate to a base64-encoded, NUL-terminated string. * The returned string is malloc-allocated and must be free()d by the * caller. */ char *ne_ssl_cert_export(const ne_ssl_certificate *cert); /* Import a certificate from a base64-encoded string as returned by * ne_ssl_cert_export(). Returns a certificate object or NULL if * 'data' was not valid. */ ne_ssl_certificate *ne_ssl_cert_import(const char *data); /* Returns the identity of the certificate, or NULL if none is given. * For a server certificate this will be the hostname of the server to * which the cert was issued. A NUL-terminated UTF-8-encoded string * is returned, which is valid for the lifetime of the certificate * object. */ const char *ne_ssl_cert_identity(const ne_ssl_certificate *cert); /* Return the certificate of the entity which signed certificate * 'cert'. Returns NULL if 'cert' is self-signed or the issuer * certificate is not available; if non-NULL, the pointer is valid for * the lifetime of the certificate object. */ const ne_ssl_certificate *ne_ssl_cert_signedby(const ne_ssl_certificate *cert); /* Returns the distinguished name of the certificate issuer. */ const ne_ssl_dname *ne_ssl_cert_issuer(const ne_ssl_certificate *cert); /* Returns the distinguished name of the certificate subject. */ const ne_ssl_dname *ne_ssl_cert_subject(const ne_ssl_certificate *cert); #define NE_SSL_DIGESTLEN (60) /* Calculate the certificate digest ("fingerprint") and format it as a * NUL-terminated hex string in 'digest', of the form "aa:bb:...:ff". * Returns zero on success or non-zero if there was an internal error * whilst calculating the digest. 'digest' must be at least * NE_SSL_DIGESTLEN bytes in length. */ int ne_ssl_cert_digest(const ne_ssl_certificate *cert, char *digest); /* Copy the validity times for the certificate 'cert' into 'from' and * 'until' (either may be NULL). If the time cannot be represented by * a time_t value, then (time_t)-1 will be written. */ void ne_ssl_cert_validity_time(const ne_ssl_certificate *cert, time_t *from, time_t *until); #define NE_SSL_VDATELEN (30) /* Copy the validity times into buffers 'from' and 'until' as * NUL-terminated human-readable strings, using RFC 1123-style date * formatting (and not localized, so always using English month/week * names). The buffers must be at least NE_SSL_VDATELEN bytes in * length, and either may be NULL. */ void ne_ssl_cert_validity(const ne_ssl_certificate *cert, char *from, char *until); /* Returns zero if 'c1' and 'c2' refer to the same certificate, or * non-zero otherwise. */ int ne_ssl_cert_cmp(const ne_ssl_certificate *c1, const ne_ssl_certificate *c2); /* Deallocate memory associated with certificate. */ void ne_ssl_cert_free(ne_ssl_certificate *cert); /* A client certificate (and private key). A client certificate * object has state; the object is either in the "encrypted" or * "decrypted" state. */ typedef struct ne_ssl_client_cert_s ne_ssl_client_cert; /* Read a client certificate and private key from a PKCS12 file; * returns NULL if the file could not be parsed, or otherwise * returning a client certificate object. The returned object may be * in either the encrypted or decrypted state. */ ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename); /* Returns non-zero if client cert is in the encrypted state. */ int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *ccert); /* * Load client certificate from PEM files **/ ne_ssl_client_cert *ne_ssl_clicert_pem_read(const char* pkey, const char* cred, const char* password); /* Duplicate a client certificate object * Must be in a decrypted state */ ne_ssl_client_cert *ne_ssl_dup_client_cert(const ne_ssl_client_cert *cc); /* Returns the "friendly name" given for the client cert, or NULL if * none given. Returns a NUL-terminated, UTF-8-encoded string. This * function may be used on a ccert object in either encrypted or * decrypted state. */ const char *ne_ssl_clicert_name(const ne_ssl_client_cert *ccert); /* Decrypt the encrypted client cert using the given password. * Returns non-zero on failure, in which case, the ccert object * remains in the encrypted state and the function may be called again * with a different password. This function has undefined behaviour * for a ccert object which is in the decrypted state. */ int ne_ssl_clicert_decrypt(ne_ssl_client_cert *ccert, const char *password); /* Return the actual certificate part of the client certificate (never * returns NULL). This function has undefined behaviour for a ccert * object which is in the encrypted state. */ const ne_ssl_certificate *ne_ssl_clicert_owner(const ne_ssl_client_cert *ccert); /* Destroy a client certificate object. This function may be used on * a ccert object in either the encrypted or decrypted state. */ void ne_ssl_clicert_free(ne_ssl_client_cert *ccert); /* SSL context object. The interfaces to manipulate an SSL context * are only needed when interfacing directly with ne_socket.h. */ typedef struct ne_ssl_context_s ne_ssl_context; /* Context creation modes: */ #define NE_SSL_CTX_CLIENT (0) /* client context */ #define NE_SSL_CTX_SERVER (1) /* default server context */ #define NE_SSL_CTX_SERVERv2 (2) /* SSLv2-specific server context */ ne_ssl_context *ne_ssl_context_create(int mode); /* Client mode: trust the given certificate 'cert' in context 'ctx'. */ void ne_ssl_context_trustcert(ne_ssl_context *ctx, const ne_ssl_certificate *cert); /* trust all the CA certificate contained in the directory dir for this ssl context */ int ne_ssl_context_trust_add_ca_path(ne_ssl_context * ctx, const char* path); /* Server mode: use given cert and key (filenames to PEM certificates). */ int ne_ssl_context_keypair(ne_ssl_context *ctx, const char *cert, const char *key); /* Server mode: set client cert verification options: required is non-zero if * a client cert is required, if ca_names is non-NULL it is a filename containing * a set of PEM certs from which CA names are sent in the ccert request. */ int ne_ssl_context_set_verify(ne_ssl_context *ctx, int required, const char *ca_names, const char *verify_cas); #define NE_SSL_CTX_SSLv2 (0) /* Set a flag for the SSL context. */ void ne_ssl_context_set_flag(ne_ssl_context *ctx, int flag, int value); /* Destroy an SSL context. */ void ne_ssl_context_destroy(ne_ssl_context *ctx); NE_END_DECLS #endif davix-R_0_5_0/deps/libneon/src/ne_sspi.c000066400000000000000000000422151257152637300202450ustar00rootroot00000000000000/* Microsoft SSPI based authentication routines Copyright (C) 2004-2005, Vladimir Berezniker @ http://public.xdi.org/=vmpn Copyright (C) 2007, Yves Martin This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include "ne_utils.h" #include "ne_string.h" #include "ne_socket.h" #include "ne_sspi.h" #ifdef HAVE_SSPI #define SEC_SUCCESS(Status) ((Status) >= 0) #ifndef SECURITY_ENTRYPOINT /* Missing in MingW 3.7 */ #define SECURITY_ENTRYPOINT "InitSecurityInterfaceA" #endif struct SSPIContextStruct { CtxtHandle context; char *serverName; CredHandle credentials; int continueNeeded; int authfinished; char *mechanism; int ntlm; ULONG maxTokenSize; }; typedef struct SSPIContextStruct SSPIContext; static ULONG negotiateMaxTokenSize = 0; static ULONG ntlmMaxTokenSize = 0; static HINSTANCE hSecDll = NULL; static PSecurityFunctionTable pSFT = NULL; static int initialized = 0; /* * Query specified package for it's maximum token size. */ static int getMaxTokenSize(char *package, ULONG * maxTokenSize) { SECURITY_STATUS status; SecPkgInfo *packageSecurityInfo = NULL; status = pSFT->QuerySecurityPackageInfo(package, &packageSecurityInfo); if (status == SEC_E_OK) { *maxTokenSize = packageSecurityInfo->cbMaxToken; if (pSFT->FreeContextBuffer(packageSecurityInfo) != SEC_E_OK) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unable to free security package info."); } } else { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: QuerySecurityPackageInfo [failed] [%x].", status); return -1; } return 0; } /* * Initialize all the SSPI data */ static void initDll(HINSTANCE hSecDll) { INIT_SECURITY_INTERFACE initSecurityInterface = NULL; initSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSecDll, SECURITY_ENTRYPOINT); if (initSecurityInterface == NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Obtaining security interface [fail].\n"); initialized = -1; return; } else { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Obtaining security interface [ok].\n"); } pSFT = (initSecurityInterface) (); if (pSFT == NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Security Function Table [fail]."); initialized = -2; return; } else { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Security Function Table [ok]."); } if (getMaxTokenSize("Negotiate", &negotiateMaxTokenSize)) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unable to get negotiate maximum packet size"); initialized = -3; } if (getMaxTokenSize("NTLM", &ntlmMaxTokenSize)) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unable to get negotiate maximum packet size"); initialized = -3; } } /* * This function needs to be called at least once before using any other. */ int ne_sspi_init(void) { if (initialized) { return 0; } NE_DEBUG(NE_DBG_SOCKET, "sspiInit"); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Loading security dll."); hSecDll = LoadLibrary("security.dll"); if (hSecDll == NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Loading of security dll [fail]."); } else { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Loading of security dll [ok]."); initDll(hSecDll); if (initialized == 0) { initialized = 1; } } NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: sspiInit [%d].", initialized); if (initialized < 0) { return initialized; } else { return 0; } } /* * This function can be called to free resources used by SSPI. */ int ne_sspi_deinit(void) { NE_DEBUG(NE_DBG_SOCKET, "sspi: DeInit"); if (initialized <= 0) { return initialized; } pSFT = NULL; if (hSecDll != NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unloading security dll."); if (FreeLibrary(hSecDll)) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unloading of security dll [ok].\n"); } else { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unloading of security dll [fail].\n"); return -1; } hSecDll = NULL; } initialized = 0; return 0; } /* * Simplification wrapper arround AcquireCredentialsHandle as most of * the parameters do not change. */ static int acquireCredentialsHandle(CredHandle * credentials, char *package) { SECURITY_STATUS status; TimeStamp timestamp; status = pSFT->AcquireCredentialsHandle(NULL, package, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, credentials, ×tamp); if (status != SEC_E_OK) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: AcquireCredentialsHandle [fail] [%x].\n", status); return -1; } return 0; } /* * Wrapper arround initializeSecurityContext. Supplies several * default parameters as well as logging in case of errors. */ static SECURITY_STATUS initializeSecurityContext(CredHandle * credentials, CtxtHandle * context, char *spn, ULONG contextReq, SecBufferDesc * inBuffer, CtxtHandle * newContext, SecBufferDesc * outBuffer) { ULONG contextAttributes; SECURITY_STATUS status; status = pSFT->InitializeSecurityContext(credentials, context, spn, contextReq, 0, SECURITY_NETWORK_DREP, inBuffer, 0, newContext, outBuffer, &contextAttributes, NULL); if (!SEC_SUCCESS(status)) { if (status == SEC_E_INVALID_TOKEN) { NE_DEBUG(NE_DBG_HTTPAUTH, "InitializeSecurityContext [fail] SEC_E_INVALID_TOKEN.\n"); } else if (status == SEC_E_UNSUPPORTED_FUNCTION) { NE_DEBUG(NE_DBG_HTTPAUTH, "InitializeSecurityContext [fail] SEC_E_UNSUPPORTED_FUNCTION.\n"); } else { NE_DEBUG(NE_DBG_HTTPAUTH, "InitializeSecurityContext [fail] [%x].\n", status); } } return status; } /* * Validates that the pointer is not NULL and converts it to its real type. */ static int getContext(void *context, SSPIContext **sspiContext) { if (!context) { return -1; } *sspiContext = context; return 0; } /* * Verifies that the buffer descriptor point only to one buffer and * returns the pointer to it. */ static int getSingleBufferDescriptor(SecBufferDesc *secBufferDesc, SecBuffer **secBuffer) { if (secBufferDesc->cBuffers != 1) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: fillBufferDescriptor " "[fail] numbers of descriptor buffers. 1 != [%d].\n", secBufferDesc->cBuffers); return -1; } *secBuffer = secBufferDesc->pBuffers; return 0; } /* * Decodes BASE64 string into SSPI SecBuffer */ static int base64ToBuffer(const char *token, SecBufferDesc * secBufferDesc) { SecBuffer *buffer; if (getSingleBufferDescriptor(secBufferDesc, &buffer)) { return -1; } buffer->BufferType = SECBUFFER_TOKEN; buffer->cbBuffer = ne_unbase64(token, (unsigned char **) &buffer->pvBuffer); if (buffer->cbBuffer == 0) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Unable to decode BASE64 SSPI token.\n"); return -1; } return 0; } /* * Creates a SecBuffer of a specified size. */ static int makeBuffer(SecBufferDesc * secBufferDesc, ULONG size) { SecBuffer *buffer; if (getSingleBufferDescriptor(secBufferDesc, &buffer)) { return -1; } buffer->BufferType = SECBUFFER_TOKEN; buffer->cbBuffer = size; buffer->pvBuffer = ne_calloc(size); return 0; } /* * Frees data allocated in the buffer. */ static int freeBuffer(SecBufferDesc * secBufferDesc) { SecBuffer *buffer; if (getSingleBufferDescriptor(secBufferDesc, &buffer)) { return -1; } if (buffer->cbBuffer > 0 && buffer->pvBuffer) { ne_free(buffer->pvBuffer); buffer->cbBuffer = 0; buffer->pvBuffer = NULL; } return 0; } /* * Canonicalize a server host name if possible. * The returned pointer must be freed after usage. */ static char *canonical_hostname(const char *serverName) { char *hostname; ne_sock_addr *addresses; /* DNS resolution. It would be useful to be able to use the * AI_CANONNAME flag where getaddrinfo() is available, but the * reverse-lookup is sufficient and simpler. */ addresses = ne_addr_resolve(serverName, 0); if (ne_addr_result(addresses)) { /* Lookup failed */ char buf[256]; NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Could not resolve IP address for `%s': %s\n", serverName, ne_addr_error(addresses, buf, sizeof buf)); hostname = ne_strdup(serverName); } else { char hostbuffer[256]; const ne_inet_addr *address = ne_addr_first(addresses); if (ne_iaddr_reverse(address, hostbuffer, sizeof hostbuffer) == 0) { hostname = ne_strdup(hostbuffer); } else { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Could not resolve host name" "from IP address for `%s'\n", serverName); hostname = ne_strdup(serverName); } } ne_addr_destroy(addresses); return hostname; } /* * Create a context to authenticate to specified server, using either * ntlm or negotiate. */ int ne_sspi_create_context(void **context, char *serverName, int ntlm) { SSPIContext *sspiContext; char *canonicalName; if (initialized <= 0) { return -1; } sspiContext = ne_calloc(sizeof(SSPIContext)); sspiContext->continueNeeded = 0; if (ntlm) { sspiContext->mechanism = "NTLM"; sspiContext->serverName = ne_strdup(serverName); sspiContext->maxTokenSize = ntlmMaxTokenSize; } else { sspiContext->mechanism = "Negotiate"; /* Canonicalize to conform to GSSAPI behavior */ canonicalName = canonical_hostname(serverName); sspiContext->serverName = ne_concat("HTTP/", canonicalName, NULL); ne_free(canonicalName); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Created context with SPN '%s'", sspiContext->serverName); sspiContext->maxTokenSize = negotiateMaxTokenSize; } sspiContext->ntlm = ntlm; sspiContext->authfinished = 0; *context = sspiContext; return 0; } /* * Resets the context */ static void resetContext(SSPIContext * sspiContext) { pSFT->DeleteSecurityContext(&(sspiContext->context)); #if defined(_MSC_VER) && _MSC_VER <= 1200 pSFT->FreeCredentialHandle(&(sspiContext->credentials)); #else pSFT->FreeCredentialsHandle(&(sspiContext->credentials)); #endif sspiContext->continueNeeded = 0; } /* * Initializes supplied SecBufferDesc to point to supplied SecBuffer * that is also initialized; */ static void initSingleEmptyBuffer(SecBufferDesc * bufferDesc, SecBuffer * buffer) { buffer->BufferType = SECBUFFER_EMPTY; buffer->cbBuffer = 0; buffer->pvBuffer = NULL; bufferDesc->cBuffers = 1; bufferDesc->ulVersion = SECBUFFER_VERSION; bufferDesc->pBuffers = buffer; } /* * Destroyes the supplied context. */ int ne_sspi_destroy_context(void *context) { int status; SSPIContext *sspiContext; if (initialized <= 0) { return -1; } status = getContext(context, &sspiContext); if (status) { return status; } resetContext(sspiContext); if (sspiContext->serverName) { ne_free(sspiContext->serverName); sspiContext->serverName = NULL; } ne_free(sspiContext); return 0; } int ne_sspi_clear_context(void *context) { int status; SSPIContext *sspiContext; if (initialized <= 0) { return -1; } status = getContext(context, &sspiContext); if (status) { return status; } sspiContext->authfinished = 0; return 0; } /* * Processes received authentication tokens as well as supplies the * response token. */ int ne_sspi_authenticate(void *context, const char *base64Token, char **responseToken) { SecBufferDesc outBufferDesc; SecBuffer outBuffer; int status; SECURITY_STATUS securityStatus; ULONG contextFlags; SSPIContext *sspiContext; if (initialized <= 0) { return -1; } status = getContext(context, &sspiContext); if (status) { return status; } /* TODO: Not sure what flags should be set. joe: this needs to be * driven by the ne_auth interface; the GSSAPI code needs similar * flags. */ contextFlags = ISC_REQ_CONFIDENTIALITY | ISC_REQ_MUTUAL_AUTH; initSingleEmptyBuffer(&outBufferDesc, &outBuffer); status = makeBuffer(&outBufferDesc, sspiContext->maxTokenSize); if (status) { return status; } if (base64Token) { SecBufferDesc inBufferDesc; SecBuffer inBuffer; if (!sspiContext->continueNeeded) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Got an unexpected token."); return -1; } initSingleEmptyBuffer(&inBufferDesc, &inBuffer); status = base64ToBuffer(base64Token, &inBufferDesc); if (status) { freeBuffer(&outBufferDesc); return status; } securityStatus = initializeSecurityContext(&sspiContext->credentials, &(sspiContext->context), sspiContext->serverName, contextFlags, &inBufferDesc, &(sspiContext->context), &outBufferDesc); if (securityStatus == SEC_E_OK) { sspiContext->authfinished = 1; } freeBuffer(&inBufferDesc); } else { if (sspiContext->continueNeeded) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Expected a token from server."); return -1; } if (sspiContext->authfinished && (sspiContext->credentials.dwLower || sspiContext->credentials.dwUpper)) { if (sspiContext->authfinished) { freeBuffer(&outBufferDesc); sspiContext->authfinished = 0; NE_DEBUG(NE_DBG_HTTPAUTH,"sspi: failing because starting over from failed try."); return -1; } sspiContext->authfinished = 0; } /* Reset any existing context since we are starting over */ resetContext(sspiContext); if (acquireCredentialsHandle (&sspiContext->credentials, sspiContext->mechanism) != SEC_E_OK) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: acquireCredentialsHandle failed.\n"); return -1; } securityStatus = initializeSecurityContext(&sspiContext->credentials, NULL, sspiContext->serverName, contextFlags, NULL, &(sspiContext->context), &outBufferDesc); } if (securityStatus == SEC_I_COMPLETE_AND_CONTINUE || securityStatus == SEC_I_COMPLETE_NEEDED) { SECURITY_STATUS compleStatus = pSFT->CompleteAuthToken(&(sspiContext->context), &outBufferDesc); if (compleStatus != SEC_E_OK) { freeBuffer(&outBufferDesc); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: CompleteAuthToken failed."); return -1; } } if (securityStatus == SEC_I_COMPLETE_AND_CONTINUE || securityStatus == SEC_I_CONTINUE_NEEDED) { sspiContext->continueNeeded = 1; } else { sspiContext->continueNeeded = 0; } if (!(securityStatus == SEC_I_COMPLETE_AND_CONTINUE || securityStatus == SEC_I_COMPLETE_NEEDED || securityStatus == SEC_I_CONTINUE_NEEDED || securityStatus == SEC_E_OK)) { NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: initializeSecurityContext [failed] [%x].\n", securityStatus); freeBuffer(&outBufferDesc); return -1; } *responseToken = ne_base64(outBufferDesc.pBuffers->pvBuffer, outBufferDesc.pBuffers->cbBuffer); freeBuffer(&outBufferDesc); return 0; } #endif /* HAVE_SSPI */ davix-R_0_5_0/deps/libneon/src/ne_sspi.h000066400000000000000000000027031257152637300202500ustar00rootroot00000000000000/* Microsoft SSPI based authentication routines Copyright (C) 2004-2005, Vladimir Berezniker @ http://public.xdi.org/=vmpn This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_SSPI_H #define NE_SSPI_H /* Win32 SSPI-based authentication interfaces. PRIVATE TO NEON -- NOT * PART OF THE EXTERNAL API. */ #ifdef HAVE_SSPI #include #define SECURITY_WIN32 #include int ne_sspi_init(void); int ne_sspi_deinit(void); int ne_sspi_create_context(void **context, char * serverName, int ntlm); int ne_sspi_destroy_context(void *context); int ne_sspi_clear_context(void *context); int ne_sspi_authenticate(void *context, const char *base64Token, char **responseToken); #endif /* HAVE_SSPI */ #endif /* NE_SSPI_H */ davix-R_0_5_0/deps/libneon/src/ne_string.c000066400000000000000000000412561257152637300206010ustar00rootroot00000000000000/* String utility functions Copyright (C) 1999-2007, 2009, Joe Orton strcasecmp/strncasecmp implementations are: Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include "ne_alloc.h" #include "ne_string.h" char *ne_token(char **str, char separator) { char *ret = *str, *pnt = strchr(*str, separator); if (pnt) { *pnt = '\0'; *str = pnt + 1; } else { /* no separator found: return end of string. */ *str = NULL; } return ret; } char *ne_qtoken(char **str, char separator, const char *quotes) { char *pnt, *ret = NULL; for (pnt = *str; *pnt != '\0'; pnt++) { char *quot = strchr(quotes, *pnt); if (quot) { char *qclose = strchr(pnt+1, *quot); if (!qclose) { /* no closing quote: invalid string. */ return NULL; } pnt = qclose; } else if (*pnt == separator) { /* found end of token. */ *pnt = '\0'; ret = *str; *str = pnt + 1; return ret; } } /* no separator found: return end of string. */ ret = *str; *str = NULL; return ret; } char *ne_shave(char *str, const char *whitespace) { char *pnt, *ret = str; while (*ret != '\0' && strchr(whitespace, *ret) != NULL) { ret++; } /* pnt points at the NUL terminator. */ pnt = &ret[strlen(ret)]; while (pnt > ret && strchr(whitespace, *(pnt-1)) != NULL) { pnt--; } *pnt = '\0'; return ret; } void ne_buffer_clear(ne_buffer *buf) { memset(buf->data, 0, buf->length); buf->used = 1; } /* Grows for given size, returns 0 on success, -1 on error. */ void ne_buffer_grow(ne_buffer *buf, size_t newsize) { #define NE_BUFFER_GROWTH 512 if (newsize > buf->length) { /* If it's not big enough already... */ buf->length = ((newsize / NE_BUFFER_GROWTH) + 1) * NE_BUFFER_GROWTH; /* Reallocate bigger buffer */ buf->data = ne_realloc(buf->data, buf->length); } } static size_t count_concat(va_list *ap) { size_t total = 0; char *next; while ((next = va_arg(*ap, char *)) != NULL) total += strlen(next); return total; } static void do_concat(char *str, va_list *ap) { char *next; while ((next = va_arg(*ap, char *)) != NULL) { #ifdef HAVE_STPCPY str = stpcpy(str, next); #else size_t len = strlen(next); memcpy(str, next, len); str += len; #endif } } void ne_buffer_concat(ne_buffer *buf, ...) { va_list ap; ssize_t total; va_start(ap, buf); total = buf->used + count_concat(&ap); va_end(ap); /* Grow the buffer */ ne_buffer_grow(buf, total); va_start(ap, buf); do_concat(buf->data + buf->used - 1, &ap); va_end(ap); buf->used = total; buf->data[total - 1] = '\0'; } char *ne_concat(const char *str, ...) { va_list ap; size_t total, slen = strlen(str); char *ret; va_start(ap, str); total = slen + count_concat(&ap); va_end(ap); ret = memcpy(ne_malloc(total + 1), str, slen); va_start(ap, str); do_concat(ret + slen, &ap); va_end(ap); ret[total] = '\0'; return ret; } /* Append zero-terminated string... returns 0 on success or -1 on * realloc failure. */ void ne_buffer_zappend(ne_buffer *buf, const char *str) { ne_buffer_append(buf, str, strlen(str)); } void ne_buffer_append(ne_buffer *buf, const char *data, size_t len) { ne_buffer_grow(buf, buf->used + len); memcpy(buf->data + buf->used - 1, data, len); buf->used += len; buf->data[buf->used - 1] = '\0'; } size_t ne_buffer_snprintf(ne_buffer *buf, size_t max, const char *fmt, ...) { va_list ap; size_t ret; ne_buffer_grow(buf, buf->used + max); va_start(ap, fmt); ret = ne_vsnprintf(buf->data + buf->used - 1, max, fmt, ap); va_end(ap); buf->used += ret; return ret; } ne_buffer *ne_buffer_create(void) { return ne_buffer_ncreate(512); } ne_buffer *ne_buffer_ncreate(size_t s) { ne_buffer *buf = ne_malloc(sizeof(*buf)); buf->data = ne_malloc(s); buf->data[0] = '\0'; buf->length = s; buf->used = 1; return buf; } void ne_buffer_destroy(ne_buffer *buf) { ne_free(buf->data); ne_free(buf); } char *ne_buffer_finish(ne_buffer *buf) { char *ret = buf->data; ne_free(buf); return ret; } void ne_buffer_altered(ne_buffer *buf) { buf->used = strlen(buf->data) + 1; } /* ascii_quote[n] gives the number of bytes needed by * ne_buffer_qappend() to append character 'n'. */ static const unsigned char ascii_quote[256] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; static const char hex_chars[16] = "0123456789ABCDEF"; /* Return the expected number of bytes needed to append the string * beginning at byte 's', where 'send' points to the last byte after * 's'. */ static size_t qappend_count(const unsigned char *s, const unsigned char *send) { const unsigned char *p; size_t ret; for (p = s, ret = 0; p < send; p++) { ret += ascii_quote[*p]; } return ret; } /* Append the string 's', up to but not including 'send', to string * 'dest', quoting along the way. Returns pointer to NUL. */ static char *quoted_append(char *dest, const unsigned char *s, const unsigned char *send) { const unsigned char *p; char *q = dest; for (p = s; p < send; p++) { if (ascii_quote[*p] == 1) { *q++ = *p; } else { *q++ = '\\'; *q++ = 'x'; *q++ = hex_chars[(*p >> 4) & 0x0f]; *q++ = hex_chars[*p & 0x0f]; } } /* NUL terminate after the last character */ *q = '\0'; return q; } void ne_buffer_qappend(ne_buffer *buf, const unsigned char *data, size_t len) { const unsigned char *dend = data + len; char *q, *qs; ne_buffer_grow(buf, buf->used + qappend_count(data, dend)); /* buf->used >= 1, so this is safe. */ qs = buf->data + buf->used - 1; q = quoted_append(qs, data, dend); /* used already accounts for a NUL, so increment by number of * characters appended, *before* the NUL. */ buf->used += q - qs; } char *ne_strnqdup(const unsigned char *data, size_t len) { const unsigned char *dend = data + len; char *dest = malloc(qappend_count(data, dend) + 1); quoted_append(dest, data, dend); return dest; } static const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/="; char *ne_base64(const unsigned char *text, size_t inlen) { /* The tricky thing about this is doing the padding at the end, * doing the bit manipulation requires a bit of concentration only */ char *buffer, *point; size_t outlen; /* Use 'buffer' to store the output. Work out how big it should be... * This must be a multiple of 4 bytes */ outlen = (inlen*4)/3; if ((inlen % 3) > 0) /* got to pad */ outlen += 4 - (inlen % 3); buffer = ne_malloc(outlen + 1); /* +1 for the \0 */ /* now do the main stage of conversion, 3 bytes at a time, * leave the trailing bytes (if there are any) for later */ for (point=buffer; inlen>=3; inlen-=3, text+=3) { *(point++) = b64_alphabet[ (*text)>>2 ]; *(point++) = b64_alphabet[ ((*text)<<4 & 0x30) | (*(text+1))>>4 ]; *(point++) = b64_alphabet[ ((*(text+1))<<2 & 0x3c) | (*(text+2))>>6 ]; *(point++) = b64_alphabet[ (*(text+2)) & 0x3f ]; } /* Now deal with the trailing bytes */ if (inlen > 0) { /* We always have one trailing byte */ *(point++) = b64_alphabet[ (*text)>>2 ]; *(point++) = b64_alphabet[ (((*text)<<4 & 0x30) | (inlen==2?(*(text+1))>>4:0)) ]; *(point++) = (inlen==1?'=':b64_alphabet[ (*(text+1))<<2 & 0x3c ]); *(point++) = '='; } /* Null-terminate */ *point = '\0'; return buffer; } /* VALID_B64: fail if 'ch' is not a valid base64 character */ #define VALID_B64(ch) (((ch) >= 'A' && (ch) <= 'Z') || \ ((ch) >= 'a' && (ch) <= 'z') || \ ((ch) >= '0' && (ch) <= '9') || \ (ch) == '/' || (ch) == '+' || (ch) == '=') /* DECODE_B64: decodes a valid base64 character. */ #define DECODE_B64(ch) ((ch) >= 'a' ? ((ch) + 26 - 'a') : \ ((ch) >= 'A' ? ((ch) - 'A') : \ ((ch) >= '0' ? ((ch) + 52 - '0') : \ ((ch) == '+' ? 62 : 63)))) size_t ne_unbase64(const char *data, unsigned char **out) { size_t inlen = strlen(data); unsigned char *outp; const unsigned char *in; if (inlen == 0 || (inlen % 4) != 0) return 0; outp = *out = ne_malloc(inlen * 3 / 4); for (in = (const unsigned char *)data; *in; in += 4) { unsigned int tmp; if (!VALID_B64(in[0]) || !VALID_B64(in[1]) || !VALID_B64(in[2]) || !VALID_B64(in[3]) || in[0] == '=' || in[1] == '=' || (in[2] == '=' && in[3] != '=')) { ne_free(*out); return 0; } tmp = (DECODE_B64(in[0]) & 0x3f) << 18 | (DECODE_B64(in[1]) & 0x3f) << 12; *outp++ = (tmp >> 16) & 0xff; if (in[2] != '=') { tmp |= (DECODE_B64(in[2]) & 0x3f) << 6; *outp++ = (tmp >> 8) & 0xff; if (in[3] != '=') { tmp |= DECODE_B64(in[3]) & 0x3f; *outp++ = tmp & 0xff; } } } return outp - *out; } /* Character map array; ascii_clean[n] = isprint(n) ? n : 0x20. Used * by ne_strclean as a locale-independent isprint(). */ static const unsigned char ascii_clean[256] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; char *ne_strclean(char *str) { unsigned char *pnt; for (pnt = (unsigned char *)str; *pnt; pnt++) *pnt = (char)ascii_clean[*pnt]; return str; } char *ne_strerror(int errnum, char *buf, size_t buflen) { #ifdef HAVE_STRERROR_R #ifdef STRERROR_R_CHAR_P /* glibc-style strerror_r which may-or-may-not use provided buffer. */ char *ret = strerror_r(errnum, buf, buflen); if (ret != buf) ne_strnzcpy(buf, ret, buflen); #else /* POSIX-style strerror_r: */ char tmp[256]; if (strerror_r(errnum, tmp, sizeof tmp) == 0) ne_strnzcpy(buf, tmp, buflen); else ne_snprintf(buf, buflen, "Unknown error %d", errnum); #endif #else /* no strerror_r: */ ne_strnzcpy(buf, strerror(errnum), buflen); #endif return buf; } /* Wrapper for ne_snprintf. */ size_t ne_snprintf(char *str, size_t size, const char *fmt, ...) { va_list ap; va_start(ap, fmt); #ifdef HAVE_TRIO trio_vsnprintf(str, size, fmt, ap); #else vsnprintf(str, size, fmt, ap); #endif va_end(ap); str[size-1] = '\0'; return strlen(str); } /* Wrapper for ne_vsnprintf. */ size_t ne_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { #ifdef HAVE_TRIO trio_vsnprintf(str, size, fmt, ap); #else vsnprintf(str, size, fmt, ap); #endif str[size-1] = '\0'; return strlen(str); } /* Locale-independent strcasecmp implementations. */ static const unsigned char ascii_tolower[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; #define TOLOWER(ch) ascii_tolower[ch] const unsigned char *ne_tolower_array(void) { return ascii_tolower; } int ne_strcasecmp(const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; if (p1 == p2) return 0; do { c1 = TOLOWER(*p1++); c2 = TOLOWER(*p2++); if (c1 == '\0') break; } while (c1 == c2); return c1 - c2; } int ne_strncasecmp(const char *s1, const char *s2, size_t n) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; if (p1 == p2 || n == 0) return 0; do { c1 = TOLOWER(*p1++); c2 = TOLOWER(*p2++); if (c1 == '\0' || c1 != c2) return c1 - c2; } while (--n > 0); return c1 - c2; } davix-R_0_5_0/deps/libneon/src/ne_string.h000066400000000000000000000164741257152637300206120ustar00rootroot00000000000000/* String utility functions Copyright (C) 1999-2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_STRING_H #define NE_STRING_H #include "ne_defs.h" #include "ne_alloc.h" #include NE_BEGIN_DECLS /* ne_token and ne_qtoken return the next token in *str before either * the next separator character 'sep' or the NUL terminator. * ne_qtoken skips over any parts quoted using a pair of any one of * the characters given in 'quotes'. After returning, *str will point * to the next character after the separator, or NULL if no separator * character was found. * * ne_qtoken will return NULL if unterminated quotes are found. */ char *ne_token(char **str, char sep); char *ne_qtoken(char **str, char sep, const char *quotes); /* Return portion of 'str' with any characters in 'whitespace' shaved * off the beginning and end. Modifies str in-place. */ char *ne_shave(char *str, const char *whitespace); /* Cleanse 'str' of non-printable (e.g. control) characters. 'str' is * modified in-place, and returned. */ char *ne_strclean(char *str); /* Encode 'len' bytes of 'text' to base64. Returns malloc-allocated * NUL-terminated buffer which the caller must free(). */ char *ne_base64(const unsigned char *text, size_t len); /* Decode NUL-terminated base64-encoded string 'data', placing * malloc-allocated raw decoder output in '*out'. Returns length, or * zero on decode error (in which case the content of *out is * undefined). */ size_t ne_unbase64(const char *data, unsigned char **out); /* Dynamically-allocated string buffer. A string buffer which grows * dynamically . (Strings are zero-terminated still). A * string buffer ne_buffer which grows dynamically with the string. */ typedef struct { char *data; /* contents: NUL-terminated string */ size_t used; /* strlen(data) + 1 */ size_t length; /* number of bytes allocated */ } ne_buffer; /* Create a new string buffer object. */ ne_buffer *ne_buffer_create(void); /* Create a new string buffer object with at least 'size' bytes of * allocated space. */ ne_buffer *ne_buffer_ncreate(size_t size); /* Returns size of data in buffer, equiv to strlen(ne_buffer_data(buf)) */ #define ne_buffer_size(buf) ((buf)->used - 1) /* Concatenate all given strings onto the end of the buffer. The * strings must all be NUL-terminated, and MUST be followed by a NULL * argument marking the end of the list. */ void ne_buffer_concat(ne_buffer *buf, ...) ne_attribute_sentinel; /* Append a NUL-terminated string 'str' to buf. */ void ne_buffer_zappend(ne_buffer *buf, const char *str); /* Append 'len' bytes of 'data' to buf, where 'data' does not contain * a NUL terminator. (A NUL terminator is appended to buf) */ void ne_buffer_append(ne_buffer *buf, const char *data, size_t len); /* Append 'len' bytes of 'data' to buf. All non-ASCII bytes, and * ASCII control characters, are escaped. (Note that this includes * the NUL byte). */ void ne_buffer_qappend(ne_buffer *buf, const unsigned char *data, size_t len); /* Print a string to the end of the buffer using printf-style format * string 'format' and subsqeuent arguments. At most 'max' characters * are appended; the number of characters appended (excluding the NUL * terminator) is returned. Behaviour is undefined if 'max' is passed * as zero. */ size_t ne_buffer_snprintf(ne_buffer *buf, size_t max, const char *format, ...) ne_attribute((format(printf, 3, 4))); /* Append a literal, NUL-terminated constant string 'str' to buffer * 'buf'. */ #define ne_buffer_czappend(buf, str) \ ne_buffer_append((buf), (str), sizeof((str)) - 1) /* Clear the string buffer 'buf', making it equivalent to the empty * string. */ void ne_buffer_clear(ne_buffer *buf); /* Grow the allocated size of string buffer 'buf' to at least 'size' * bytes. */ void ne_buffer_grow(ne_buffer *buf, size_t size); /* Re-establish the 'used' invariant if the string buffer data field is * altered directly. */ void ne_buffer_altered(ne_buffer *buf); /* Destroy the string buffer object 'buf' without deallocating the * data string. The data string must subsequently be freed using * ne_free(). */ char *ne_buffer_finish(ne_buffer *buf); /* Destroy a string buffer object. */ void ne_buffer_destroy(ne_buffer *buf); /* Thread-safe strerror() wrapper; place system error for errno value * 'errnum' in 'buffer', which is of length 'buflen'. Returns * 'buffer'. */ char *ne_strerror(int errnum, char *buffer, size_t buflen); /* ne_strnzcpy copies at most 'n'-1 bytes of 'src' to 'dest', and * ensures that 'dest' is subsequently NUL-terminated. */ #define ne_strnzcpy(dest, src, n) do { size_t ne__nm1 = (n) - 1; \ strncpy(dest, src, ne__nm1); dest[ne__nm1] = '\0'; } while (0) /* Return a malloc-allocated copy of 'data', of length 'len', with all * non-ASCII bytes, and ASCII control characters escaped. (Note that * the escaping includes the NUL byte). */ char *ne_strnqdup(const unsigned char *data, size_t len); /* Return malloc-allocated concatenation of all NUL-terminated string * arguments, up to a terminating NULL pointer. */ char *ne_concat(const char *str, ...) ne_attribute_sentinel; /* Wrapper for snprintf: always NUL-terminates returned buffer, and * returns strlen(str). */ size_t ne_snprintf(char *str, size_t size, const char *fmt, ...) ne_attribute((format(printf, 3, 4))); /* Wrapper for vsnprintf. */ size_t ne_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) ne_attribute((format(printf, 3, 0))); /* Implementations of strcasecmp and strncasecmp which behave as * defined by the ANSI C strcasecmp() and strncasecmp() when in the * POSIX locale; i.e. ignoring the process locale. */ /* Compares 's1' and 's2', ignoring differences in case. */ int ne_strcasecmp(const char *s1, const char *s2); /* Compares up to 'n' characters of 's1' and 's2', ignoring * differences in case. */ int ne_strncasecmp(const char *s1, const char *s2, size_t n); /* Return lowercase 'c' as in POSIX locale; note difference from ANSI * C semantics as both the argument and return value are unsigned * char. */ #define ne_tolower(c) (ne_tolower_array()[(unsigned char)c]) const unsigned char *ne_tolower_array(void); /* Convert an ASCII hexadecimal character in the ranges '0'..'9' * 'a'..'f' 'A'..'F' to its numeric equivalent. */ #define NE_ASC2HEX(x) (((x) <= '9') ? ((x) - '0') : \ (ne_tolower((x)) + 10 - 'a')) /* Convert an integer in the range 0..15 to the equivalent (lowercase) * ASCII hexadecimal equivalent character, in the range '0..9,'a..f' */ #define NE_HEX2ASC(x) ((char) ((x) > 9 ? ((x) - 10 + 'a') : ((x) + '0'))) NE_END_DECLS #endif /* NE_STRING_H */ davix-R_0_5_0/deps/libneon/src/ne_stubssl.c000066400000000000000000000064431257152637300207710ustar00rootroot00000000000000/* Stubs for SSL support when no SSL library has been configured Copyright (C) 2002-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include /* for NULL */ #include "ne_ssl.h" #include "ne_session.h" char *ne_ssl_readable_dname(const ne_ssl_dname *dn) { return NULL; } ne_ssl_certificate *ne_ssl_cert_read(const char *filename) { return NULL; } int ne_ssl_cert_cmp(const ne_ssl_certificate *c1, const ne_ssl_certificate *c2) { return 1; } const ne_ssl_certificate *ne_ssl_cert_signedby(const ne_ssl_certificate *cert) { return NULL; } const ne_ssl_dname *ne_ssl_cert_issuer(const ne_ssl_certificate *cert) { return NULL; } const ne_ssl_dname *ne_ssl_cert_subject(const ne_ssl_certificate *cert) { return NULL; } void ne_ssl_cert_free(ne_ssl_certificate *cert) {} ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename) { return NULL; } const ne_ssl_certificate *ne_ssl_clicert_owner(const ne_ssl_client_cert *ccert) { return NULL; } int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *ccert) { return -1; } int ne_ssl_clicert_decrypt(ne_ssl_client_cert *ccert, const char *password) { return -1; } void ne_ssl_clicert_free(ne_ssl_client_cert *ccert) {} void ne_ssl_trust_default_ca(ne_session *sess) {} ne_ssl_context *ne_ssl_context_create(int mode) { return NULL; } void ne_ssl_context_trustcert(ne_ssl_context *ctx, const ne_ssl_certificate *cert) {} int ne_ssl_context_set_verify(ne_ssl_context *ctx, int required, const char *ca_names, const char *verify_cas) { return -1; } void ne_ssl_context_set_flag(ne_ssl_context *ctx, int flag, int value) {} void ne_ssl_context_destroy(ne_ssl_context *ctx) {} int ne_ssl_cert_digest(const ne_ssl_certificate *cert, char digest[60]) { return -1; } void ne_ssl_cert_validity_time(const ne_ssl_certificate *cert, time_t *from, time_t *until) {} const char *ne_ssl_cert_identity(const ne_ssl_certificate *cert) { return NULL; } const char *ne_ssl_clicert_name(const ne_ssl_client_cert *ccert) { return NULL; } int ne_ssl_dname_cmp(const ne_ssl_dname *dn1, const ne_ssl_dname *dn2) { return -1; } int ne_ssl_cert_write(const ne_ssl_certificate *cert, const char *filename) { return -1; } char *ne_ssl_cert_export(const ne_ssl_certificate *cert) { return NULL; } ne_ssl_certificate *ne_ssl_cert_import(const char *data) { return NULL; } void ne_ssl_set_clicert(ne_session *sess, const ne_ssl_client_cert *cc) {} davix-R_0_5_0/deps/libneon/src/ne_uri.c000066400000000000000000000423301257152637300200640ustar00rootroot00000000000000/* URI manipulation routines. Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include "ne_string.h" /* for ne_buffer */ #include "ne_alloc.h" #include "ne_uri.h" /* URI ABNF from RFC 3986: */ #define PS (0x0001) /* "+" */ #define PC (0x0002) /* "%" */ #define DS (0x0004) /* "-" */ #define DT (0x0008) /* "." */ #define US (0x0010) /* "_" */ #define TD (0x0020) /* "~" */ #define FS (0x0040) /* "/" */ #define CL (0x0080) /* ":" */ #define AT (0x0100) /* "@" */ #define QU (0x0200) /* "?" */ #define DG (0x0400) /* DIGIT */ #define AL (0x0800) /* ALPHA */ #define GD (0x1000) /* gen-delims = "#" / "[" / "]" * ... except ":", "/", "@", and "?" */ #define SD (0x2000) /* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" * / "*" / "+" / "," / ";" / "=" * ... except "+" which is PS */ #define OT (0x4000) /* others */ #define URI_ALPHA (AL) #define URI_DIGIT (DG) /* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" */ #define URI_UNRESERVED (AL | DG | DS | DT | US | TD) /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ #define URI_SCHEME (AL | DG | PS | DS | DT) /* real sub-delims definition, including "+" */ #define URI_SUBDELIM (PS | SD) /* real gen-delims definition, including ":", "/", "@" and "?" */ #define URI_GENDELIM (GD | CL | FS | AT | QU) /* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */ #define URI_USERINFO (URI_UNRESERVED | PC | URI_SUBDELIM | CL) /* pchar = unreserved / pct-encoded / sub-delims / ":" / "@" */ #define URI_PCHAR (URI_UNRESERVED | PC | URI_SUBDELIM | CL | AT) /* invented: segchar = pchar / "/" */ #define URI_SEGCHAR (URI_PCHAR | FS) /* query = *( pchar / "/" / "?" ) */ #define URI_QUERY (URI_PCHAR | FS | QU) /* fragment == query */ #define URI_FRAGMENT URI_QUERY /* any characters which should be path-escaped: */ #define URI_ESCAPE ((URI_GENDELIM & ~(FS)) | URI_SUBDELIM | OT | PC) static const unsigned int uri_chars[256] = { /* 0xXX x0 x2 x4 x6 x8 xA xC xE */ /* 0x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* 1x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* 2x */ OT, SD, OT, GD, SD, PC, SD, SD, SD, SD, SD, PS, SD, DS, DT, FS, /* 3x */ DG, DG, DG, DG, DG, DG, DG, DG, DG, DG, CL, SD, OT, SD, OT, QU, /* 4x */ AT, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, /* 5x */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, GD, OT, GD, OT, US, /* 6x */ OT, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, /* 7x */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, OT, OT, OT, TD, OT, /* 8x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* 9x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Ax */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Bx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Cx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Dx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Ex */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Fx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT }; #define uri_lookup(ch) (uri_chars[(unsigned char)ch]) char *ne_path_parent(const char *uri) { size_t len = strlen(uri); const char *pnt = uri + len - 1; /* skip trailing slash (parent of "/foo/" is "/") */ if (pnt >= uri && *pnt == '/') pnt--; /* find previous slash */ while (pnt > uri && *pnt != '/') pnt--; if (pnt < uri || (pnt == uri && *pnt != '/')) return NULL; return ne_strndup(uri, pnt - uri + 1); } int ne_path_has_trailing_slash(const char *uri) { size_t len = strlen(uri); return ((len > 0) && (uri[len-1] == '/')); } unsigned int ne_uri_defaultport(const char *scheme) { /* RFC2616/3.2.3 says use case-insensitive comparisons here. */ if (ne_strcasecmp(scheme, "http") == 0) return 80; else if (ne_strcasecmp(scheme, "https") == 0) return 443; else return 0; } int ne_uri_parse(const char *uri, ne_uri *parsed) { const char *p, *s; memset(parsed, 0, sizeof *parsed); p = s = uri; /* => s = p = URI-reference */ if (uri_lookup(*p) & URI_ALPHA) { while (uri_lookup(*p) & URI_SCHEME) p++; if (*p == ':') { parsed->scheme = ne_strndup(uri, p - s); s = p + 1; } } /* => s = heir-part, or s = relative-part */ if (s[0] == '/' && s[1] == '/') { const char *pa; /* => s = "//" authority path-abempty (from expansion of * either heir-part of relative-part) */ /* authority = [ userinfo "@" ] host [ ":" port ] */ s = pa = s + 2; /* => s = authority */ while (*pa != '/' && *pa != '\0') pa++; /* => pa = path-abempty */ p = s; while (p < pa && uri_lookup(*p) & URI_USERINFO) p++; if (*p == '@') { parsed->userinfo = ne_strndup(s, p - s); s = p + 1; } /* => s = host */ if (s[0] == '[') { p = s + 1; while (*p != ']' && p < pa) p++; if (p == pa || (p + 1 != pa && p[1] != ':')) { /* Ill-formed IP-literal. */ return -1; } p++; /* => p = colon */ } else { /* Find the colon. */ p = pa; while (*p != ':' && p > s) p--; } if (p == s) { p = pa; /* No colon; => p = path-abempty */ } else if (p + 1 != pa) { /* => p = colon */ parsed->port = atoi(p + 1); if(parsed->port == 0) parsed->port = UINT_MAX; } parsed->host = ne_strndup(s, p - s); s = pa; if (*s == '\0') { s = "/"; /* FIXME: scheme-specific. */ } } /* => s = path-abempty / path-absolute / path-rootless * / path-empty / path-noscheme */ p = s; while (uri_lookup(*p) & URI_SEGCHAR) p++; /* => p = [ "?" query ] [ "#" fragment ] */ parsed->path = ne_strndup(s, p - s); if (*p != '\0') { s = p++; while (uri_lookup(*p) & URI_QUERY) p++; /* => p = [ "#" fragment ] */ /* => s = [ "?" query ] [ "#" fragment ] */ if (*s == '?') { parsed->query = ne_strndup(s + 1, p - s - 1); if (*p != '\0') { s = p++; while (uri_lookup(*p) & URI_FRAGMENT) p++; } } /* => p now points to the next character after the * URI-reference; which should be the NUL byte. */ if (*s == '#') { parsed->fragment = ne_strndup(s + 1, p - s - 1); } else if (*p || *s != '?') { return -1; } } return 0; } /* This function directly implements the "Merge Paths" algorithm * described in RFC 3986 section 5.2.3. */ static char *merge_paths(const ne_uri *base, const char *path) { const char *p; if (base->host && base->path[0] == '\0') { return ne_concat("/", path, NULL); } p = strrchr(base->path, '/'); if (p == NULL) { return ne_strdup(path); } else { size_t len = p - base->path + 1; char *ret = ne_malloc(strlen(path) + len + 1); memcpy(ret, base->path, len); memcpy(ret + len, path, strlen(path) + 1); return ret; } } /* This function directly implements the "Remove Dot Segments" * algorithm described in RFC 3986 section 5.2.4. */ static char *remove_dot_segments(const char *path) { char *in, *inc, *out; inc = in = ne_strdup(path); out = ne_malloc(strlen(path) + 1); out[0] = '\0'; while (in[0]) { /* case 2.A: */ if (strncmp(in, "./", 2) == 0) { in += 2; } else if (strncmp(in, "../", 3) == 0) { in += 3; } /* case 2.B: */ else if (strncmp(in, "/./", 3) == 0) { in += 2; } else if (strcmp(in, "/.") == 0) { in[1] = '\0'; } /* case 2.C: */ else if (strncmp(in, "/../", 4) == 0 || strcmp(in, "/..") == 0) { char *p; /* Make the next character in the input buffer a "/": */ if (in[3] == '\0') { /* terminating "/.." case */ in += 2; in[0] = '/'; } else { /* "/../" prefix case */ in += 3; } /* Trim the last component from the output buffer, or * empty it. */ p = strrchr(out, '/'); if (p) { *p = '\0'; } else { out[0] = '\0'; } } /* case 2.D: */ else if (strcmp(in, ".") == 0 || strcmp(in, "..") == 0) { in[0] = '\0'; } /* case 2.E */ else { char *p; /* Search for the *second* "/" if the leading character is * already "/": */ p = strchr(in + (in[0] == '/'), '/'); /* Otherwise, copy the whole string */ if (p == NULL) p = strchr(in, '\0'); strncat(out, in, p - in); in = p; } } ne_free(inc); return out; } /* Copy authority components from 'src' to 'dest' if defined. */ static void copy_authority(ne_uri *dest, const ne_uri *src) { if (src->host) dest->host = ne_strdup(src->host); dest->port = src->port; if (src->userinfo) dest->userinfo = ne_strdup(src->userinfo); } /* This function directly implements the "Transform References" * algorithm described in RFC 3986 section 5.2.2. */ ne_uri *ne_uri_resolve(const ne_uri *base, const ne_uri *relative, ne_uri *target) { memset(target, 0, sizeof *target); if (relative->scheme) { target->scheme = ne_strdup(relative->scheme); copy_authority(target, relative); target->path = remove_dot_segments(relative->path); if (relative->query) target->query = ne_strdup(relative->query); } else { if (relative->host) { copy_authority(target, relative); target->path = remove_dot_segments(relative->path); if (relative->query) target->query = ne_strdup(relative->query); } else { if (relative->path[0] == '\0') { target->path = ne_strdup(base->path); if (relative->query) { target->query = ne_strdup(relative->query); } else if (base->query) { target->query = ne_strdup(base->query); } } else { if (relative->path[0] == '/') { target->path = remove_dot_segments(relative->path); } else { char *merged = merge_paths(base, relative->path); target->path = remove_dot_segments(merged); ne_free(merged); } if (relative->query) target->query = ne_strdup(relative->query); } copy_authority(target, base); } if (base->scheme) target->scheme = ne_strdup(base->scheme); } if (relative->fragment) target->fragment = ne_strdup(relative->fragment); return target; } ne_uri *ne_uri_copy(ne_uri *dest, const ne_uri *src) { memset(dest, 0, sizeof *dest); if (src->scheme) dest->scheme = ne_strdup(src->scheme); copy_authority(dest, src); if (src->path) dest->path = ne_strdup(src->path); if (src->query) dest->query = ne_strdup(src->query); if (src->fragment) dest->fragment = ne_strdup(src->fragment); return dest; } void ne_uri_free(ne_uri *u) { if (u->host) ne_free(u->host); if (u->path) ne_free(u->path); if (u->scheme) ne_free(u->scheme); if (u->userinfo) ne_free(u->userinfo); if (u->fragment) ne_free(u->fragment); if (u->query) ne_free(u->query); memset(u, 0, sizeof *u); } char *ne_path_unescape(const char *uri) { const char *pnt; char *ret, *retpos, buf[5] = { "0x00" }; retpos = ret = ne_malloc(strlen(uri) + 1); for (pnt = uri; *pnt != '\0'; pnt++) { if (*pnt == '%') { if (!isxdigit((unsigned char) pnt[1]) || !isxdigit((unsigned char) pnt[2])) { /* Invalid URI */ ne_free(ret); return NULL; } buf[2] = *++pnt; buf[3] = *++pnt; /* bit faster than memcpy */ *retpos++ = (char)strtol(buf, NULL, 16); } else { *retpos++ = *pnt; } } *retpos = '\0'; return ret; } /* CH must be an unsigned char; evaluates to 1 if CH should be * percent-encoded. */ #define path_escape_ch(ch) (uri_lookup(ch) & URI_ESCAPE) char *ne_path_escape(const char *path) { const unsigned char *pnt; char *ret, *p; size_t count = 0; for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { count += path_escape_ch(*pnt); } if (count == 0) { return ne_strdup(path); } p = ret = ne_malloc(strlen(path) + 2 * count + 1); for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { if (path_escape_ch(*pnt)) { /* Escape it - % */ sprintf(p, "%%%02x", (unsigned char) *pnt); p += 3; } else { *p++ = *pnt; } } *p = '\0'; return ret; } #undef path_escape_ch #define CMPWITH(field, func) \ do { \ if (u1->field) { \ if (!u2->field) return -1; \ n = func(u1->field, u2->field); \ if (n) return n; \ } else if (u2->field) { \ return 1; \ } \ } while (0) #define CMP(field) CMPWITH(field, strcmp) #define CASECMP(field) CMPWITH(field, ne_strcasecmp) /* As specified by RFC 2616, section 3.2.3. */ int ne_uri_cmp(const ne_uri *u1, const ne_uri *u2) { int n; CMP(path); CASECMP(host); CASECMP(scheme); CMP(query); CMP(fragment); CMP(userinfo); return u2->port - u1->port; } #undef CMP #undef CASECMP #undef CMPWITH /* TODO: implement properly */ int ne_path_compare(const char *a, const char *b) { int ret = ne_strcasecmp(a, b); if (ret) { /* This logic says: "If the lengths of the two URIs differ by * exactly one, and the LONGER of the two URIs has a trailing * slash and the SHORTER one DOESN'T, then..." */ int traila = ne_path_has_trailing_slash(a), trailb = ne_path_has_trailing_slash(b), lena = strlen(a), lenb = strlen(b); if (traila != trailb && abs(lena - lenb) == 1 && ((traila && lena > lenb) || (trailb && lenb > lena))) { /* Compare them, ignoring the trailing slash on the longer * URI */ if (strncasecmp(a, b, lena < lenb ? lena : lenb) == 0) ret = 0; } } return ret; } char *ne_uri_unparse(const ne_uri *uri) { ne_buffer *buf = ne_buffer_create(); if (uri->scheme) { ne_buffer_concat(buf, uri->scheme, ":", NULL); } if (uri->host) { ne_buffer_czappend(buf, "//"); if (uri->userinfo) { ne_buffer_concat(buf, uri->userinfo, "@", NULL); } ne_buffer_zappend(buf, uri->host); if (uri->port > 0 && (!uri->scheme || ne_uri_defaultport(uri->scheme) != uri->port)) { char str[20]; ne_snprintf(str, 20, ":%d", uri->port); ne_buffer_zappend(buf, str); } } ne_buffer_zappend(buf, uri->path); if (uri->query) { ne_buffer_concat(buf, "?", uri->query, NULL); } if (uri->fragment) { ne_buffer_concat(buf, "#", uri->fragment, NULL); } return ne_buffer_finish(buf); } /* Give it a path segment, it returns non-zero if child is * a child of parent. */ int ne_path_childof(const char *parent, const char *child) { char *root = ne_strdup(child); int ret; if (strlen(parent) >= strlen(child)) { ret = 0; } else { /* root is the first of child, equal to length of parent */ root[strlen(parent)] = '\0'; ret = (ne_path_compare(parent, root) == 0); } ne_free(root); return ret; } davix-R_0_5_0/deps/libneon/src/ne_uri.h000066400000000000000000000075011257152637300200720ustar00rootroot00000000000000/* URI manipulation routines. Copyright (C) 1999-2008, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_URI_H #define NE_URI_H #include "ne_defs.h" NE_BEGIN_DECLS /* Return a copy of a path string with anything other than * "unreserved" and the forward-slash character percent-encoded * according to the URI encoding rules. Returns a malloc-allocated * string and never NULL. */ char *ne_path_escape(const char *path); /* Return a decoded copy of a percent-encoded path string. Returns * malloc-allocated path on success, or NULL if the string contained * any syntactically invalid percent-encoding sequences. */ char *ne_path_unescape(const char *epath); /* Returns malloc-allocated parent of path, or NULL if path has no * parent (such as "/"). */ char *ne_path_parent(const char *path); /* Returns strcmp-like value giving comparison between p1 and p2, * ignoring trailing-slashes. */ int ne_path_compare(const char *p1, const char *p2); /* Returns non-zero if child is a child of parent */ int ne_path_childof(const char *parent, const char *child); /* Returns non-zero if path has a trailing slash character */ int ne_path_has_trailing_slash(const char *path); /* Return the default port for the given scheme, or 0 if none is * known. */ unsigned int ne_uri_defaultport(const char *scheme); typedef struct { char *scheme; char *host, *userinfo; unsigned int port; char *path, *query, *fragment; } ne_uri; /* Parse a URI-reference 'uri' and place parsed components in *parsed. * Returns zero on success, non-zero on parse error. On successful or * error return, all the 'char *' fields of *parsed are either set to * NULL, or point to malloc-allocated NUL-terminated strings; * ne_uri_free can be used to free any set fields. On success, * parsed->path is guaranteed to be non-NULL. */ int ne_uri_parse(const char *uri, ne_uri *parsed); /* Turns a URI structure back into a string. The returned string is * malloc-allocated, and must be freed by the caller. */ char *ne_uri_unparse(const ne_uri *uri); /* Resolve a relative URI 'relative', with respect to base URI 'base', * placing the resultant URI in '*result'. At least both base->path * and relative->path must be non-NULL. On return, all the 'char *' * fields of *result are either set to NULL or point to * malloc-allocated NUL-terminated strings. result->path is * guaranteed to be non-NULL. ne_uri_free can be used to free the * result structure after use. Returns 'result'. */ ne_uri *ne_uri_resolve(const ne_uri *base, const ne_uri *relative, ne_uri *result); /* Compares URIs u1 and u2, returns non-zero if they are found to be * non-equal. The sign of the return value is <0 if 'u1' is less than * 'u2', or >0 if 'u2' is greater than 'u1'. */ int ne_uri_cmp(const ne_uri *u1, const ne_uri *u2); /* Copy components of URI 'src' to destination 'dest'. Returns * 'dest'. */ ne_uri *ne_uri_copy(ne_uri *dest, const ne_uri *src); /* Frees any non-NULL fields of parsed URI structure *parsed. All * fields are then zero-initialized. */ void ne_uri_free(ne_uri *parsed); NE_END_DECLS #endif /* NE_URI_H */ davix-R_0_5_0/deps/libneon/src/ne_utils.c000066400000000000000000000144251257152637300204310ustar00rootroot00000000000000/* HTTP utility functions Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #ifdef HAVE_STRING_H #include #endif #include #include /* isdigit() for ne_parse_statusline */ #ifdef NE_HAVE_ZLIB #include #endif #ifdef HAVE_OPENSSL #include #endif #ifdef HAVE_GNUTLS #include #endif /* libxml2: pick up the version string. */ #if defined(HAVE_LIBXML) #include #elif defined(HAVE_EXPAT) && !defined(HAVE_XMLPARSE_H) #include #endif #include "ne_utils.h" #include "ne_string.h" /* for ne_strdup */ #include "ne_dates.h" int ne_debug_mask = 0; FILE *ne_debug_stream = NULL; void ne_debug_init(FILE *stream, int mask) { ne_debug_stream = stream; ne_debug_mask = mask; #if defined(HAVE_SETVBUF) && defined(_IONBF) /* If possible, turn off buffering on the debug log. this is very * helpful if debugging segfaults. */ if (stream) setvbuf(stream, NULL, _IONBF, 0); #endif } void ne_debug(int ch, const char *template, ...) { va_list params; if ((ch & ne_debug_mask) == 0) return; fflush(stdout); va_start(params, template); vfprintf(ne_debug_stream, template, params); va_end(params); if ((ch & NE_DBG_FLUSH) == NE_DBG_FLUSH) fflush(ne_debug_stream); } #define NE_STRINGIFY(x) # x #define NE_EXPAT_VER(x,y,z) NE_STRINGIFY(x) "." NE_STRINGIFY(y) "." NE_STRINGIFY(z) static const char version_string[] = "neon " NEON_VERSION ": " #ifdef NEON_IS_LIBRARY "Library build" #else "Bundled build" #endif #ifdef NE_HAVE_IPV6 ", IPv6" #endif #ifdef HAVE_EXPAT ", Expat" /* expat >=1.95.2 exported the version */ #ifdef XML_MAJOR_VERSION " " NE_EXPAT_VER(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION) #endif #else /* !HAVE_EXPAT */ #ifdef HAVE_LIBXML ", libxml " LIBXML_DOTTED_VERSION #endif /* HAVE_LIBXML */ #endif /* !HAVE_EXPAT */ #if defined(NE_HAVE_ZLIB) && defined(ZLIB_VERSION) ", zlib " ZLIB_VERSION #endif /* NE_HAVE_ZLIB && ... */ #ifdef NE_HAVE_SOCKS ", SOCKSv5" #endif #ifdef HAVE_OPENSSL #ifdef OPENSSL_VERSION_TEXT ", " OPENSSL_VERSION_TEXT #else "OpenSSL (unknown version)" #endif /* OPENSSL_VERSION_TEXT */ #endif /* HAVE_OPENSSL */ #ifdef HAVE_GNUTLS ", GNU TLS " LIBGNUTLS_VERSION #endif /* HAVE_GNUTLS */ "." ; const char *ne_version_string(void) { return version_string; } int ne_version_match(int major, int minor) { return NE_VERSION_MAJOR != major || NE_VERSION_MINOR < minor || (NE_VERSION_MAJOR == 0 && NE_VERSION_MINOR != minor); } void ne_davix_logger(int scope, const char *msg, ...) { if( (davix_get_log_level() >= DAVIX_LOG_DEBUG) && (davix_get_log_scope() & scope) ) { va_list va; va_start(va, msg); davix_vlogger2(scope, DAVIX_LOG_TRACE, msg, va); va_end(va); } } void ne_gettime(struct timespec *time_value){ // duplicate code with timepoint // add support for OSX and other plateform without clock_gettime // going to be eradicate with the boost ASIO replacement if(time_value == NULL) return; #ifdef HAVE_CLOCK_GETTIME clock_gettime(CLOCK_MONOTONIC, time_value); #elif HAVE_GETTIMEOFDAY // TODO: gettimeofday is vulnerable to time jump // need an OSX specific implementation using Mach micro kernel API struct timeval now; (void) gettimeofday(&now, NULL); time_value->tv_sec = now.tv_sec; time_value->tv_nsec = now.tv_usec * 1000; #else #error "No gettimeofday nor clock_gettime: No time support" #endif } int ne_has_support(int feature) { switch (feature) { #if defined(NE_HAVE_SSL) || defined(NE_HAVE_ZLIB) || defined(NE_HAVE_IPV6) \ || defined(NE_HAVE_SOCKS) || defined(NE_HAVE_LFS) \ || defined(NE_HAVE_TS_SSL) || defined(NE_HAVE_I18N) #ifdef NE_HAVE_SSL case NE_FEATURE_SSL: #endif #ifdef NE_HAVE_ZLIB case NE_FEATURE_ZLIB: #endif #ifdef NE_HAVE_IPV6 case NE_FEATURE_IPV6: #endif #ifdef NE_HAVE_SOCKS case NE_FEATURE_SOCKS: #endif #ifdef NE_HAVE_LFS case NE_FEATURE_LFS: #endif #ifdef NE_HAVE_TS_SSL case NE_FEATURE_TS_SSL: #endif #ifdef NE_HAVE_I18N case NE_FEATURE_I18N: #endif return 1; #endif /* NE_HAVE_* */ default: return 0; } } int ne_parse_statusline(const char *status_line, ne_status *st) { const char *part; int major, minor, status_code, klass; /* skip leading garbage if any. */ part = strstr(status_line, "HTTP/"); if (part == NULL) return -1; minor = major = 0; /* Parse version string, skipping leading zeroes. */ for (part += 5; *part != '\0' && isdigit(*part); part++) major = major*10 + (*part-'0'); if (*part++ != '.') return -1; for (;*part != '\0' && isdigit(*part); part++) minor = minor*10 + (*part-'0'); if (*part != ' ') return -1; /* Skip any spaces */ for (; *part == ' '; part++) /* noop */; /* Parse the Status-Code; part now points at the first Y in * "HTTP/x.x YYY". */ if (!isdigit(part[0]) || !isdigit(part[1]) || !isdigit(part[2]) || (part[3] != '\0' && part[3] != ' ')) return -1; status_code = 100*(part[0]-'0') + 10*(part[1]-'0') + (part[2]-'0'); klass = part[0]-'0'; /* Skip whitespace between status-code and reason-phrase */ for (part+=3; *part == ' ' || *part == '\t'; part++) /* noop */; /* part now may be pointing to \0 if reason phrase is blank */ /* Fill in the results */ st->major_version = major; st->minor_version = minor; st->reason_phrase = ne_strclean(ne_strdup(part)); st->code = status_code; st->klass = klass; return 0; } davix-R_0_5_0/deps/libneon/src/ne_utils.h000066400000000000000000000106731257152637300204370ustar00rootroot00000000000000/* HTTP utility functions Copyright (C) 1999-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_UTILS_H #define NE_UTILS_H #include #include #include #include #include #include "ne_defs.h" #ifdef NEON_TRIO #include #endif #include "davix_logger_c.h" NE_BEGIN_DECLS /* Returns a human-readable library version string describing the * version and build information; for example: * "neon 0.2.0: Library build, OpenSSL support" */ const char *ne_version_string(void); /* Returns non-zero if library version is not of major version * 'major', or if minor version is not greater than or equal to * 'minor'. For neon versions with major == 0, all minor versions are * presumed to be incompatible. */ int ne_version_match(int major, int minor); void ne_davix_logger(int scope, const char* msg, ...); void ne_gettime(struct timespec * t); /* Feature codes: */ #define NE_FEATURE_SSL (1) /* SSL/TLS support */ #define NE_FEATURE_ZLIB (2) /* zlib compression in compress interface */ #define NE_FEATURE_IPV6 (3) /* IPv6 is supported in resolver */ #define NE_FEATURE_LFS (4) /* large file support */ #define NE_FEATURE_SOCKS (5) /* SOCKSv5 support */ #define NE_FEATURE_TS_SSL (6) /* Thread-safe SSL/TLS support */ #define NE_FEATURE_I18N (7) /* i18n error message support */ /* Returns non-zero if library is built with support for the given * NE_FEATURE_* feature code 'code'. */ int ne_has_support(int feature); /* Debugging macro to allow code to be optimized out if debugging is * disabled at build time. */ #ifndef NE_DEBUGGING #define NE_DEBUG if (0) ne_debug #else /* DEBUGGING */ /* #define NE_DEBUG ne_debug */ /* bypasses default Neon logger and use Davix's instead */ #define NE_DEBUG ne_davix_logger #endif /* DEBUGGING */ /* Debugging masks. */ /* Map to DAVIX logging masks. */ #define NE_DBG_SOCKET (DAVIX_LOG_SOCKET ) /* raw socket */ #define NE_DBG_HTTP (DAVIX_LOG_HEADER ) /* HTTP request/response handling */ #define NE_DBG_XML (DAVIX_LOG_XML ) /* XML parser */ #define NE_DBG_HTTPAUTH (DAVIX_LOG_SSL ) /* HTTP authentication (hiding credentials) */ #define NE_DBG_HTTPPLAIN (DAVIX_LOG_SSL ) /* plaintext HTTP authentication */ #define NE_DBG_LOCKS (DAVIX_LOG_LOCKS ) /* WebDAV locking */ #define NE_DBG_XMLPARSE (DAVIX_LOG_XML ) /* low-level XML parser */ #define NE_DBG_HTTPBODY (DAVIX_LOG_BODY ) /* HTTP response body blocks */ #define NE_DBG_SSL (DAVIX_LOG_SSL ) /* SSL/TLS */ #define NE_DBG_CORE (DAVIX_LOG_SOCKET ) #define NE_DBG_FLUSH (1<<30) /* always flush debugging */ /* Send debugging output to 'stream', for all of the given debug * channels. To disable debugging, pass 'stream' as NULL and 'mask' * as 0. */ void ne_debug_init(FILE *stream, int mask); /* The current debug mask and stream set by the last call to * ne_debug_init. */ extern int ne_debug_mask; extern FILE *ne_debug_stream; /* Produce debug output if any of channels 'ch' is enabled for * debugging. */ void ne_debug(int ch, const char *, ...) ne_attribute((format(printf, 2, 3))); /* Storing an HTTP status result */ typedef struct { int major_version; int minor_version; int code; /* Status-Code value */ int klass; /* Class of Status-Code (1-5) */ char *reason_phrase; } ne_status; /* NB: couldn't use 'class' in ne_status because it would clash with * the C++ reserved word. */ /* Parse 'status_line' using the the RFC2616 Status-Line grammar. * s->reason_phrase is malloc-allocated if non-NULL, and must be * free'd by the caller. Returns 0 on success, in which case all * fields of '*s' will be set; or -1 on parse error, in which case * '*s' is unmodified. */ int ne_parse_statusline(const char *status_line, ne_status *s); NE_END_DECLS #endif /* NE_UTILS_H */ davix-R_0_5_0/deps/libneon/src/ne_xml.c000066400000000000000000000514071257152637300200720ustar00rootroot00000000000000/* Wrapper interface to XML parser Copyright (C) 1999-2007, 2009, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #pragma GCC diagnostic ignored "-Wpointer-sign" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include "ne_internal.h" #include "ne_alloc.h" #include "ne_xml.h" #include "ne_utils.h" #include "ne_string.h" #if defined(HAVE_EXPAT) /* expat support: */ #ifdef HAVE_XMLPARSE_H #include "xmlparse.h" #else #include #endif typedef XML_Char ne_xml_char; #if !defined(XML_MAJOR_VERSION) #define NEED_BOM_HANDLING #elif XML_MAJOR_VERSION < 2 && XML_MINOR_VERSION == 95 && XML_MICRO_VERSION < 2 #define NEED_BOM_HANDLING #endif #elif defined(HAVE_LIBXML) /* libxml2 support: */ #include #include #include typedef xmlChar ne_xml_char; #if LIBXML_VERSION < 20619 /* 2.6.19 and earlier have broken BOM handling */ #define NEED_BOM_HANDLING #endif #else /* not HAVE_LIBXML */ # error need an XML parser #endif /* not HAVE_EXPAT */ /* Approx. one screen of text: */ #define ERR_SIZE (2048) struct handler { ne_xml_startelm_cb *startelm_cb; /* start-element callback */ ne_xml_endelm_cb *endelm_cb; /* end-element callback */ ne_xml_cdata_cb *cdata_cb; /* character-data callback. */ void *userdata; /* userdata for the above. */ struct handler *next; /* next handler in stack. */ }; #ifdef HAVE_LIBXML static void sax_error(void *ctx, const char *msg, ...); #endif struct element { const ne_xml_char *nspace; ne_xml_char *name; int state; /* opaque state integer */ /* Namespaces declared in this element */ ne_xml_char *default_ns; /* A default namespace */ struct namespace *nspaces; /* List of other namespace scopes */ struct handler *handler; /* Handler for this element */ struct element *parent; /* parent element, or NULL */ }; /* We pass around a ne_xml_parser as the userdata in the parsing * library. This maintains the current state of the parse and various * other bits and bobs. Within the parse, we store the current branch * of the tree, i.e., the current element and all its parents, up to * the root, but nothing other than that. */ struct ne_xml_parser_s { struct element *root; /* the root of the document */ struct element *current; /* current element in the branch */ struct handler *top_handlers; /* always points at the * handler on top of the stack. */ int failure; /* zero whilst parse should continue */ int prune; /* if non-zero, depth within a dead branch */ #ifdef NEED_BOM_HANDLING int bom_pos; #endif #ifdef HAVE_EXPAT XML_Parser parser; char *encoding; #else xmlParserCtxtPtr parser; #endif char error[ERR_SIZE]; }; /* The callback handlers */ static void start_element(void *userdata, const ne_xml_char *name, const ne_xml_char **atts); static void end_element(void *userdata, const ne_xml_char *name); static void char_data(void *userdata, const ne_xml_char *cdata, int len); static const char *resolve_nspace(const struct element *elm, const char *prefix, size_t pfxlen); /* Linked list of namespace scopes */ struct namespace { ne_xml_char *name; ne_xml_char *uri; struct namespace *next; }; #ifdef HAVE_LIBXML /* Could be const as far as we care, but libxml doesn't want that */ static xmlSAXHandler sax_handler = { NULL, /* internalSubset */ NULL, /* isStandalone */ NULL, /* hasInternalSubset */ NULL, /* hasExternalSubset */ NULL, /* resolveEntity */ NULL, /* getEntity */ NULL, /* entityDecl */ NULL, /* notationDecl */ NULL, /* attributeDecl */ NULL, /* elementDecl */ NULL, /* unparsedEntityDecl */ NULL, /* setDocumentLocator */ NULL, /* startDocument */ NULL, /* endDocument */ start_element, /* startElement */ end_element, /* endElement */ NULL, /* reference */ char_data, /* characters */ NULL, /* ignorableWhitespace */ NULL, /* processingInstruction */ NULL, /* comment */ NULL, /* xmlParserWarning */ sax_error, /* xmlParserError */ sax_error, /* fatal error (never called by libxml2?) */ NULL, /* getParameterEntity */ char_data /* cdataBlock */ }; /* empty attributes array to mimic expat behaviour */ static const char *const empty_atts[] = {NULL, NULL}; /* macro for determining the attributes array to pass */ #define PASS_ATTS(atts) (atts ? (const char **)(atts) : empty_atts) /* locker for libxml2 thread safety */ static pthread_once_t libxml_is_initialized = PTHREAD_ONCE_INIT; void initialize_libxml() { xmlInitParser(); } #else #define PASS_ATTS(atts) ((const char **)(atts)) /* XML declaration callback for expat. */ static void decl_handler(void *userdata, const XML_Char *version, const XML_Char *encoding, int standalone) { ne_xml_parser *p = userdata; if (encoding) p->encoding = ne_strdup(encoding); } #endif /* HAVE_LIBXML */ int ne_xml_currentline(ne_xml_parser *p) { #ifdef HAVE_EXPAT return XML_GetCurrentLineNumber(p->parser); #else return p->parser->input->line; #endif } const char *ne_xml_doc_encoding(const ne_xml_parser *p) { #ifdef HAVE_LIBXML return p->parser->encoding; #else return p->encoding; #endif } /* The first character of the REC-xml-names "NCName" rule excludes * "Digit | '.' | '-' | '_' | CombiningChar | Extender"; the XML * parser will not enforce this rule in a namespace declaration since * it treats the entire attribute name as a REC-xml "Name" rule. It's * too hard to check for all of CombiningChar | Digit | Extender here, * but the valid_ncname_ch1 macro catches some of the rest. */ /* Return non-zero if 'ch' is an invalid start character for an NCName: */ #define invalid_ncname_ch1(ch) ((ch) == '\0' || strchr("-.0123456789", (ch)) != NULL) /* Subversion repositories have been deployed which use property names * marshalled as NCNames including a colon character; these should * also be rejected but will be allowed for the time being. */ #define invalid_ncname(xn) (invalid_ncname_ch1((xn)[0])) /* Extract the namespace prefix declarations from 'atts'. */ static int declare_nspaces(ne_xml_parser *p, struct element *elm, const ne_xml_char **atts) { int n; for (n = 0; atts && atts[n]; n += 2) { if (strcmp(atts[n], "xmlns") == 0) { /* New default namespace */ elm->default_ns = ne_strdup(atts[n+1]); } else if (strncmp(atts[n], "xmlns:", 6) == 0) { struct namespace *ns; /* Reject some invalid NCNames as namespace prefix, and an * empty URI as the namespace URI */ if (invalid_ncname(atts[n] + 6) || atts[n+1][0] == '\0') { ne_snprintf(p->error, ERR_SIZE, ("XML parse error at line %d: invalid namespace " "declaration"), ne_xml_currentline(p)); return -1; } /* New namespace scope */ ns = ne_calloc(sizeof(*ns)); ns->next = elm->nspaces; elm->nspaces = ns; ns->name = ne_strdup(atts[n]+6); /* skip the xmlns= */ ns->uri = ne_strdup(atts[n+1]); } } return 0; } /* Expand an XML qualified name, which may include a namespace prefix * as well as the local part. */ static int expand_qname(ne_xml_parser *p, struct element *elm, const ne_xml_char *qname) { const ne_xml_char *pfx; pfx = strchr(qname, ':'); if (pfx == NULL) { struct element *e = elm; /* Find default namespace; guaranteed to terminate as the root * element always has default_ns="". */ while (e->default_ns == NULL) e = e->parent; elm->name = ne_strdup(qname); elm->nspace = e->default_ns; } else if (invalid_ncname(pfx + 1) || qname == pfx) { ne_snprintf(p->error, ERR_SIZE, _("XML parse error at line %d: invalid element name"), ne_xml_currentline(p)); return -1; } else { const char *uri = resolve_nspace(elm, qname, pfx-qname); if (uri) { elm->name = ne_strdup(pfx+1); elm->nspace = uri; } else { ne_snprintf(p->error, ERR_SIZE, ("XML parse error at line %d: undeclared namespace prefix"), ne_xml_currentline(p)); return -1; } } return 0; } /* Called with the start of a new element. */ static void start_element(void *userdata, const ne_xml_char *name, const ne_xml_char **atts) { ne_xml_parser *p = userdata; struct element *elm; struct handler *hand; int state = NE_XML_DECLINE; if (p->failure) return; if (p->prune) { p->prune++; return; } /* Create a new element */ elm = ne_calloc(sizeof *elm); elm->parent = p->current; p->current = elm; if (declare_nspaces(p, elm, atts) || expand_qname(p, elm, name)) { p->failure = 1; return; } /* Find a handler which will accept this element (or abort the parse) */ for (hand = elm->parent->handler; hand && state == NE_XML_DECLINE; hand = hand->next) { elm->handler = hand; state = hand->startelm_cb(hand->userdata, elm->parent->state, elm->nspace, elm->name, PASS_ATTS(atts)); } NE_DEBUG(NE_DBG_XML, "XML: start-element (%d, {%s, %s}) => %d", elm->parent->state, elm->nspace, elm->name, state); if (state > 0) elm->state = state; else if (state == NE_XML_DECLINE) /* prune this branch. */ p->prune++; else /* state < 0 => abort parse */ p->failure = state; } /* Destroys an element structure. */ static void destroy_element(struct element *elm) { struct namespace *this_ns, *next_ns; ne_free(elm->name); /* Free the namespaces */ this_ns = elm->nspaces; while (this_ns != NULL) { next_ns = this_ns->next; ne_free(this_ns->name); ne_free(this_ns->uri); ne_free(this_ns); this_ns = next_ns; } if (elm->default_ns) ne_free(elm->default_ns); ne_free(elm); } /* cdata SAX callback */ static void char_data(void *userdata, const ne_xml_char *data, int len) { ne_xml_parser *p = userdata; struct element *elm = p->current; if (p->failure || p->prune) return; if (elm->handler->cdata_cb) { p->failure = elm->handler->cdata_cb(elm->handler->userdata, elm->state, data, len); NE_DEBUG(NE_DBG_XML, "XML: char-data (%d) returns %d", elm->state, p->failure); } } /* Called with the end of an element */ static void end_element(void *userdata, const ne_xml_char *name) { ne_xml_parser *p = userdata; struct element *elm = p->current; if (p->failure) return; if (p->prune) { if (p->prune-- > 1) return; } else if (elm->handler->endelm_cb) { p->failure = elm->handler->endelm_cb(elm->handler->userdata, elm->state, elm->nspace, elm->name); if (p->failure) { NE_DEBUG(NE_DBG_XML, "XML: end-element for %d failed with %d.", elm->state, p->failure); } } NE_DEBUG(NE_DBG_XML, "XML: end-element (%d, {%s, %s})", elm->state, elm->nspace, elm->name); /* move back up the tree */ p->current = elm->parent; p->prune = 0; destroy_element(elm); } #if defined(HAVE_EXPAT) && XML_MAJOR_VERSION > 1 /* Stop the parser if an entity declaration is hit. */ static void entity_declaration(void *userData, const XML_Char *entityName, int is_parameter_entity, const XML_Char *value, int value_length, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName) { ne_xml_parser *parser = userData; NE_DEBUG(NE_DBG_XMLPARSE, "XML: entity declaration [%s]. Failing.", entityName); XML_StopParser(parser->parser, XML_FALSE); } #elif defined(HAVE_EXPAT) /* A noop default_handler. */ static void default_handler(void *userData, const XML_Char *s, int len) { } #endif /* Find a namespace definition for 'prefix' in given element, where * length of prefix is 'pfxlen'. Returns the URI or NULL. */ static const char *resolve_nspace(const struct element *elm, const char *prefix, size_t pfxlen) { const struct element *s; /* Search up the tree. */ for (s = elm; s != NULL; s = s->parent) { const struct namespace *ns; /* Iterate over defined spaces on this node. */ for (ns = s->nspaces; ns != NULL; ns = ns->next) { if (strlen(ns->name) == pfxlen && memcmp(ns->name, prefix, pfxlen) == 0) return ns->uri; } } return NULL; } const char *ne_xml_resolve_nspace(ne_xml_parser *parser, const char *prefix, size_t length) { if (prefix) { return resolve_nspace(parser->current, prefix, length); } else { struct element *e = parser->current; while (e->default_ns == NULL) e = e->parent; return e->default_ns; } } ne_xml_parser *ne_xml_create(void) { ne_xml_parser *p = ne_calloc(sizeof *p); /* Placeholder for the root element */ p->current = p->root = ne_calloc(sizeof *p->root); p->root->default_ns = ""; p->root->state = 0; strcpy(p->error, _("Unknown error")); #ifdef HAVE_EXPAT p->parser = XML_ParserCreate(NULL); if (p->parser == NULL) { abort(); } XML_SetElementHandler(p->parser, start_element, end_element); XML_SetCharacterDataHandler(p->parser, char_data); XML_SetUserData(p->parser, (void *) p); XML_SetXmlDeclHandler(p->parser, decl_handler); /* Prevent the "billion laughs" attack against expat by disabling * internal entity expansion. With 2.x, forcibly stop the parser * if an entity is declared - this is safer and a more obvious * failure mode. With older versions, installing a noop * DefaultHandler means that internal entities will be expanded as * the empty string, which is also sufficient to prevent the * attack. */ #if XML_MAJOR_VERSION > 1 XML_SetEntityDeclHandler(p->parser, entity_declaration); #else XML_SetDefaultHandler(p->parser, default_handler); #endif #else /* HAVE_LIBXML */ pthread_once(&libxml_is_initialized, initialize_libxml); p->parser = xmlCreatePushParserCtxt(&sax_handler, (void *)p, NULL, 0, NULL); if (p->parser == NULL) { abort(); } #if LIBXML_VERSION < 20602 p->parser->replaceEntities = 1; #else /* Enable expansion of entities, and disable network access. */ xmlCtxtUseOptions(p->parser, XML_PARSE_NOENT | XML_PARSE_NONET); #endif #endif /* HAVE_LIBXML || HAVE_EXPAT */ return p; } void ne_xml_push_handler(ne_xml_parser *p, ne_xml_startelm_cb *startelm_cb, ne_xml_cdata_cb *cdata_cb, ne_xml_endelm_cb *endelm_cb, void *userdata) { struct handler *hand = ne_calloc(sizeof(struct handler)); hand->startelm_cb = startelm_cb; hand->cdata_cb = cdata_cb; hand->endelm_cb = endelm_cb; hand->userdata = userdata; /* If this is the first handler registered, update the * base pointer too. */ if (p->top_handlers == NULL) { p->root->handler = hand; p->top_handlers = hand; } else { p->top_handlers->next = hand; p->top_handlers = hand; } } int ne_xml_parse_v(void *userdata, const char *block, size_t len) { ne_xml_parser *p = userdata; return ne_xml_parse(p, (const ne_xml_char *)block, len); } #define BOM_UTF8 "\xEF\xBB\xBF" /* UTF-8 BOM */ int ne_xml_parse(ne_xml_parser *p, const char *block, size_t len) { int ret, flag; /* duck out if it's broken */ if (p->failure) { NE_DEBUG(NE_DBG_XMLPARSE, "XML: Failed; ignoring %" NE_FMT_SIZE_T " bytes.\n", len); return p->failure; } if (len == 0) { flag = -1; block = ""; NE_DEBUG(NE_DBG_XMLPARSE, "XML: End of document."); } else { NE_DEBUG(NE_DBG_XMLPARSE, "XML: Parsing %" NE_FMT_SIZE_T " bytes.", len); flag = 0; } #ifdef NEED_BOM_HANDLING if (p->bom_pos < 3) { NE_DEBUG(NE_DBG_XMLPARSE, "Checking for UTF-8 BOM."); while (len > 0 && p->bom_pos < 3 && block[0] == BOM_UTF8[p->bom_pos]) { block++; len--; p->bom_pos++; } if (len == 0) return 0; if (p->bom_pos == 0) { p->bom_pos = 3; /* no BOM */ } else if (p->bom_pos > 0 && p->bom_pos < 3) { strcpy(p->error, _("Invalid Byte Order Mark")); return p->failure = 1; } } #endif /* Note, don't write a parser error if p->failure, since an error * will already have been written in that case. */ #ifdef HAVE_EXPAT ret = XML_Parse(p->parser, block, len, flag); NE_DEBUG(NE_DBG_XMLPARSE, "XML: XML_Parse returned %d", ret); if (ret == 0 && p->failure == 0) { ne_snprintf(p->error, ERR_SIZE, "XML parse error at line %" NE_FMT_XML_SIZE ": %s", XML_GetCurrentLineNumber(p->parser), XML_ErrorString(XML_GetErrorCode(p->parser))); p->failure = 1; NE_DEBUG(NE_DBG_XMLPARSE, "XML: Parse error: %s", p->error); } #else ret = xmlParseChunk(p->parser, block, len, flag); NE_DEBUG(NE_DBG_XMLPARSE, "XML: xmlParseChunk returned %d", ret); /* Parse errors are normally caught by the sax_error() callback, * which clears p->valid. */ if (p->parser->errNo && p->failure == 0) { ne_snprintf(p->error, ERR_SIZE, "XML parse error at line %d", ne_xml_currentline(p)); p->failure = 1; NE_DEBUG(NE_DBG_XMLPARSE, "XML: Parse error: %s", p->error); } #endif return p->failure; } int ne_xml_failed(ne_xml_parser *p) { return p->failure; } void ne_xml_destroy(ne_xml_parser *p) { struct element *elm, *parent; struct handler *hand, *next; /* Free up the handlers on the stack: the root element has the * pointer to the base of the handler stack. */ for (hand = p->root->handler; hand!=NULL; hand=next) { next = hand->next; ne_free(hand); } /* Clean up remaining elements */ for (elm = p->current; elm != p->root; elm = parent) { parent = elm->parent; destroy_element(elm); } /* free root element */ ne_free(p->root); #ifdef HAVE_EXPAT XML_ParserFree(p->parser); if (p->encoding) ne_free(p->encoding); #else xmlFreeParserCtxt(p->parser); #endif ne_free(p); } void ne_xml_set_error(ne_xml_parser *p, const char *msg) { ne_snprintf(p->error, ERR_SIZE, "%s", msg); } #ifdef HAVE_LIBXML static void sax_error(void *ctx, const char *msg, ...) { ne_xml_parser *p = ctx; va_list ap; char buf[1024]; va_start(ap, msg); ne_vsnprintf(buf, 1024, msg, ap); va_end(ap); if (p->failure == 0) { ne_snprintf(p->error, ERR_SIZE, _("XML parse error at line %d: %s"), p->parser->input->line, buf); p->failure = 1; } } #endif const char *ne_xml_get_error(ne_xml_parser *p) { return p->error; } const char * ne_xml_get_attr(ne_xml_parser *p, const char **attrs, const char *nspace, const char *name) { int n; for (n = 0; attrs[n] != NULL; n += 2) { char *pnt = strchr(attrs[n], ':'); if (!nspace && !pnt && strcmp(attrs[n], name) == 0) { return attrs[n+1]; } else if (nspace && pnt) { /* If a namespace is given, and the local part matches, * then resolve the namespace and compare that too. */ if (strcmp(pnt + 1, name) == 0) { const char *uri = resolve_nspace(p->current, attrs[n], pnt - attrs[n]); if (uri && strcmp(uri, nspace) == 0) return attrs[n+1]; } } } return NULL; } int ne_xml_mapid(const struct ne_xml_idmap map[], size_t maplen, const char *nspace, const char *name) { size_t n; for (n = 0; n < maplen; n++) if (strcmp(name, map[n].name) == 0 && strcmp(nspace, map[n].nspace) == 0) return map[n].id; return 0; } davix-R_0_5_0/deps/libneon/src/ne_xml.h000066400000000000000000000152261257152637300200760ustar00rootroot00000000000000/* neon XML parser interface Copyright (C) 1999-2007, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_XML_H #define NE_XML_H #include /* for size_t */ #include "ne_defs.h" NE_BEGIN_DECLS /* The neon XML interface filters a streamed XML tree through a stack * of SAX "handlers". A handler is made up of three callbacks * (start-element, char-data, end-element). Each start-element event * is passed to each handler in the stack in turn until one until one * accepts the element. This handler then receives subsequent * char-data and end-element events for the element. * * For each new start-element event, the search up the handler stack * begins with the handler for the parent element (for the root * element, at the base of the stack). * * For each accepted element, a "state" integer is stored, which is * passed to the corresponding char-data and end-element callbacks for * the element. This integer is also passed to the start-element * callback of child elements so they can determine context. * * If no handler in the stack accepts a particular element, it (and * its children, if any) is ignored. */ #define NE_XML_DECLINE (0) #define NE_XML_ABORT (-1) /* A start-element callback for element with given namespace/name. * The callback may return: * <0 => abort the parse (NE_XML_ABORT) * 0 => decline this element (NE_XML_DECLINE) * >0 => accept this element; value is state for this element. * * The 'parent' integer is the state returned by the handler of the * parent element. The attributes array gives name/value pairs * in atts[n] and atts[n+1] from n=0 up to atts[n]==NULL. */ typedef int ne_xml_startelm_cb(void *userdata, int parent, const char *nspace, const char *name, const char **atts); /* state for the root element */ #define NE_XML_STATEROOT (0) /* Character data callback; may return non-zero to abort the parse. */ typedef int ne_xml_cdata_cb(void *userdata, int state, const char *cdata, size_t len); /* End element callback; may return non-zero to abort the parse. */ typedef int ne_xml_endelm_cb(void *userdata, int state, const char *nspace, const char *name); typedef struct ne_xml_parser_s ne_xml_parser; /* Create an XML parser. */ ne_xml_parser *ne_xml_create(void); /* Push a new handler on the stack of parser 'p'. 'cdata' and/or * 'endelm' may be NULL; startelm must be non-NULL. */ void ne_xml_push_handler(ne_xml_parser *p, ne_xml_startelm_cb *startelm, ne_xml_cdata_cb *cdata, ne_xml_endelm_cb *endelm, void *userdata); /* ne_xml_failed returns non-zero if there was an error during * parsing, or zero if the parse completed successfully. The return * value is equal to that of the last ne_xml_parse() call for this * parser object. */ int ne_xml_failed(ne_xml_parser *p); /* Set error string for parser. (The string may be truncated * internally). */ void ne_xml_set_error(ne_xml_parser *p, const char *msg); /* Return the error string (and never NULL). After ne_xml_failed * returns >0, this will describe the parse error. Otherwise it will * be a default error string. */ const char *ne_xml_get_error(ne_xml_parser *p); /* Parse the given block of input of length len. Parser must be * called with len=0 to signify the end of the document (for that * case, the block argument is ignored). Returns zero on success, or * non-zero on error: for an XML syntax error, a positive number is * returned; if parsing is aborted by a caller-supplied callback, that * callback's return value is returned. */ int ne_xml_parse(ne_xml_parser *p, const char *block, size_t len); /* As ne_xml_parse, casting (ne_xml_parser *)userdata internally. * (This function can be passed to ne_add_response_body_reader) */ int ne_xml_parse_v(void *userdata, const char *block, size_t len); /* Return current line of document during parsing or after parsing is * complete. */ int ne_xml_currentline(ne_xml_parser *p); /* From a start_element callback which was passed 'attrs' using given * parser, return attribute of given name and namespace. If nspace is * NULL, no namespace resolution is performed. Note that this call is * context-specific; if called outside a start_element callback, * behaviour is undefined. */ const char *ne_xml_get_attr(ne_xml_parser *parser, const char **attrs, const char *nspace, const char *name); /* From a start_element callback, resolve a given XML Namespace * prefix, if defined. Given a non-NULL prefix, returns the namespace * URI which corresponds to the prefix 'prefix' (of length 'length'), * or NULL if no such namespace prefix is defined. Given a NULL * prefix, returns the default namespace URI or the empty string if * none is defined. Note that this call is context-specific; if * called outside a start_element callback, behaviour is undefined. */ const char *ne_xml_resolve_nspace(ne_xml_parser *parser, const char *prefix, size_t length); /* Return the encoding of the document being parsed. May return NULL * if no encoding is defined or if the XML declaration has not yet * been parsed. */ const char *ne_xml_doc_encoding(const ne_xml_parser *p); /* Destroy the parser object. */ void ne_xml_destroy(ne_xml_parser *p); /* A utility interface for mapping {nspace, name} onto an integer. */ struct ne_xml_idmap { const char *nspace, *name; int id; }; /* Return the size of an idmap array */ #define NE_XML_MAPLEN(map) (sizeof(map) / sizeof(struct ne_xml_idmap)) /* Return the 'id' corresponding to {nspace, name}, or zero. */ int ne_xml_mapid(const struct ne_xml_idmap map[], size_t maplen, const char *nspace, const char *name); /* media type, appropriate for adding to a Content-Type header */ #define NE_XML_MEDIA_TYPE "application/xml" NE_END_DECLS #endif /* NE_XML_H */ davix-R_0_5_0/deps/libneon/src/ne_xmlreq.c000066400000000000000000000061611257152637300205770ustar00rootroot00000000000000/* XML/HTTP response handling Copyright (C) 2004-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "config.h" #include #include #include "ne_internal.h" #include "ne_xmlreq.h" #include "ne_basic.h" #include "ne_string.h" /* Handle an XML response parse error, setting session error string * and closing the connection. */ static int parse_error(ne_session *sess, ne_xml_parser *parser) { ne_set_error(sess, _("Could not parse response: %s"), ne_xml_get_error(parser)); ne_close_connection(sess); return NE_ERROR; } int ne_xml_parse_response(ne_request *req, ne_xml_parser *parser) { char buf[8000]; ssize_t bytes; int ret = 0; while ((bytes = ne_read_response_block(req, buf, sizeof buf)) > 0) { ret = ne_xml_parse(parser, buf, bytes); if (ret) return parse_error(ne_get_session(req), parser); } if (bytes == 0) { /* Tell the parser that end of document was reached: */ if (ne_xml_parse(parser, NULL, 0) == 0) return NE_OK; else return parse_error(ne_get_session(req), parser); } else { return NE_ERROR; } } /* Returns non-zero if given content-type is an XML media type, * following the RFC 3023 rules. */ static int media_type_is_xml(const ne_content_type *ctype) { size_t stlen; return (ne_strcasecmp(ctype->type, "text") == 0 && ne_strcasecmp(ctype->subtype, "xml") == 0) || (ne_strcasecmp(ctype->type, "application") == 0 && ne_strcasecmp(ctype->subtype, "xml") == 0) || ((stlen = strlen(ctype->subtype)) > 4 && ne_strcasecmp(ctype->subtype + stlen - 4, "+xml") == 0); } int ne_xml_dispatch_request(ne_request *req, ne_xml_parser *parser) { int ret; do { int parseit = 0; ret = ne_begin_request(req); if (ret) break; if (ne_get_status(req)->klass == 2) { ne_content_type ctype; if (ne_get_content_type(req, &ctype) == 0) { parseit = media_type_is_xml(&ctype); ne_free(ctype.value); } } if (parseit) ret = ne_xml_parse_response(req, parser); else ret = ne_discard_response(req); if (ret == NE_OK) ret = ne_end_request(req); } while (ret == NE_RETRY); return ret; } davix-R_0_5_0/deps/libneon/src/ne_xmlreq.h000066400000000000000000000036651257152637300206120ustar00rootroot00000000000000/* XML/HTTP response handling Copyright (C) 2004-2006, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef NE_XMLREQ_H #define NE_XMLREQ_H #include "ne_request.h" #include "ne_xml.h" NE_BEGIN_DECLS /* Read the HTTP response body using calls to ne_read_response_block * (so must be enclosed by ne_begin_request/ne_end_request calls), and * parse it as an XML document, using the given parser. Returns NE_* * error codes. If an XML parse error occurs, the session error * string is set to the XML parser's error string, and NE_ERROR is * returned. */ int ne_xml_parse_response(ne_request *req, ne_xml_parser *parser); /* Dispatch the HTTP request, parsing the response body as an XML * document using the given parser, if the response status class is * 2xx and an XML media type is specified for the response entity. If * a non-2xx response code is given, or a non-XML media type is * specified, then the response body will be silently discarded. * * Returns NE_* error codes. If an XML parse error occurs, the * session error string is set to the XML parser's error string, and * NE_ERROR is returned. */ int ne_xml_dispatch_request(ne_request *req, ne_xml_parser *parser); NE_END_DECLS #endif /* NE_XMLREQ_H */ davix-R_0_5_0/deps/libneon/src/neon.vers000066400000000000000000000005331257152637300202760ustar00rootroot00000000000000# GNU linker version script for neon. # All symbols in <= 0.28.x use default unversioned. NEON_0_29 { ne_iaddr_raw; ne_sock_writev; ne_sock_fullwritev; ne_sock_set_error; ne_sock_proxy; ne_session_system_proxy; ne_session_socks_proxy; ne_acl3744_set; ne_buffer_qappend; ne_strnqdup; ne_iaddr_parse; }; davix-R_0_5_0/deps/libneon/test/000077500000000000000000000000001257152637300166255ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/test/COPYING000066400000000000000000000430761257152637300176720ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. 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 Appendix: 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) 19yy 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. 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) 19yy 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 Library General Public License instead of this License. davix-R_0_5_0/deps/libneon/test/ChangeLog000066400000000000000000001330551257152637300204060ustar00rootroot00000000000000Wed Aug 25 21:05:28 2004 Joe Orton * cookies.c: Removed. * Makefile.in: Updated. Wed Aug 25 19:47:28 2004 Joe Orton * socket.c (do_connect, begin): Simplify do_connect use. Wed Aug 25 18:28:19 2004 Joe Orton * xml.c (matches, fail_parse): Test for UTF-8 BOM handling. Mon Jul 5 18:41:07 2004 Joe Orton * basic.c (content_type): Test for correct default charset for text/xml content-type by RFC3280. Mon Jul 5 10:59:17 2004 Joe Orton Add XFAIL regression tests for trio of ne_compress.c bugs: * compress.c (reader): Validate that a size=0 call comes only after the expected response data, and use struct string. (do_fetch): Pass a struct string to reader and adapt for failure logic. (auth_cb, retry_compress_helper, retry_compress, retry_notcompress): New tests. Sun Jul 4 21:55:00 2004 Joe Orton * utils.c (serve_sstring_slowly, serve_sstring): Moved from sockets.c, renamed from serve_string_slowly, serve_sstring. * sockets.c: All callers updated. Sun May 2 21:16:45 2004 Joe Orton * util-tests.c (regress_dates): Add regression tests. Wed Apr 14 10:45:43 2004 Joe Orton * props.c (regress, patch_regress): Add regression tests for CAN-2004-0179 issues. Thu Apr 8 13:57:04 2004 Joe Orton * largefile.c (read_large_response): Go faster: turn off debugging during request dispatch. Wed Apr 7 13:39:37 2004 Joe Orton * auth.c (basic): Add some multi-scheme challenges. Wed Apr 7 13:14:16 2004 Joe Orton * request.c (s_progress): Use NE_FMT_OFF_T for printing off_t's throughout. Sun Feb 22 23:38:05 2004 Joe Orton * request.c (expect_100_once, serve_100_once): Adjust for new 100-continue interface. (expect_100_nobody): New test. Sun Feb 22 20:39:15 2004 Joe Orton * cookies.c (parsing): Use ne_cookie_empty_cache. Sun Feb 22 17:28:41 2004 Joe Orton * props.c (pfind_simple): Test for whitespace handling. Sun Feb 22 16:31:52 2004 Joe Orton * auth.c (basic): Test handling of Basic challenge in presence of multiple challenges. Sun Feb 15 12:34:13 2004 Joe Orton * makekeys.sh, openssl.conf: Create new utf8subj.cert, bmpsubj.cert, t61subj.cert certificates. * ssl.c (dname_readable): Test that ne_ssl_readable_dname always gives back UTF-8. Sat Feb 14 21:59:17 2004 Joe Orton * xml.c (fail_parse): Add tests for invalid NCNames in namespace prefix declaration and as element names. Sun Jan 25 15:21:56 2004 Joe Orton * largefile.c (serve_large_response, read_large_response): New test. Sat Jan 24 18:10:14 2004 Joe Orton * Makefile.in: Fix test suite for 'make' implementatinos which don't handle single-suffix inference rules. Sat Jan 3 14:10:14 2004 Joe Orton * largefile.c (send_high_offset): Renamed from send_large_file. Sat Jan 3 13:57:16 2004 Joe Orton * Makefile.in (BASIC_TESTS): Add cookies. Thu Jan 1 17:42:30 2004 Joe Orton * util-tests.c (support): Check for NE_FEATURE_LFS. * largefile.c: New file. * Makefile.in: Add lfs-check, largefile, largefile.lo targets. Sat Nov 15 08:04:22 2003 Joe Orton * request.c (idna_hostname, dup_header, serve_check_host): New test. Fri Nov 14 14:06:57 2003 Joe Orton * util-tests.c (support): Test for NE_FEATURE_IDNA. Fri Nov 14 11:26:29 2003 Joe Orton * acl.c: Remove NEON_NODAV condition. * stubs.c: Use new NE_HAVE_* conditions. * util-tests.c (supports): Test new ne_has_support interface. Thu Nov 13 20:33:44 2003 Joe Orton * request.c (no_body_205): New test. Tue Nov 11 20:36:43 2003 Joe Orton Adjust for ne_xml_valid->ne_xml_failure API change. * xml.c (chardata, startelm_abort, endelm_abort, parse_match): Check for propagation of negative failure codes. (fail_parse): Check for positive failure code. (attributes): Use ne_xml_failure. Sat Oct 25 00:11:29 2003 Joe Orton * ssl.c (fail_truncated_eof): Remove test. Tue Oct 21 20:29:46 2003 Joe Orton * ssl.c (fail_tunnel, proxy_tunnel): Fix non-C89 code, Radu Greab. Thu Oct 9 19:42:13 2003 Joe Orton * socket.c (ssl_closure): Fix occassional spurious errors. Tue Oct 7 20:23:35 2003 Joe Orton * ssl.c (ssl_server): Handle several requests if required. (tunnel_header): New function. (serve_tunnel): Fail with a 500 if the request included an Authenticate header; take an ssl_server_args pointer as userdata. (fail_tunnel, proxy_tunnel): Adjust accordingly. (apt_post_send): Adjust for 401 check. (auth_tunnel_creds): New test. Wed Oct 1 00:30:25 2003 Joe Orton * ssl.c (simple_sslv2): Regression test. (ssl_server): Create SSL_CTX locally; optionally create an SSLv2-only server. (init_ssl): Do not create the SSL_CTX. Wed Sep 17 19:57:22 2003 Joe Orton * ssl.c: Refactor around single SSL server function. (ssl_server): Combination of do_ssl_response and old serve_* functions. All callers updated. Sun Sep 14 12:27:22 2003 Joe Orton * socket.c (write_reset, read_reset): Skip if no RESET was returned. Sun Sep 14 11:01:08 2003 Joe Orton * Makefile.in: Fix building the 'resolve' tool. Sat Sep 6 12:29:53 2003 Joe Orton * makekeys.sh, openssl.conf: Generate altname5.cert with an IPv4 address in the subjectAltName attribute. * ssl.c (ipaddr_altname): Test for IPv4 address in subjectAltName. Sat Sep 6 12:28:55 2003 Joe Orton * Makefile.in: Clear the SUFFIXES list; use standard make syntax; fix build of 'basic' on some platforms. Sat Aug 30 18:59:24 2003 Joe Orton * Makefile.in: Rewrite to use libtool to build object files and libtest. * run.sh: Don't set LD_LIBRARY_PATH. Wed Jul 23 23:25:39 2003 Joe Orton * compress.c (do_fetch): Check for response truncation for success case. (fail_corrupt1, fail_corrupt2): New tests. Sat Jun 21 12:59:49 2003 Joe Orton * request.c (versions): Fix and enable test. Wed Jun 18 20:09:59 2003 Joe Orton * request.c (is_alive): Adapt for new socket API. * socket.c (do_connect, addr_connect): Likewise. Tue May 20 20:14:03 2003 Joe Orton * ssl.c (cert_fingerprint): Fix for VPATH builds. Sat May 10 17:13:05 2003 Joe Orton * xml.c (matches): Add regression test for prefix matching bug fixed in 0.18.0. Sat Apr 26 19:22:29 2003 Joe Orton * request.c (any_te_header): New function. Wed Apr 23 18:24:19 2003 Joe Orton * stubs.c (stub_ssl): Test ne_ssl_cert_import, ne_ssl_cert_export, ne_ssl_cert_write stubs. Wed Apr 23 14:05:38 2003 Joe Orton * ssl.c (read_write): New function. Wed Apr 23 00:34:44 2003 Joe Orton * ssl.c (cache_cert, verify_cache): New functions. Wed Apr 23 00:14:14 2003 Joe Orton * ssl.c (any_ssl_request): Free the cert after passing it to ne_ssl_trust_cert. Tue Apr 22 23:24:33 2003 Joe Orton * string-tests.c (unbase64): Improve coverage. Tue Apr 22 20:25:15 2003 Joe Orton * ssl.c (import_export, flatten_pem, cert_compare): New functions. Tue Apr 22 18:32:43 2003 Joe Orton * string-tests.c (b64_check, unbase64): New functions. (base64): Use b64_check. Tue Apr 22 15:54:04 2003 Joe Orton * string-tests.c (base64): Test decoding binary data which contains bytes with the high bit set. Tue Apr 22 14:18:03 2003 Joe Orton * string-tests.c (base64): Moved here... * util-tests.c (base64): ...from here. Tue Apr 22 13:17:48 2003 Joe Orton * ssl.c (just_serve_string, fail_not_ssl): New functions. Tue Apr 22 13:09:13 2003 Joe Orton * stubs.c (stub_ssl): Test ne_ssl_cert_validity stub. Tue Apr 22 11:35:10 2003 Joe Orton * request.c (versions): Run test as XFAIL. Tue Apr 22 11:33:43 2003 Joe Orton * util-tests.c (version_string): New function. Tue Apr 22 09:23:27 2003 Joe Orton * ssl.c (check_validity, cert_validity): New functions. Mon Apr 21 19:45:39 2003 Joe Orton * util-tests.c (digest_md5): Replace ne_md5_buffer. (md5): Use digest_md5; test 500-byte string. Mon Apr 21 18:38:02 2003 Joe Orton * xml.c (fail_parse): Call ne_xml_parse with length=0 finish parse. Mon Apr 21 17:18:45 2003 Joe Orton * props.c: Add tests for ne_207.h interface and ne_simple_propfind from ne_props.h. * xml.c: Add tests for new XML interface. * Makefile.in: Run props tests before lock since the latter is implemented using the former. Mon Apr 7 22:27:18 2003 Joe Orton * stubs.c (stub_ssl): Test for ne_ssl_cert_identity stub. Mon Apr 7 22:17:56 2003 Joe Orton * ssl.c (cert_fingerprint): Renamed from fingerprint. (check_identity, cert_identities): New functions. Sun Apr 6 20:18:30 2003 Joe Orton * stubs.c (stub_ssl): Adjust for new clicert API. Sun Apr 6 20:12:48 2003 Joe Orton * ssl.c (dname_compare): Renamed from comparisons. (dname_readable): New function. * makekeys.sh: Create justmail.cert. Sun Apr 6 20:00:18 2003 Joe Orton * ssl.c (keypw_prompt): Removed function. (init, load_client_cert, client_cert_provided): Adapt for new clicert API. (ccert_unencrypted): New function. Fri Apr 4 22:34:12 2003 Joe Orton * request.c (fail_request_with_error): Refactored from fail_request; check for a particular error string. (fail_request): Use fail_request_with_error. (invalid_response_gives_error): New function. (fail_long_header): Use it. (fail_corrupt_chunks): New function. Sat Mar 29 14:39:20 2003 Joe Orton * ssl.c (comparisons): New function. * stubs.c (stub_ssl): Test ne_ssl_dname_cmp. Sat Mar 29 13:58:37 2003 Joe Orton * makekeys.sh: Generate noclient.p12. * ssl.c (load_client_cert): Test ne_ssl_clicert_name. * stubs.c (stub_ssl): Check for ne_ssl_clicert_name stub. Sat Mar 29 13:31:35 2003 Joe Orton * ssl.c (load_client_cert): Test ne_ssl_clicert_owner. Fri Mar 28 22:13:55 2003 Joe Orton * ssl.c (fingerprint): New function. * stubs.c (stub_ssl): Check for ne_ssl_cert_digest stub. Wed Mar 26 22:52:15 2003 Joe Orton * ssl.c (fail_missing_CN): New function. * makekeys.sh: Generate missingcn.cert. * openssl.conf: Allow commonName to be omitted from CSR. Wed Mar 26 22:41:48 2003 Joe Orton * ssl.c (load_server_certs): Renamed from load_ca; test loading non-existent file. Wed Mar 26 20:38:08 2003 Joe Orton * stubs.c (stub_ssl): Updated for new SSL interface. Tue Mar 25 20:32:07 2003 Joe Orton Update tests for changes to SSL interface: * socket.c (init_ssl): Use ne_ssl_context_create, ne_ssl_cert_read, ne_ssl_ctx_trustcert. (begin): Use ne_sock_connect_ssl. * ssl.c (serve_ssl_chained, trust_default_ca, load_client_cert, check_dname, check_cert_dnames, check_cert, check_chain, parse_chain, cc_check_dnames, cc_provided_dnames): New functions. (serve_ccert): Always trust SERVER_CERT; optionally call SSL_CTX_set_client_CA_list. (any_ssl_request, load_ca, fail_truncated_eof): Use ne_ssl_cert_read and ne_ssl_trust_cert. (keypw_prompt): Fail if userdata is NULL. (fail_load_ccerts, load_pkcs12_ccert, load_pem_ccert, check_DNs): Removed functions. (parse_cert): Use check_cert. (client_cert_provided, client_cert_pkcs12): Rewritten for new API. * makekeys.sh: Generate calist.pem, unclient.p12. Wed Mar 12 22:36:27 2003 Joe Orton * redirect.c (simple): Fold in tests for 30[237] redirects for better coverage. (no_redirect): Another test for _location returning NULL. Wed Mar 12 22:29:45 2003 Joe Orton * redirect.c (process_redir): Factored out from check_redir. (no_redirect): New function. Sun Mar 9 17:46:37 2003 Joe Orton * lock.c (fail_discover): New function. Sat Mar 1 10:53:58 2003 Joe Orton * uri-tests.c (authinfo): Removed. (escapes): Test nothing-to-escape and invalid URI cases. (compares): Gain 100% branch coverage in ne_path_compare. (default_port): Test unknown scheme case. (parse): Test authinfo here, and some edge cases. (unparse): Fill in port if default. Sat Mar 1 09:20:42 2003 Joe Orton * socket.c (multi_init): New function. Sat Mar 1 08:04:09 2003 Joe Orton * string-tests.c (cleaner): New function. Wed Feb 26 22:13:14 2003 Joe Orton * request.c (fail_eof_chunk, fail_eof_badclen): New tests. Wed Feb 26 21:54:39 2003 Joe Orton * util-tests.c (support): New function. (bad_sl, accept_sl): More status-lines. Tue Feb 25 21:06:18 2003 Joe Orton * ssl.c (do_ssl_response): Fail if response contains "Proxy-Authorization" header. (apt_post_send, apt_creds, auth_proxy_tunnel): New functions. Thu Nov 28 21:25:01 2002 Joe Orton * request.c (te_over_clength2): New test. Sun Nov 17 18:59:04 2002 Joe Orton * socket.c (addr_make_v4, addr_make_v6, addr_compare): New functions. Fri Oct 11 00:49:01 2002 Joe Orton * props.c (regress): Moved from regress.c:propfind_segv; add regression test for ne_props.c segfault fixed in rev 1.83. * regress.c: Removed. Tue Oct 8 20:06:55 2002 Joe Orton * xml.c (matches): Add tests that entities in attribute values are dereferenced by the XML parser. Fri Oct 4 17:10:19 2002 Joe Orton * request.c (no_body_bad_clength, no_body_empty_clength): New tests. (expect_no_body): Use better paths in the requests. Tue Sep 24 21:27:33 2002 Joe Orton * request.c (fail_long_header, versions, hook_create_req): New functions. Tue Sep 17 21:08:17 2002 Joe Orton * openssl.conf (neonca): Make 'countryName' optional in CA policy. (reqDN.CNfirst): New section. * makekeys.sh: Generate 'cnfirst.cert', which has commonName as first attribute in subject DN. * ssl.c (commonName_first): New function. Tue Sep 10 21:11:18 2002 Joe Orton * request.c (fail_double_lookup): New function. Sun Aug 25 23:16:33 2002 Joe Orton * ssl.c (do_ssl_response): Add 'unclean' argument. (all callers changed). (serve_response_unclean, empty_truncated_eof, fail_truncated_eof): New functions. Sun Aug 25 19:16:00 2002 Joe Orton * socket.c (resolve_numeric): Test ne_addr_print too. Sun Aug 25 13:39:37 2002 Joe Orton * resolve.c: New file. Sun Aug 25 11:25:12 2002 Joe Orton * request.c (is_alive): Update for new ne_addr_* interface. Sun Aug 25 08:31:16 2002 Joe Orton * socket.c (serve_truncate, ssl_truncate): New functions. Sun Aug 25 08:28:17 2002 Joe Orton * socket.c (do_connect): New function; use new ne_sock_connect/ne_addr interface. (begin) [SOCKET_SSL, !SOCKET_SSL]: Use do_connect. (resolve_numeric): Adjust for new ne_addr interface. (resolve_ipv6): Disable test. Sat Aug 24 08:50:06 2002 Joe Orton * request.c (fail_statusline): New function. Fri Aug 23 22:52:38 2002 Joe Orton * ssl.c (init): FAILHARD if initialization fails. Wed Aug 21 13:29:58 2002 Joe Orton * uri-tests.c (null_uri): Removed test. (parse): More tests including IPv6 address tests; use ONCMP macro. (failparse): New function. (unparse): Add URI with IPv6 address. Wed Aug 21 13:28:37 2002 Joe Orton * socket.c (resolve_ipv6): New function. Mon Aug 19 16:59:46 2002 Joe Orton * socket.c (resolve): Adapt for new ne_addr_resolve interface. (resolve_numeric): New test. * request.c (is_alive): Use new ne_addr_resolve interface. Mon Aug 19 16:57:53 2002 Joe Orton * socket.c (begin): Fix handling of connect failure. (TO_BEGIN): Handle errors from to_begin properly. Sun Aug 18 23:37:34 2002 Joe Orton * string-tests.c (str_errors): Check return value and behaviour when error string is truncated, an Sun Aug 18 23:31:51 2002 Joe Orton * util-tests.c (str_errors): Moved to... * string-tests.c (str_errors): here. Sun Aug 18 23:11:28 2002 Joe Orton * string-tests.c (strnzcpy): New function. Sun Aug 18 08:18:24 2002 Joe Orton * ssl.c (caseless_match): New function. * makekeys.sh: Create caseless.cert. Sun Aug 18 08:12:32 2002 Joe Orton * ssl.c (notdns_altname): New function. * makekeys.sh: Create altname4.cert. * openssl.conf (altExt4): New section. Sun Aug 18 07:42:30 2002 Joe Orton * ssl.c (multi_commonName): New function. * openssl.conf (req): Use distinguished_name section as specificied by $REQDN. (reqDN.doubleCN): New section. * makekeys.sh: Set $REQDN; create twocn.cert. Sun Aug 18 00:47:19 2002 Joe Orton * ssl.c (accept_signed_cert): New function, factored out from simple. (simple): Use accept_signed_cert. (subject_altname, two_subject_altname, two_subject_altname2): New function. * openssl.conf: Add extension sections altExt, altExt2, altExt3. * makekeys.sh: Generate altname.cert, altname2.cert, altname3.cert. Sat Aug 17 18:41:42 2002 Joe Orton * makekeys.sh (csr_fields): New function; generate output for `openssl req'. Sat Aug 17 18:27:36 2002 Joe Orton * makekeys.sh: Add CA and REQ variables to simplify OpenSSL invocation. Pass -config to req rather than relying on installed default configuration. * openssl.conf: Add `req' and `reqDN' sections to allow use with `openssl req' command. Add CA basic constraint extention to certificates used. Sat Aug 10 10:42:57 2002 Joe Orton * makekeys.sh: Use openssl binary as ${OPENSSL}. * Makefile.in: Pick up OPENSSL from configure, and pass it through to makekeys.sh. Sat Aug 10 10:18:15 2002 Joe Orton * socket.c (begin): Don't use run-time initialization. * request.c (s_progress): Fix warnings on FreeBSD. Mon Aug 5 21:08:24 2002 Joe Orton * ssl.c (ccert_provider, client_cert_provided): New functions. (fail_load_ccerts): Enable function. Sun Aug 4 22:32:43 2002 Joe Orton * request.c (serve_abort, retry_after_abort): New functions. Sun Aug 4 13:28:47 2002 Joe Orton * request.c (continued_header): New function. Sun Aug 4 12:54:52 2002 Joe Orton * socket.c [SOCKET_SSL] (ssl_closure): New function; use instead of read_reset, write_reset for SOCKET_SSL build. Sun Aug 4 12:27:34 2002 Joe Orton Build socket.c twice, once for testing over SSL connections: * Makefile.in (socket-ssl.o, socket-ssl): New targets. (SSL_TESTS): Include socket-ssl target. * socket.c [SOCKET_SSL] (init_ssl, wrap_serve): New functions. [SOCKET_SSL] (begin): Alternate implementation. Sat Aug 3 22:20:59 2002 Joe Orton * session.c (privates): New function. Sat Aug 3 22:20:14 2002 Joe Orton * auth.c (fail_auth_cb, tunnel_regress): New function. Sat Aug 3 22:12:48 2002 Joe Orton * auth.c (forget_regress): New function. Sun Jul 28 12:24:02 2002 Joe Orton * lock.c (lock_timeout, submit_test, lock_shared): Use ne_concat, not CONCAT? macros. * ssl.c (init, fail_expired, fail_notvalid): Likewise. Thu Jul 25 00:04:47 2002 Joe Orton * string-tests.c (buf_concat, buf_concat2, buf_concat3): Renamed from concat, concat1, concat3). (concat): New function. Sun Jul 14 11:42:03 2002 Joe Orton * util-tests.c (versioning): New function. Thu Jul 11 17:24:29 2002 Joe Orton * request.c (no_headers): New function. Wed Jul 10 22:58:01 2002 Joe Orton * utils.c (any_2xx_request_body): New function. Wed Jul 10 22:44:12 2002 Joe Orton * request.c (ptimeout_eof, ptimeout_eof2, close_not_retried, serve_close2): New functions. (abort_respbody): Rejoin child earlier for reliable results. Sun Jul 7 12:17:11 2002 Joe Orton * socket.c (expect_eof): Better error reporting. (good_close): Split from finish(). (finish): Use good_close. (expect_write_closed, write_reset, read_reset): Add tests that an ECONNRESET is treated as a SOCK_CLOSED failure. Sun Jul 7 08:38:12 2002 Joe Orton * utils.c (serve_response): Use discard_body(). Sun Jul 7 08:28:56 2002 Joe Orton * socket.c (serve_expect, full_write, small_writes, large_writes, echo_server, echo_expect, echo_lines): New functions. Sat Jul 6 13:11:33 2002 Joe Orton * request.c (serve_eof, fail_early_eof, fail_eof_continued, fail_eof_headers): New functions. Sat Jul 6 08:58:17 2002 Joe Orton * request.c (serve_100_once, expect_100_once): New functions. Fri Jul 5 21:43:58 2002 Joe Orton * auth.c (username): Use the correct spelling of Aladdin. (auth_hdr): Simplify debug messages. (auth_serve): Fail if no Authorization header is given. (basic): Check for response status. Fri Jul 5 21:41:02 2002 Joe Orton * utils.c (any_2xx_request): New function. Sun Jun 30 17:10:59 2002 Joe Orton * request.c (fail_noserver): Factor out from host_not_found. (fail_lookup): Equivalent to old host_not_found. (fail_connect, abort_respbody): New function. Sun Jun 30 14:32:32 2002 Joe Orton * request.c (fail_chunksize): New function. Sun Jun 30 10:39:17 2002 Joe Orton * request.c (test_persist): Factor out from persist; take response and response body as arguments. (persist_http11): New function, equivalent to old persist. (persist_chunked, persist_http10): New functions. Sun Jun 30 10:25:07 2002 Joe Orton * utils.c (serve_response): Factor out from single_serve_string, many_serve_string. (single_serve_string, many_serve_string): Use serve_response. Sun Jun 30 09:13:55 2002 Joe Orton * request.c (expect_response, persist, persist_timeout, multi_header): Rely on the fact that the test framework will reap the server. (expect_no_body, no_body_304, no_body_204, no_body_HEAD, no_body_chunks): New functions. Tue Jun 25 23:05:42 2002 Joe Orton * request.c (trailing_header): New function. Sun Jun 23 23:00:03 2002 Joe Orton * ssl.c (no_verify): Fix sixth argument to any_ssl_request. Sun Jun 23 15:21:06 2002 Joe Orton * Makefile.in (grind): New target. * run.sh: Respect $HARNESS. Sun Jun 23 15:20:38 2002 Joe Orton * props.c: New file. Sun Jun 23 09:37:10 2002 Joe Orton * makekeys.sh: Ignore failure from `hostname -[sdf]' commands, as appropriate tests are skipped on failure. Sun Jun 23 08:33:50 2002 Joe Orton * request.c (host_not_found): Use any_request(); simplify. (proxy_no_resolve): New function. Sun Jun 16 11:40:19 2002 Joe Orton * ssl.c (do_ssl_response): Succeed if connection is closed by client after negotiation. (serve_tunnel, fail_tunnel, proxy_tunnel): New functions. Mon Jun 10 21:18:03 2002 Joe Orton * redirect.c (check_redir): Await server child before returning. Sun Jun 9 13:05:25 2002 Joe Orton * socket.c (DECL): Don't use run-time initialization. (single_read, single_peek, small_reads, read_and_peek, line_closure, larger_read, line_toolong): Use DECL, as last declaration. Sun Jun 9 13:03:36 2002 Joe Orton * compress.c (reader, do_fetch): Check that inflated data is of expected length. Sun Jun 9 11:40:54 2002 Joe Orton * redirect.c (struct redir_args): Add 'path' field. (any_request): Use path in Request-URI. (simple, redir_303, non_absolute): Fill in path. (relative_1, relative_2): New functions. Tue Jun 4 16:56:08 2002 Joe Orton * uri-tests.c (parents): Improve ne_path_parent tests. Mon Jun 3 18:22:31 2002 Joe Orton * cookies.c: New file. Sun Jun 2 10:06:42 2002 Joe Orton * basic.c (dav_capabilities): New function. Sat Jun 1 10:39:04 2002 Joe Orton * socket.c (to_begin, to_end, peek_timeout, read_timeout, readline_timeout, fullread_timeout): New functions. Sat Jun 1 10:38:13 2002 Joe Orton * request.c (read_timeout): Use sleepy_server. (hung_server): Removed. Sat Jun 1 10:32:45 2002 Joe Orton * utils.c (sleepy_server): New function. Thu May 30 20:00:40 2002 Joe Orton * socket.c (finish): New function, factored out from common code. (small_reads, read_and_peek, larger_read): Use it. (line_simple, line_closure, line_empty, line_toolong, line_mingle, line_chunked): New functions. Sun May 26 14:54:52 2002 Joe Orton * request.c (fill_uri, match_hostport, hostports): Moved functions to session.c. * session.c: New file. Fri May 24 08:14:21 2002 Joe Orton * request.c (match_hostport, hostports): New functions. Tue May 21 21:29:25 2002 Joe Orton * redirect.c: New file. Sun May 19 18:25:48 2002 Joe Orton * auth.c, lock.c, regress.c, socket.c, ssl.c, utils.c, utils.h: Update for socket API change; s/sock_/ne_sock_/, s/SOCK_/NE_SOCK_/. Wed May 8 19:41:24 2002 Joe Orton * ssl.c (do_ssl_response): Take response body as parameter; all callers changed. (serve_eof, simple_eof): New functions. Wed May 8 17:17:27 2002 Joe Orton * socket.c: New file. * sock-tests.c: Removed file. * Makefile.in: Updated accordingly. Wed May 8 11:53:35 2002 Joe Orton * request.c (host_not_found): New function. Wed May 1 21:41:02 2002 Joe Orton * uri-tests.c (parse): New function. (simple, simple_ssl): Adjust for ne_uri_parse port default. Tue Apr 23 21:39:09 2002 Joe Orton * request.c (read_timeout): Better diagnostic for test failure cases. Sun Apr 14 12:00:19 2002 Joe Orton * basic.c (content_type): Updated to reflect default charset ISO-8859-1 for text/ media types. Sun Apr 7 17:35:21 2002 Joe Orton * run.sh: Set MALLOC_CHECK_ so glibc's heap corruption detection is enabled. Sun Apr 7 17:30:37 2002 Joe Orton * compress.c (do_fetch): Reset 'failed' flag to zero each time. Wed Apr 3 20:16:43 2002 Joe Orton * request.c (NO_BODY): Renamed from NOBODY (all callers changed). (empty_header, ignore_header_ws, ignore_header_ws2): New tests. (ignore_header_ws3): Renamed from ignore_header_spaces. Tue Apr 2 21:09:33 2002 Joe Orton * request.c (expect_header_value): New function. (ignore_header_case, ignore_header_spaces, ignore_header_tabs): New tests. Mon Mar 25 21:51:24 2002 Joe Orton * lock.c (multi_lock_response, lock_shared): New function. (lock_compare): Factored out from discover_results. (discover, lock_timeout, submit_test): Adjust for lock API changes. Mon Mar 25 21:36:55 2002 Joe Orton * ssl.c (fail_ssl_request): Check failure bits against NE_SSL_FAILMASK. Sun Mar 10 22:07:48 2002 Joe Orton * stubs.c (stub_decompress, sd_reader): New function. Sun Mar 10 21:39:29 2002 Joe Orton * lock.c (activelock): New function, factored out from lock_response. (lock_response): Use activelock; adjust argument types. (make_lock): Adjusted for lock_response arg changes. (discard_response, serve_discovery, discover_result, discover): New functions. Wed Mar 6 22:22:04 2002 Joe Orton * lock.c (submit_test): Handle failures gracefully. Wed Mar 6 21:23:27 2002 Joe Orton * lock.c (submit_test): Update to expect an absoluteURI in If: headers. Wed Mar 6 21:17:37 2002 Joe Orton * uri-tests.c (unparse): New function. Tue Mar 5 22:59:37 2002 Joe Orton * uri-tests.c (cmp): Checks for case-insensitive comparison, and empty path, "/" equivalence. Mon Mar 4 01:07:03 2002 Joe Orton * request.c (blank_response): Add test for potential segfault in strip_eol (would fail if run under Electric Fence). Sun Mar 3 20:50:01 2002 Joe Orton * lock.c (make_lock, store_single, store_several, got_if_header, serve_verify_if, do_request, submit_test, if_simple, if_under_infinite, if_infinite_over, if_child, if_covered_child): New tests. (lock_timeout): Adjusted for API changes. Sun Mar 3 15:29:05 2002 Joe Orton * uri-tests.c (cmp_differ, cmp): New functions. Sun Mar 3 11:08:36 2002 Joe Orton * request.c (fill_uri): New function. Sun Feb 17 21:31:21 2002 Joe Orton * ssl.c (fqdn_match): Removed test. Sun Feb 17 20:32:16 2002 Joe Orton * makekeys.sh: Create keypair for client cert. * ssl.c (do_ssl_response, any_ssl_request, all callers thereof): Better error handling. (serve_ccert, load_pem_ccert, keypw_prompt, load_pkcs12_ccert, fail_load_ccerts, client_cert_pem, client_cert_pkcs12): New functions. Sun Feb 17 11:54:19 2002 Joe Orton * basic.c (do_range): Factored out from get_range/fail_range_length. (get_range, fail_range_length): Use do_range. (fail_range_units, fail_range_notrange, fail_range_unsatify): New tests. Sun Feb 17 11:36:00 2002 Joe Orton * basic.c (get_range, fail_range_length): New functions. Sat Feb 16 23:29:40 2002 Joe Orton * xml.c: New file. * Makefile.in (DAV_TESTS): Add xml tests. Sat Feb 16 15:26:27 2002 Joe Orton * compress.c (do_fetch): Rename from fetch(); add 'expect_fail' paramater. (fetch): Re-implement using do_fetch. (fail_trailing, fail_bad_csum, fail_truncate): New functions. * Makefile.in (trailing.gz, truncated.gz, badcsum.gz): New helper files. Thu Feb 14 19:09:42 2002 Joe Orton * request.c (everywhere): Simplify use of expect_response. Thu Feb 14 19:05:48 2002 Joe Orton * request.c (ignore_bad_headers): New function. Mon Feb 11 22:06:40 2002 Joe Orton * makekeys.sh: If the hostname command is clever enough to give FQDN, hostname, domainname, then create wildcard.cert; cert with a wildcard commonName. * ssl.c (wildcard_match): New function Mon Feb 11 21:55:52 2002 Joe Orton * ssl.c (any_ssl_request): Take session pointer, don't initialize here. (DEFSESS): New macro. (everywhere): Use DEFSESS rather than passing pointer-to- session pointer. Mon Feb 11 20:44:44 2002 Joe Orton * ssl.c (fqdn_match): Test for FQDN matching against non-qualified FQDN. (makekeys.sh): Create server cert with FQDN. Sun Feb 10 12:36:55 2002 Joe Orton * request.c (chunk_oversize): New function. Sat Feb 9 21:12:47 2002 Joe Orton * request.c (reason_phrase): New function. Sat Feb 9 16:50:58 2002 Joe Orton * request.c (read_timeout, hung_server): New functions. Thu Feb 7 22:58:31 2002 Joe Orton * ssl.c (cache_verify, no_verify, count_vfy): New functions. Thu Feb 7 19:39:33 2002 Joe Orton * ssl.c (any_ssl_request): Take server function as argument: all callers changed. (fail_ssl_request): Renamed from failreq; uses any_ssl_request. Wed Feb 6 20:43:32 2002 Joe Orton * ssl.c (load_ca): New function. Wed Feb 6 20:36:15 2002 Joe Orton * ssl.c (any_ssl_request): Make ca_cert and verify_fn arguments optional. (trustall): Removed function. (simple): Use the CA cert; no need for a verify function. (parse_cert): Don't give a CA cert, force use of verify function. (failreq): Bug fix, don't trust server cert as CA. (fail_wrongCN, fail_notvalid, fail_expired): Pass server cert as CA cert server cert is self-signed. Tue Feb 5 20:33:42 2002 Joe Orton * ssl.c (fail_untrusted_ca, fail_self_signed): New tests. (fail_serve): New function. (failreq, any_ssl_request): Take ca cert argument. (check_DNs, trustall, get_failures): Adjust for new verify callback interface. Sat Feb 2 14:18:11 2002 Joe Orton * ssl.c (do_ssl_response): Factored out from serve_ssl. (serve_ssl): Use do_ssl_response. (serve_scache, session_cache): New functions. Thu Jan 31 21:09:58 2002 Joe Orton * Makefile.in (ca-stamp): New target. * makekeys.sh: New helper script. * ssl.c (parse_cert, fail_wrongCN, fail_expired, fail_notvalid): New tests. (any_ssl_request, trustall, check_DNs, failreq): New auxiliaries. Thu Jan 31 20:42:38 2002 Joe Orton * wrongcn.pem, notvalid.pem, expired.pem, server.key: New files. * Makefile.in: Remove targets to generate certs. Wed Jan 30 21:15:33 2002 Joe Orton * Makefile.in (wrongcn.pem): New target. Wed Jan 30 19:58:18 2002 Joe Orton * string-tests.c: Updated for ne_buffer API change. Sat Jan 26 11:23:34 2002 Joe Orton * Makefile.in: Pick up appropriate TESTS, HELPERS from configure. (ssltests*, davtests*): Remove crud. * compress.c: Presume zlib support present if built. Sun Jan 20 23:29:37 2002 Joe Orton * ssl.c: New file. * Makefile.in (ssltests-no, ssltests-yes, server.pem, server.key): New targets. (check): Conditionally run SSL tests. Sun Jan 20 13:20:56 2002 Joe Orton * Makefile.in (davtests-no, davtests-yes): Separate test programs which require DAV support; only run if DAV is enabled. * Makefile.in (test): Pass SRCDIR env var through to run.sh. * run.sh: Pass SRCDIR as argv[1] to test programs. * compress.c (init): New function. Use 'newsfn' global for filename of NEWS file. Sun Jan 20 13:06:40 2002 Joe Orton * Makefile.in: Fixes for VPATH build Mon Jan 14 01:58:39 2002 Joe Orton * basic.c (content_type): Add harsher charset handling tests. Sun Jan 13 14:01:57 2002 Joe Orton * lock.c (lock_timeout): Use make_session. * acl.c (test_acl): Use make_session. * auth.c (basic, retries): Use make_session. Sun Jan 13 14:01:13 2002 Joe Orton * utils.c (make_session): New function. Sun Jan 13 14:00:34 2002 Joe Orton * basic.c (content_type): Rename ctype to ct; check if charset is unexpectedly set. Sun Jan 13 13:58:07 2002 Joe Orton * basic.c: New file. * Makefile.in: Add `basic' test suite. Mon Jan 7 22:05:33 2002 Joe Orton * Makefile.in: Don't pass CFLAGS to CC when linking. Mon Jan 7 21:46:03 2002 Joe Orton * lock.c: New file. * Makefile.in: Add 'lock' to TESTS, build lock. Mon Jan 7 21:17:21 2002 Joe Orton * skeleton.c: Add skeleton test suite. Tue Jan 1 21:47:09 2002 Joe Orton * Makefile.in: Use CPPFLAGS correctly. Sun Dec 9 14:02:50 2001 Joe Orton * string-tests.c (ONCMP): New macro. (everywhere): Use it. (grow): Add ne_buffer_grow test. Sun Dec 9 13:12:27 2001 Joe Orton * string-tests.c (concat2, concat3): New ne_buffer_concat tests. Sat Dec 1 18:35:29 2001 Joe Orton * utils.c (any_request): Don't set the error context. Sat Dec 1 12:21:48 2001 Joe Orton * auth.c (retry_failure, retry_fail_cb, retry_fail_serve): New functions. Tue Nov 27 21:24:22 2001 Joe Orton * request.c (s_progress, provide_progress, send_progress): New functions. Sun Nov 18 19:11:23 2001 Joe Orton * auth.c (send_response): New function. (auth_serve): Simplify using send_response. (retry_serve, retry_cb, retries): New functions. Sat Nov 17 22:32:29 2001 Joe Orton * auth.c (auth_serve, basic): Simplify, use a persistent connection and any_request() to work with --disable-dav builds. Sat Nov 17 22:30:43 2001 Joe Orton * utils.c (any_request): New function. Sun Oct 28 19:38:05 2001 Joe Orton * Makefile.in: Use explicit link rules. Fri Oct 26 20:08:33 2001 Joe Orton * request.c (persist_timeout): Test behaviour when connection closes after between 1 and 10 requests. Fri Oct 26 20:04:27 2001 Joe Orton * utils.c (many_serve_string): New function. Sun Oct 7 17:48:53 2001 Joe Orton * utils.c: New file. * request.c (single_serve_string): Moved to utils.c. * Makefile.in: Link utils.o into all libtest.a. Move libtest.a into this directory. Sun Oct 7 15:01:47 2001 Joe Orton * request.c (persist, persist_timeout, serve_twice, is_alive): New functions. (closed_connection): Avoid race condition. Sat Oct 6 14:33:42 2001 Joe Orton * request.c (prepare_request, finish_request): Renamed from make_request, destroy_request. (skip_interim_1xx, skip_many_1xx, skip_1xx_hdrs): New functions. Wed Oct 3 00:03:33 2001 Joe Orton * request.c (fail_request): Optionally include a request body, and optionally presume the server runs "forever". (all callers changed). (serve_close, closed_connection): New function. Sat Sep 29 14:08:16 2001 Joe Orton * compress.c (fetch): Update for new decompression API. Sat Sep 29 11:21:56 2001 Joe Orton * compress.c: New file. * Makefile.in: Build compress test, and some its helpers. Add -lneon to LIBS, and pick up NEON_CFLAGS. Thu Sep 27 20:31:51 2001 Joe Orton * utils.h: New file. * request.c: Moved ONREQ() into utils.h Mon Aug 27 00:34:56 2001 Joe Orton * regress.c: New file. Mon Aug 27 00:33:13 2001 Joe Orton * request.c (discard_request): Moved into common/child.c. (make_request, destroy_request): Convenience functions. (serve_non_http, not_http): New test. Sun Jun 24 22:15:46 2001 Joe Orton * test.[ch], child.[ch]: Moved into 'common' subdir. * Makefile.in: Updated likewise. Tue Jun 19 22:00:06 2001 Joe Orton * util-tests.c (parse_dates): Test date parsers. Sun Jun 10 17:36:11 2001 Joe Orton * request.c (infinite_headers, unbounded_headers): New test. Sun Jun 10 16:38:53 2001 Joe Orton * child.c [HAVE_PIPE]: Use a pipe between child and parent to know when the child is ready to accept connections. Avoids boring sleep()ing. Fri Jun 8 21:19:35 2001 Joe Orton * tests.c (segv, main): Remove SEGV handler in favour of useful core dumps. Mon Jun 4 01:15:52 2001 Joe Orton * child.c (server_socket): Set socket family correctly. Thu May 31 08:58:41 2001 Joe Orton * util-tests.c (md5_alignment): New test for MD5 alignment issue on Sparc. Thu May 31 00:40:43 2001 Joe Orton * child.c (minisleep): Just sleep for a second anyway. Thu May 31 00:19:16 2001 Joe Orton * child.c (server_socket): Casts for bind and setsockopt arguments. Thu May 31 00:02:21 2001 Joe Orton * request.c (send_bodies): Test callback-provided request bodies. Wed May 30 22:37:08 2001 Joe Orton * tests.c (child_segv): New function. (in_child): Install different SEGV handler. (segv): Sleep so the re-raised SEGV signal gets handled and we dump core. Wed May 30 19:24:32 2001 Joe Orton * request.c (send_bodies): New test for sending request bodies. Wed May 16 21:19:49 2001 Joe Orton * request.c (expect_response): Renamed, fold together single_request and do_get_request. (all callers changed) Wed May 16 20:59:19 2001 Joe Orton * request.c (construct_get, run_request): New functions. (fold_headers, fold_many_headers, multi_header): New tests. Sat May 12 17:37:36 2001 Joe Orton * server.c: Renamed from http-tests.c. Sat May 12 17:35:05 2001 Joe Orton * child.c (minisleep): New function. (spawn_server, reap_server): New functions. (server_child): Call in_child. Sat May 12 17:33:57 2001 Joe Orton * tests.c (main): Open two log files for debugging messages. (in_child): Switch to debug using child log. Sat May 12 11:18:18 2001 Joe Orton * tests.c (main): Call sock_init. (segv): Re-raise SEGV signal after printing message. Mon May 7 10:38:50 2001 Joe Orton * request.c (chunk_syntax_1, chunk_syntax_2, chunk_syntax_3, chunk_syntax_4, chunk_syntax_5): Split down from chunk_syntax. Mon May 7 10:37:38 2001 Joe Orton * util-tests.c (base64): Update for ne_base64() changes. Add tests for binary data. Sun May 6 23:55:36 2001 Joe Orton * tests.h (ON): Use global buffer 'on_err_buf'. Make 'name' variable public. Sun May 6 23:53:06 2001 Joe Orton * request.c (single_serve_string): General version of single_serve_*. (single_request): Pass in expected response body. (single_get_*): Use new single_request/single_serve_string. (chunk_syntax): Add some tests for chunk syntax. Sun May 6 22:29:36 2001 Joe Orton * child.c, child.h: New files, split down from request.c. Sun May 6 21:53:28 2001 Joe Orton * request.c (spawn_server): Sleep for a while to let the server get going. (do_request): Use passed parameters when creating request. Sun May 6 21:34:27 2001 Joe Orton * request.c (spawn_server): Use callback to handle the server side of connection. (single_request): New function. (single_get_eof, single_get_clength, single_get_chunked): New functions. (reap_server): New function. Sun May 6 20:02:32 2001 Joe Orton * request.c: New file. Wed May 2 12:08:53 2001 Joe Orton * string-tests.c (token1, token2, nulls, empty, quoted, badquotes, shave, combo): New tests for ne_token and ne_shave. Wed May 2 12:04:52 2001 Joe Orton * string-tests.c: Updated for sbuffer -> ne_buffer changes. Wed May 2 01:08:45 2001 Joe Orton * Makefile.in (check): Alias for test goal. Wed May 2 01:08:36 2001 Joe Orton * tests.c (segv): Disable SEGV handler once handling it. Sun Apr 29 14:57:59 2001 Joe Orton * uri-tests.c (slash): Check behaviour of passing zero-length URI. Sun Apr 29 13:43:59 2001 Joe Orton * Makefile.in (clean): New target. (libtest.a): Depend on libneon to force rebuilds when necessary. (all): Build but don't test. Sun Apr 29 13:41:13 2001 Joe Orton * util-tests.c: Add status line with leading garbage. Sun Apr 29 13:39:53 2001 Joe Orton * util-tests.c (status_lines): Add some tests for invalid status lines too. Sun Apr 29 13:38:31 2001 Joe Orton * tests.c (main): Use basename(argv[0]) as suite name. Fail if no tests are in the functions vector. Sun Apr 29 11:06:45 2001 Joe Orton * tests.c (segv): New function. (main): Add SIGSEGV handler. Fri Apr 27 00:00:12 2001 Joe Orton * util-tests.c (base64): New test. Thu Apr 26 22:39:44 2001 Joe Orton * uri-tests.c (just_hostname, just_path, null_uri): New tests. Thu Apr 26 22:03:58 2001 Joe Orton * util-tests.c (md5): Test of MD5 functions. Mon Apr 23 23:08:02 2001 Joe Orton * http-tests.c (simple_head): Add HEAD test. Mon Apr 23 22:49:52 2001 Joe Orton * http-tests.c (simple_get): Check for EOF after reading response body of HTTP/1.0 GET request. (null_resource): New function, test for 404 on null resource. davix-R_0_5_0/deps/libneon/test/Makefile.in000066400000000000000000000150571257152637300207020ustar00rootroot00000000000000# Makefile for neon test suite. SHELL = @SHELL@ CPPFLAGS = @CPPFLAGS@ -I. -I$(top_srcdir)/src -I$(top_srcdir)/test/common CFLAGS = @CFLAGS@ @NEON_CFLAGS@ LDFLAGS = @LDFLAGS@ DEFS = @DEFS@ top_builddir = .. top_srcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ AR = ar RANLIB = @RANLIB@ LIBS = $(LIBTEST) CC = @CC@ OPENSSL = @OPENSSL@ HELPERS = @HELPERS@ foobar.txt BASIC_TESTS = uri-tests util-tests string-tests socket \ session request auth basic stubs redirect ZLIB_TESTS = compress ZLIB_HELPERS = file1.gz file2.gz trailing.gz badcsum.gz truncated.gz \ corrupt1.gz corrupt2.gz empty.gz random.txt DAV_TESTS = xml xmlreq oldacl acl3744 props lock SSL_TESTS = socket-ssl ssl SSL_HELPERS = ca-stamp TESTS = @TESTS@ VALGRIND = valgrind --tool=memcheck --leak-check=yes --trace-children=no --show-reachable=yes # Make every object depend on libneon.la to force a rebuild on any src/* changes OBJDEPS = $(srcdir)/common/tests.h $(srcdir)/common/child.h $(srcdir)/utils.h \ $(top_builddir)/config.h $(top_builddir)/src/libneon.la # Test program just depends on libtest DEPS = $(LIBTEST) LIBTEST = libtest.la LIBNEON = $(top_builddir)/src/libneon.la LIBTOOL = @LIBTOOL@ --silent TEST_LDFLAGS = @TEST_LDFLAGS@ LINK = $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(TEST_LDFLAGS) COMPILE = $(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) prefix = @prefix@ exec_prefix = @exec_prefix@ libdir = @libdir@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL = @INSTALL@ INSTALL_HELPERS = $(HELPERS) server.key makekeys \ $(srcdir)/openssl.conf $(srcdir)/notvalid.pem \ $(srcdir)/expired.pem .SUFFIXES: .SUFFIXES: .lo .c # By default, compile but don't run the tests. all: $(TESTS) clean: rm -f $(TESTS) $(HELPERS) *.*o common/*.*o libtest.*a *.log rm -f *.gc* *.da *.bb* common/*.bb* common/*.gc* common/*.da rm -rf ca ca2 .libs nssdb* rm -f ca-stamp client.key *.csr ssigned.pem wrongcn.pem \ server.cert client.cert *.p12 *.cert sparse.bin check: $(TESTS) $(HELPERS) @SRCDIR=$(srcdir) $(SHELL) $(srcdir)/run.sh $(TESTS) grind: $(TESTS) $(HELPERS) @SRCDIR=$(srcdir) HARNESS="$(VALGRIND)" $(SHELL) $(srcdir)/run.sh $(TESTS) lfs-check: largefile $(LFS_HELPERS) @SRCDIR=$(srcdir) $(SHELL) $(srcdir)/run.sh largefile install: $(TESTS) $(HELPERS) @$(INSTALL) -d $(DESTDIR)$(libdir)/neon-tests @$(INSTALL) -d $(DESTDIR)$(libdir)/neon-tests/bin @$(INSTALL) -d $(DESTDIR)$(libdir)/neon-tests/data @for t in $(TESTS); do \ $(LIBTOOL) --mode=install \ $(INSTALL_PROGRAM) $$t $(DESTDIR)$(libdir)/neon-tests/bin; \ done @for h in $(INSTALL_HELPERS); do \ $(INSTALL_DATA) $$h $(DESTDIR)$(libdir)/neon-tests/data; \ done @$(INSTALL_PROGRAM) $(srcdir)/run-tests.sh $(DESTDIR)$(libdir)/neon-tests NEWS = $(top_srcdir)/NEWS file1.gz: $(NEWS) gzip -c --no-name $(NEWS) > $@ file2.gz: $(NEWS) gzip -c --name $(NEWS) > $@ # gzip file with trailing bytes. trailing.gz: $(NEWS) gzip -c --no-name $(NEWS) > $@ echo "hello, world" >> $@ truncated.gz: file1.gz dd if=file1.gz of=$@ bs=2048 count=2 badcsum.gz: file1.gz dd of=$@ if=file1.gz bs=1 count=`perl -e 'printf "%d", (stat("file1.gz"))[7] - 8;'` echo 'broken!' >> $@ corrupt1.gz: file1.gz dd of=$@ if=file1.gz bs=1 count=500 cat $(NEWS) >> $@ corrupt2.gz: $(NEWS) cat $(NEWS) > $@ empty.gz: touch $@ random.txt: $(NEWS) cat $(NEWS) > $@ foobar.txt: echo foobar > $@ # Dummy target to create the CA keys etc. makekeys stderr is redirected # since it changes for every invocation; not helpful for regression # testing. ca-stamp: makekeys $(srcdir)/openssl.conf rm -rf ca ca2 OPENSSL=$(OPENSSL) \ $(SHELL) makekeys $(srcdir) 2>makekeys.out @echo timestamp > ca-stamp Makefile: $(srcdir)/Makefile.in cd .. && ./config.status test/Makefile makekeys: $(srcdir)/makekeys.sh cd .. && ./config.status test/makekeys LIBOBJS = common/tests.lo common/child.lo utils.lo util-socks.lo $(LIBTEST): $(LIBOBJS) $(LINK) -o $(LIBTEST) $(LIBOBJS) $(LIBNEON) .c.lo: $(COMPILE) -c $< -o $@ # Recompile socket.c with SOCKET_SSL defined socket-ssl.lo: $(srcdir)/socket.c $(HDRS) $(COMPILE) -DSOCKET_SSL -c $(srcdir)/socket.c -o $@ socket-ssl: socket-ssl.lo $(LIBTEST) $(LINK) -o $@ socket-ssl.lo $(LIBS) resolve: resolve.lo $(LIBNEON) $(LINK) -o $@ resolve.lo $(LIBNEON) common/tests.lo: $(srcdir)/common/tests.c $(OBJDEPS) common/child.lo: $(srcdir)/common/child.c $(OBJDEPS) utils.lo: $(srcdir)/utils.c $(OBJDEPS) util-socks.lo: $(srcdir)/util-socks.c $(OBJDEPS) auth.lo: $(srcdir)/auth.c $(OBJDEPS) uri-tests.lo: $(srcdir)/uri-tests.c $(OBJDEPS) util-tests.lo: $(srcdir)/util-tests.c $(OBJDEPS) string-tests.lo: $(srcdir)/string-tests.c $(OBJDEPS) socket.lo: $(srcdir)/socket.c $(OBJDEPS) server.lo: $(srcdir)/server.c $(OBJDEPS) request.lo: $(srcdir)/request.c $(OBJDEPS) regress.lo: $(srcdir)/regress.c $(OBJDEPS) compress.lo: $(srcdir)/compress.c $(OBJDEPS) oldacl.lo: $(srcdir)/oldacl.c $(OBJDEPS) acl3744.lo: $(srcdir)/acl3744.c $(OBJDEPS) utils.lo: $(srcdir)/utils.c $(OBJDEPS) stubs.lo: $(srcdir)/stubs.c $(OBJDEPS) props.lo: $(srcdir)/props.c $(OBJDEPS) session.lo: $(srcdir)/session.c $(OBJDEPS) redirect.lo: $(srcdir)/redirect.c $(OBJDEPS) basic.lo: $(srcdir)/basic.c $(OBJDEPS) ssl.lo: $(srcdir)/ssl.c $(OBJDEPS) lock.lo: $(srcdir)/lock.c $(OBJDEPS) largefile.lo: $(srcdir)/largefile.c $(OBJDEPS) auth: auth.lo $(DEPS) $(LINK) -o $@ auth.lo $(DEPS) basic: basic.lo $(DEPS) $(LINK) -o $@ basic.lo $(DEPS) uri-tests: uri-tests.lo $(DEPS) $(LINK) -o $@ uri-tests.lo $(DEPS) util-tests: util-tests.lo $(DEPS) $(LINK) -o $@ util-tests.lo $(DEPS) string-tests: string-tests.lo $(DEPS) $(LINK) -o $@ string-tests.lo $(DEPS) socket: socket.lo $(DEPS) $(LINK) -o $@ socket.lo $(DEPS) server: server.lo $(DEPS) $(LINK) -o $@ server.lo $(DEPS) request: request.lo $(DEPS) $(LINK) -o $@ request.lo $(DEPS) regress: regress.lo $(DEPS) $(LINK) -o $@ regress.lo $(DEPS) compress: compress.lo $(DEPS) $(LINK) -o $@ compress.lo $(DEPS) oldacl: oldacl.lo $(DEPS) $(LINK) -o $@ oldacl.lo $(DEPS) acl3744: acl3744.lo $(DEPS) $(LINK) -o $@ acl3744.lo $(DEPS) utils: utils.lo $(DEPS) $(LINK) -o $@ utils.lo $(DEPS) stubs: stubs.lo $(DEPS) $(LINK) -o $@ stubs.lo $(DEPS) props: props.lo $(DEPS) $(LINK) -o $@ props.lo $(DEPS) session: session.lo $(DEPS) $(LINK) -o $@ session.lo $(DEPS) redirect: redirect.lo $(DEPS) $(LINK) -o $@ redirect.lo $(DEPS) ssl: ssl.lo $(DEPS) $(LINK) -o $@ ssl.lo $(DEPS) xml: xml.lo $(DEPS) $(LINK) -o $@ xml.lo $(DEPS) xmlreq: xmlreq.lo $(DEPS) $(LINK) -o $@ xmlreq.lo $(DEPS) lock: lock.lo $(DEPS) $(LINK) -o $@ lock.lo $(DEPS) largefile: largefile.lo $(DEPS) $(LINK) -o $@ largefile.lo $(DEPS) davix-R_0_5_0/deps/libneon/test/README000066400000000000000000000023521257152637300175070ustar00rootroot00000000000000 Stupidly Simple Test Suite for neon ----------------------------------- The aim of the test suite is two-fold: 1. ensure compliance to the relevant RFCs in network behaviour. 2. ensure that the promises made by the public API are met by the current implementation. The file `STATUS' makes an attempt at listing RFC requirements and how the test suite tests whether neon meets them or not (it's not finished yet). The test suite is licensed under the GPL. Important Note About Test Failures ---------------------------------- Note that a test failure either means a bug in the test or a bug in the code itself. On platforms without pipe(), there is a race condition in the code which forks a server process: if you get random failures on a slow or loaded box, increase the sleep time in common/child.c:minisleep(). Extra Stuff ----------- server-tests requires that you have a running HTTP server on localhost port 80, and you have copied htdocs/* to server-htdocs-root/test/* Credits ------- This test suite is inspired by the Subversion project, discussion on the subversion mailing list, and seeing chromatic's talks on XP. The presentation is inspired by the standard Perl test suite. Imitation is the greatest form of flattery, right? davix-R_0_5_0/deps/libneon/test/STATUS000066400000000000000000000044721257152637300176020ustar00rootroot00000000000000 -*- text -*- This document attempts to list RFC requirements and determine whether neon meets them, or where they do not apply, etc. Yes: test written, succeeds No: test written, but currently fails ???: no test written ---: feature not supported App: this is an application issue not a neon issue RFC2616 ======= 3.1: MUST treat major/minor as separate digits Yes 3.1: MUST ignore leading zeros Yes 3.1: MUST only send HTTP/1.1 when appropriate ??? 3.2.2: MUST use abs_path of "/" in Request-URI App 3.2.3: comparisons of host names MUST be case-insensitive Yes comparisons of scheme names MUST be ... Yes comparison of empty abs_path equivalent to "/" No/--- 3.3.1: MUST accept three date formats App/Yes [2] MUST only generate RFC1123-style dates App 3.3.1: MUST use GMT for http-dates ??? MUST assume GMT when parsing asctime dates ??? 3.4.1: MUST respect charset label provided Yes/App 3.5*: content codings App 3.6: MUST requirements for multiple transfer-codings --- [4] 3.6.1: parsing of chunked transfer coding Yes MUST be able to handle "chunked" transfer-coding Yes MUST ignore unknown chunk-extension extensions Yes 3.7: parsing of Content-Type headers Yes 3.7: MUST NOT have LWS between type/subtype in C-T hdr App SHOULD only send parameters to "new HTTP apps" (>1.0?) App 3.7.1: MUST represent HTTP message in canonical form App MUST accept CRLF/CR/LF as line-breaks in text/* media App MUST NOT use only CR or LF in HTTP control structures ??? MUST specify charset if not ISO-8859-1 App 3.7.2: multipart types --- 3.8: SHOULD have short product token Yes/App [5] SHOULD use product-version for version identifier Yes/App only product-version differs between versions Yes/App 3.9: Content Negotiation ---/App 3.10: Language Tags ---/App 3.11: Entity Tags ---/App [2]: date parser is provided which handles all three formats, but no handling of the Date header is present within neon. [3]: not sure if neon should be handling of this internally. [4]: neon only supports using just chunked Transfer-Coding or none. [5]: these reflect that applications may add their own product tokens alongside neon's. davix-R_0_5_0/deps/libneon/test/acl3744.c000066400000000000000000000043111257152637300200510ustar00rootroot00000000000000/* Dummy ACL tests Copyright (C) 2001-2007, Joe Orton 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 "ne_acl3744.h" #include "tests.h" #include "child.h" #include "utils.h" /**** DUMMY TESTS: just makes sure the stuff doesn't dump core. */ static int test_acl(const char *uri, ne_acl_entry *es, int nume) { ne_session *sess; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 OK\r\n" "Connection: close\r\n\r\n")); ON(ne_acl3744_set(sess, uri, es, nume)); CALL(await_server()); ne_session_destroy(sess); return OK; } static int grant_all(void) { ne_acl_entry e = {0}; e.target = ne_acl_all; e.type = ne_acl_grant; e.privileges = NE_ACL_ALL; CALL(test_acl("/foo", &e, 1)); return OK; } static int deny_all(void) { ne_acl_entry e = {0}; e.target = ne_acl_all; e.type = ne_acl_deny; e.privileges = NE_ACL_ALL; CALL(test_acl("/foo", &e, 1)); return OK; } static int deny_one(void) { ne_acl_entry e = {0}; e.target = ne_acl_href; e.tname = "http://webdav.org/users/joe"; e.type = ne_acl_deny; e.privileges = NE_ACL_ALL; CALL(test_acl("/foo", &e, 1)); return OK; } static int deny_byprop(void) { ne_acl_entry e = {0}; e.target = ne_acl_property; e.type = ne_acl_deny; e.tname = "owner"; e.privileges = NE_ACL_ALL; CALL(test_acl("/foo", &e, 1)); return OK; } ne_test tests[] = { T(grant_all), T(deny_all), T(deny_one), T(deny_byprop), T(NULL) }; davix-R_0_5_0/deps/libneon/test/auth.c000066400000000000000000001032711257152637300177360ustar00rootroot00000000000000/* Authentication tests Copyright (C) 2001-2009, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_request.h" #include "ne_auth.h" #include "ne_basic.h" #include "ne_md5.h" #include "tests.h" #include "child.h" #include "utils.h" static const char username[] = "Aladdin", password[] = "open sesame"; static int auth_failed; #define BASIC_WALLY "Basic realm=WallyWorld" #define CHAL_WALLY "WWW-Authenticate: " BASIC_WALLY #define EOL "\r\n" static int auth_cb(void *userdata, const char *realm, int tries, char *un, char *pw) { if (strcmp(realm, "WallyWorld")) { NE_DEBUG(NE_DBG_HTTP, "Got wrong realm '%s'!\n", realm); return -1; } strcpy(un, username); strcpy(pw, password); return tries; } static void auth_hdr(char *value) { #define B "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" auth_failed = strcmp(value, B); NE_DEBUG(NE_DBG_HTTP, "Got auth header: [%s]\nWanted header: [%s]\n" "Result: %d\n", value, B, auth_failed); #undef B } /* Sends a response with given response-code. If hdr is not NULL, * sends that header string too (appending an EOL). If eoc is * non-zero, request must be last sent down a connection; otherwise, * clength 0 is sent to maintain a persistent connection. */ static int send_response(ne_socket *sock, const char *hdr, int code, int eoc) { char buffer[BUFSIZ]; sprintf(buffer, "HTTP/1.1 %d Blah Blah" EOL, code); if (hdr) { strcat(buffer, hdr); strcat(buffer, EOL); } if (eoc) { strcat(buffer, "Connection: close" EOL EOL); } else { strcat(buffer, "Content-Length: 0" EOL EOL); } return SEND_STRING(sock, buffer); } /* Server function which sends two responses: first requires auth, * second doesn't. */ static int auth_serve(ne_socket *sock, void *userdata) { char *hdr = userdata; auth_failed = 1; /* Register globals for discard_request. */ got_header = auth_hdr; want_header = "Authorization"; discard_request(sock); send_response(sock, hdr, 401, 0); discard_request(sock); send_response(sock, NULL, auth_failed?500:200, 1); return 0; } /* Test that various Basic auth challenges are correctly handled. */ static int basic(void) { const char *hdrs[] = { /* simplest case */ CHAL_WALLY, /* several challenges, one header */ "WWW-Authenticate: BarFooScheme, " BASIC_WALLY, /* several challenges, one header */ CHAL_WALLY ", BarFooScheme realm=\"PenguinWorld\"", /* whitespace tests. */ "WWW-Authenticate: Basic realm=WallyWorld ", /* nego test. */ "WWW-Authenticate: Negotiate fish, Basic realm=WallyWorld", /* nego test. */ "WWW-Authenticate: Negotiate fish, bar=boo, Basic realm=WallyWorld", /* nego test. */ "WWW-Authenticate: Negotiate, Basic realm=WallyWorld", /* multi-header case 1 */ "WWW-Authenticate: BarFooScheme\r\n" CHAL_WALLY, /* multi-header cases 1 */ CHAL_WALLY "\r\n" "WWW-Authenticate: BarFooScheme bar=\"foo\"", /* multi-header case 3 */ "WWW-Authenticate: FooBarChall foo=\"bar\"\r\n" CHAL_WALLY "\r\n" "WWW-Authenticate: BarFooScheme bar=\"foo\"", /* quoting test; fails to handle scheme properly with <= 0.28.2. */ "WWW-Authenticate: Basic realm=\"WallyWorld\" , BarFooScheme" }; size_t n; for (n = 0; n < sizeof(hdrs)/sizeof(hdrs[0]); n++) { ne_session *sess; CALL(make_session(&sess, auth_serve, (void *)hdrs[n])); ne_set_server_auth(sess, auth_cb, NULL); CALL(any_2xx_request(sess, "/norman")); ne_session_destroy(sess); CALL(await_server()); } return OK; } static int retry_serve(ne_socket *sock, void *ud) { discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, CHAL_WALLY, 401, 0); discard_request(sock); send_response(sock, NULL, 200, 0); return OK; } static int retry_cb(void *userdata, const char *realm, int tries, char *un, char *pw) { int *count = userdata; /* dummy creds; server ignores them anyway. */ strcpy(un, "a"); strcpy(pw, "b"); switch (*count) { case 0: case 1: if (tries == *count) { *count += 1; return 0; } else { t_context("On request #%d, got attempt #%d", *count, tries); *count = -1; return 1; } break; case 2: case 3: /* server fails a subsequent request, check that tries has * reset to zero. */ if (tries == 0) { *count += 1; return 0; } else { t_context("On retry after failure #%d, tries was %d", *count, tries); *count = -1; return 1; } break; case 4: case 5: if (tries > 1) { t_context("Attempt counter reached #%d", tries); *count = -1; return 1; } return tries; default: t_context("Count reached %d!?", *count); *count = -1; } return 1; } /* Test that auth retries are working correctly. */ static int retries(void) { ne_session *sess; int count = 0; CALL(make_session(&sess, retry_serve, NULL)); ne_set_server_auth(sess, retry_cb, &count); /* This request will be 401'ed twice, then succeed. */ ONREQ(any_request(sess, "/foo")); /* auth_cb will have set up context. */ CALL(count != 2); /* this request will be 401'ed once, then succeed. */ ONREQ(any_request(sess, "/foo")); /* auth_cb will have set up context. */ CALL(count != 3); /* some 20x requests. */ ONREQ(any_request(sess, "/foo")); ONREQ(any_request(sess, "/foo")); /* this request will be 401'ed once, then succeed. */ ONREQ(any_request(sess, "/foo")); /* auth_cb will have set up context. */ CALL(count != 4); /* First request is 401'ed by the server at both attempts. */ ONV(any_request(sess, "/foo") != NE_AUTH, ("auth succeeded, should have failed: %s", ne_get_error(sess))); count++; /* Second request is 401'ed first time, then will succeed if * retried. 0.18.0 didn't reset the attempt counter though so * this didn't work. */ ONV(any_request(sess, "/foo") == NE_AUTH, ("auth failed on second try, should have succeeded: %s", ne_get_error(sess))); ne_session_destroy(sess); CALL(await_server()); return OK; } /* crashes with neon <0.22 */ static int forget_regress(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_forget_auth(sess); ne_session_destroy(sess); return OK; } static int fail_auth_cb(void *ud, const char *realm, int attempt, char *un, char *pw) { return 1; } /* this may trigger a segfault in neon 0.21.x and earlier. */ static int tunnel_regress(void) { ne_session *sess = ne_session_create("https", "localhost", 443); ne_session_proxy(sess, "localhost", 7777); ne_set_server_auth(sess, fail_auth_cb, NULL); CALL(spawn_server(7777, single_serve_string, "HTTP/1.1 401 Auth failed.\r\n" "WWW-Authenticate: Basic realm=asda\r\n" "Content-Length: 0\r\n\r\n")); any_request(sess, "/foo"); ne_session_destroy(sess); CALL(await_server()); return OK; } /* regression test for parsing a Negotiate challenge with on parameter * token. */ static int negotiate_regress(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_set_server_auth(sess, fail_auth_cb, NULL); CALL(spawn_server(7777, single_serve_string, "HTTP/1.1 401 Auth failed.\r\n" "WWW-Authenticate: Negotiate\r\n" "Content-Length: 0\r\n\r\n")); any_request(sess, "/foo"); ne_session_destroy(sess); CALL(await_server()); return OK; } static char *digest_hdr = NULL; static void dup_header(char *header) { if (digest_hdr) ne_free(digest_hdr); digest_hdr = ne_strdup(header); } struct digest_parms { const char *realm, *nonce, *opaque, *domain; int rfc2617; int send_ainfo; int md5_sess; int proxy; int send_nextnonce; int num_requests; int stale; enum digest_failure { fail_not, fail_bogus_alg, fail_req0_stale, fail_req0_2069_stale, fail_omit_qop, fail_omit_realm, fail_omit_nonce, fail_ai_bad_nc, fail_ai_bad_nc_syntax, fail_ai_bad_digest, fail_ai_bad_cnonce, fail_ai_omit_cnonce, fail_ai_omit_digest, fail_ai_omit_nc, fail_outside_domain } failure; }; struct digest_state { const char *realm, *nonce, *uri, *username, *password, *algorithm, *qop, *method, *opaque; char *cnonce, *digest, *ncval; long nc; }; /* Write the request-digest into 'digest' (or response-digest if * auth_info is non-zero) for given digest auth state and * parameters. */ static void make_digest(struct digest_state *state, struct digest_parms *parms, int auth_info, char digest[33]) { struct ne_md5_ctx *ctx; char h_a1[33], h_a2[33]; /* H(A1) */ ctx = ne_md5_create_ctx(); ne_md5_process_bytes(state->username, strlen(state->username), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->realm, strlen(state->realm), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->password, strlen(state->password), ctx); ne_md5_finish_ascii(ctx, h_a1); if (parms->md5_sess) { ne_md5_reset_ctx(ctx); ne_md5_process_bytes(h_a1, 32, ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->nonce, strlen(state->nonce), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->cnonce, strlen(state->cnonce), ctx); ne_md5_finish_ascii(ctx, h_a1); } /* H(A2) */ ne_md5_reset_ctx(ctx); if (!auth_info) ne_md5_process_bytes(state->method, strlen(state->method), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->uri, strlen(state->uri), ctx); ne_md5_finish_ascii(ctx, h_a2); /* request-digest */ ne_md5_reset_ctx(ctx); ne_md5_process_bytes(h_a1, strlen(h_a1), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->nonce, strlen(state->nonce), ctx); ne_md5_process_bytes(":", 1, ctx); if (parms->rfc2617) { ne_md5_process_bytes(state->ncval, strlen(state->ncval), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->cnonce, strlen(state->cnonce), ctx); ne_md5_process_bytes(":", 1, ctx); ne_md5_process_bytes(state->qop, strlen(state->qop), ctx); ne_md5_process_bytes(":", 1, ctx); } ne_md5_process_bytes(h_a2, strlen(h_a2), ctx); ne_md5_finish_ascii(ctx, digest); ne_md5_destroy_ctx(ctx); } /* Verify that the response-digest matches expected state. */ static int check_digest(struct digest_state *state, struct digest_parms *parms) { char digest[33]; make_digest(state, parms, 0, digest); ONV(strcmp(digest, state->digest), ("bad digest; expected %s got %s", state->digest, digest)); return OK; } #define DIGCMP(field) \ do { \ ONCMP(state->field, newstate.field, \ "Digest response header", #field); \ } while (0) #define PARAM(field) \ do { \ if (ne_strcasecmp(name, #field) == 0) { \ ONV(newstate.field != NULL, \ ("received multiple %s params: %s, %s", #field, \ newstate.field, val)); \ newstate.field = val; \ } \ } while (0) /* Verify that Digest auth request header, 'header', meets expected * state and parameters. */ static int verify_digest_header(struct digest_state *state, struct digest_parms *parms, char *header) { char *ptr; struct digest_state newstate = {0}; ptr = ne_token(&header, ' '); ONCMP("Digest", ptr, "Digest response", "scheme name"); while (header) { char *name, *val; ptr = ne_qtoken(&header, ',', "\"\'"); ONN("quoting broken", ptr == NULL); name = ne_shave(ptr, " "); val = strchr(name, '='); ONV(val == NULL, ("bad name/value pair: %s", val)); *val++ = '\0'; val = ne_shave(val, "\"\' "); NE_DEBUG(NE_DBG_HTTP, "got field: [%s] = [%s]\n", name, val); PARAM(uri); PARAM(realm); PARAM(username); PARAM(nonce); PARAM(algorithm); PARAM(qop); PARAM(opaque); PARAM(cnonce); if (ne_strcasecmp(name, "nc") == 0) { long nc = strtol(val, NULL, 16); ONV(nc != state->nc, ("got bad nonce count: %ld (%s) not %ld", nc, val, state->nc)); state->ncval = ne_strdup(val); } else if (ne_strcasecmp(name, "response") == 0) { state->digest = ne_strdup(val); } } ONN("cnonce param missing for 2617-style auth", parms->rfc2617 && !newstate.cnonce); DIGCMP(realm); DIGCMP(username); if (!parms->domain) DIGCMP(uri); DIGCMP(nonce); DIGCMP(opaque); DIGCMP(algorithm); if (parms->rfc2617) { DIGCMP(qop); } if (newstate.cnonce) { state->cnonce = ne_strdup(newstate.cnonce); } if (parms->domain) { state->uri = ne_strdup(newstate.uri); } ONN("no digest param given", !state->digest); CALL(check_digest(state, parms)); state->nc++; return OK; } static char *make_authinfo_header(struct digest_state *state, struct digest_parms *parms) { ne_buffer *buf = ne_buffer_create(); char digest[33], *ncval, *cnonce; if (parms->failure == fail_ai_bad_digest) { strcpy(digest, "fish"); } else { make_digest(state, parms, 1, digest); } if (parms->failure == fail_ai_bad_nc_syntax) { ncval = "zztop"; } else if (parms->failure == fail_ai_bad_nc) { ncval = "999"; } else { ncval = state->ncval; } if (parms->failure == fail_ai_bad_cnonce) { cnonce = "another-fish"; } else { cnonce = state->cnonce; } if (parms->proxy) { ne_buffer_czappend(buf, "Proxy-"); } ne_buffer_czappend(buf, "Authentication-Info: "); if (!parms->rfc2617) { ne_buffer_concat(buf, "rspauth=\"", digest, "\"", NULL); } else { if (parms->failure != fail_ai_omit_nc) { ne_buffer_concat(buf, "nc=", ncval, ", ", NULL); } if (parms->failure != fail_ai_omit_cnonce) { ne_buffer_concat(buf, "cnonce=\"", cnonce, "\", ", NULL); } if (parms->failure != fail_ai_omit_digest) { ne_buffer_concat(buf, "rspauth=\"", digest, "\", ", NULL); } if (parms->send_nextnonce) { state->nonce = ne_concat("next-", state->nonce, NULL); ne_buffer_concat(buf, "nextnonce=\"", state->nonce, "\", ", NULL); state->nc = 1; } ne_buffer_czappend(buf, "qop=\"auth\""); } return ne_buffer_finish(buf); } static char *make_digest_header(struct digest_state *state, struct digest_parms *parms) { ne_buffer *buf = ne_buffer_create(); const char *algorithm; algorithm = parms->failure == fail_bogus_alg ? "fish" : state->algorithm; ne_buffer_concat(buf, parms->proxy ? "Proxy-Authenticate" : "WWW-Authenticate", ": Digest " "realm=\"", parms->realm, "\", ", NULL); if (parms->rfc2617) { ne_buffer_concat(buf, "algorithm=\"", algorithm, "\", ", "qop=\"", state->qop, "\", ", NULL); } if (parms->opaque) { ne_buffer_concat(buf, "opaque=\"", parms->opaque, "\", ", NULL); } if (parms->domain) { ne_buffer_concat(buf, "domain=\"", parms->domain, "\", ", NULL); } if (parms->failure == fail_req0_stale || parms->failure == fail_req0_2069_stale || parms->stale == parms->num_requests) { ne_buffer_concat(buf, "stale='true', ", NULL); } ne_buffer_concat(buf, "nonce=\"", state->nonce, "\"", NULL); return ne_buffer_finish(buf); } /* Server process for Digest auth handling. */ static int serve_digest(ne_socket *sock, void *userdata) { struct digest_parms *parms = userdata; struct digest_state state; char resp[NE_BUFSIZ]; if (parms->proxy) state.uri = "http://www.example.com/fish"; else if (parms->domain) state.uri = "/fish/0"; else state.uri = "/fish"; state.method = "GET"; state.realm = parms->realm; state.nonce = parms->nonce; state.opaque = parms->opaque; state.username = username; state.password = password; state.nc = 1; state.algorithm = parms->md5_sess ? "MD5-sess" : "MD5"; state.qop = "auth"; state.cnonce = state.digest = state.ncval = NULL; parms->num_requests += parms->stale ? 1 : 0; NE_DEBUG(NE_DBG_HTTP, ">>>> Response sequence begins, %d requests.\n", parms->num_requests); want_header = parms->proxy ? "Proxy-Authorization" : "Authorization"; digest_hdr = NULL; got_header = dup_header; CALL(discard_request(sock)); ONV(digest_hdr != NULL, ("got unwarranted WWW-Auth header: %s", digest_hdr)); ne_snprintf(resp, sizeof resp, "HTTP/1.1 %d Auth Denied\r\n" "%s\r\n" "Content-Length: 0\r\n" "\r\n", parms->proxy ? 407 : 401, make_digest_header(&state, parms)); SEND_STRING(sock, resp); /* Give up now if we've sent a challenge which should force the * client to fail immediately: */ if (parms->failure == fail_bogus_alg || parms->failure == fail_req0_stale || parms->failure == fail_req0_2069_stale) { return OK; } do { digest_hdr = NULL; CALL(discard_request(sock)); if (digest_hdr && parms->domain && (parms->num_requests & 1) != 0) { SEND_STRING(sock, "HTTP/1.1 400 Used Auth Outside Domain\r\n\r\n"); return OK; } else if (digest_hdr == NULL && parms->domain && (parms->num_requests & 1) != 0) { /* Do nothing. */ NE_DEBUG(NE_DBG_HTTP, "No Authorization header sent, good.\n"); } else { ONN("no Authorization header sent", digest_hdr == NULL); CALL(verify_digest_header(&state, parms, digest_hdr)); } if (parms->num_requests == parms->stale) { state.nonce = ne_concat("stale-", state.nonce, NULL); state.nc = 1; ne_snprintf(resp, sizeof resp, "HTTP/1.1 %d Auth Denied\r\n" "%s\r\n" "Content-Length: 0\r\n" "\r\n", parms->proxy ? 407 : 401, make_digest_header(&state, parms)); } else if (parms->send_ainfo) { char *ai = make_authinfo_header(&state, parms); ne_snprintf(resp, sizeof resp, "HTTP/1.1 200 Well, if you insist\r\n" "Content-Length: 0\r\n" "%s\r\n" "\r\n", ai); ne_free(ai); } else { ne_snprintf(resp, sizeof resp, "HTTP/1.1 200 You did good\r\n" "Content-Length: 0\r\n" "\r\n"); } SEND_STRING(sock, resp); NE_DEBUG(NE_DBG_HTTP, "Handled request; %d requests remain.\n", parms->num_requests - 1); } while (--parms->num_requests); return OK; } static int test_digest(struct digest_parms *parms) { ne_session *sess; NE_DEBUG(NE_DBG_HTTP, ">>>> Request sequence begins " "(nonce=%s, rfc=%s, stale=%d).\n", parms->nonce, parms->rfc2617 ? "2617" : "2069", parms->stale); if (parms->proxy) { sess = ne_session_create("http", "www.example.com", 80); ne_session_proxy(sess, "localhost", 7777); ne_set_proxy_auth(sess, auth_cb, NULL); } else { sess = ne_session_create("http", "localhost", 7777); ne_set_server_auth(sess, auth_cb, NULL); } CALL(spawn_server(7777, serve_digest, parms)); do { CALL(any_2xx_request(sess, "/fish")); } while (--parms->num_requests); ne_session_destroy(sess); return await_server(); } /* Test for RFC2617-style Digest auth. */ static int digest(void) { struct digest_parms parms[] = { /* RFC 2617-style */ { "WallyWorld", "this-is-a-nonce", NULL, NULL, 1, 0, 0, 0, 0, 1, 0, fail_not }, { "WallyWorld", "this-is-also-a-nonce", "opaque-string", NULL, 1, 0, 0, 0, 0, 1, 0, fail_not }, /* ... with A-I */ { "WallyWorld", "nonce-nonce-nonce", "opaque-string", NULL, 1, 1, 0, 0, 0, 1, 0, fail_not }, /* ... with md5-sess. */ { "WallyWorld", "nonce-nonce-nonce", "opaque-string", NULL, 1, 1, 1, 0, 0, 1, 0, fail_not }, /* many requests, with changing nonces; tests for next-nonce handling bug. */ { "WallyWorld", "this-is-a-nonce", "opaque-thingy", NULL, 1, 1, 0, 0, 1, 20, 0, fail_not }, /* staleness. */ { "WallyWorld", "this-is-a-nonce", "opaque-thingy", NULL, 1, 1, 0, 0, 0, 3, 2, fail_not }, /* 2069 + stale */ { "WallyWorld", "this-is-a-nonce", NULL, NULL, 0, 1, 0, 0, 0, 3, 2, fail_not }, /* RFC 2069-style */ { "WallyWorld", "lah-di-da-di-dah", NULL, NULL, 0, 0, 0, 0, 0, 1, 0, fail_not }, { "WallyWorld", "fee-fi-fo-fum", "opaque-string", NULL, 0, 0, 0, 0, 0, 1, 0, fail_not }, { "WallyWorld", "fee-fi-fo-fum", "opaque-string", NULL, 0, 1, 0, 0, 0, 1, 0, fail_not }, /* Proxy auth */ { "WallyWorld", "this-is-also-a-nonce", "opaque-string", NULL, 1, 1, 0, 0, 0, 1, 0, fail_not }, /* Proxy + A-I */ { "WallyWorld", "this-is-also-a-nonce", "opaque-string", NULL, 1, 1, 0, 1, 0, 1, 0, fail_not }, { NULL } }; size_t n; for (n = 0; parms[n].realm; n++) { CALL(test_digest(&parms[n])); } return OK; } static int digest_failures(void) { struct digest_parms parms; static const struct { enum digest_failure mode; const char *message; } fails[] = { { fail_ai_bad_nc, "nonce count mismatch" }, { fail_ai_bad_nc_syntax, "could not parse nonce count" }, { fail_ai_bad_digest, "digest mismatch" }, { fail_ai_bad_cnonce, "client nonce mismatch" }, { fail_ai_omit_nc, "missing parameters" }, { fail_ai_omit_digest, "missing parameters" }, { fail_ai_omit_cnonce, "missing parameters" }, { fail_bogus_alg, "unknown algorithm" }, { fail_req0_stale, "initial Digest challenge was stale" }, { fail_req0_2069_stale, "initial Digest challenge was stale" }, { fail_not, NULL } }; size_t n; memset(&parms, 0, sizeof parms); parms.realm = "WallyWorld"; parms.nonce = "random-invented-string"; parms.opaque = NULL; parms.send_ainfo = 1; parms.num_requests = 1; for (n = 0; fails[n].message; n++) { ne_session *sess = ne_session_create("http", "localhost", 7777); int ret; parms.failure = fails[n].mode; if (parms.failure == fail_req0_2069_stale) parms.rfc2617 = 0; else parms.rfc2617 = 1; NE_DEBUG(NE_DBG_HTTP, ">>> New Digest failure test, " "expecting failure '%s'\n", fails[n].message); ne_set_server_auth(sess, auth_cb, NULL); CALL(spawn_server(7777, serve_digest, &parms)); ret = any_2xx_request(sess, "/fish"); ONV(ret == NE_OK, ("request success; expecting error '%s'", fails[n].message)); ONV(strstr(ne_get_error(sess), fails[n].message) == NULL, ("request fails with error '%s'; expecting '%s'", ne_get_error(sess), fails[n].message)); ne_session_destroy(sess); if (fails[n].mode == fail_bogus_alg || fails[n].mode == fail_req0_stale) { reap_server(); } else { CALL(await_server()); } } return OK; } static int fail_cb(void *userdata, const char *realm, int tries, char *un, char *pw) { ne_buffer *buf = userdata; char str[64]; ne_snprintf(str, sizeof str, "<%s, %d>", realm, tries); ne_buffer_zappend(buf, str); return -1; } static int fail_challenge(void) { static const struct { const char *resp, *error, *challs; } ts[] = { /* only possible Basic parse failure. */ { "Basic", "missing realm in Basic challenge" }, /* Digest parameter invalid/omitted failure cases: */ { "Digest algorithm=MD5, qop=auth, nonce=\"foo\"", "missing parameter in Digest challenge" }, { "Digest algorithm=MD5, qop=auth, realm=\"foo\"", "missing parameter in Digest challenge" }, { "Digest algorithm=ZEBEDEE-GOES-BOING, qop=auth, realm=\"foo\"", "unknown algorithm in Digest challenge" }, { "Digest algorithm=MD5-sess, realm=\"foo\"", "incompatible algorithm in Digest challenge" }, { "Digest algorithm=MD5, qop=auth, nonce=\"foo\", realm=\"foo\", " "domain=\"http://[::1/\"", "could not parse domain" }, /* Multiple challenge failure cases: */ { "Basic, Digest", "missing parameter in Digest challenge, missing realm in Basic challenge" }, { "Digest realm=\"foo\", algorithm=MD5, qop=auth, nonce=\"foo\"," " Basic realm=\"foo\"", "rejected Digest challenge, rejected Basic challenge" }, { "WhizzBangAuth realm=\"foo\", " "Basic realm='foo'", "ignored WhizzBangAuth challenge, rejected Basic challenge" }, { "", "could not parse challenge" }, /* neon 0.26.x regression in "attempt" handling. */ { "Basic realm=\"foo\", " "Digest realm=\"bar\", algorithm=MD5, qop=auth, nonce=\"foo\"", "rejected Digest challenge, rejected Basic challenge" , "" /* Digest challenge first, Basic second. */ } }; unsigned n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) { char resp[512]; ne_session *sess; int ret; ne_buffer *buf = ne_buffer_create(); ne_snprintf(resp, sizeof resp, "HTTP/1.1 401 Auth Denied\r\n" "WWW-Authenticate: %s\r\n" "Content-Length: 0\r\n" "\r\n", ts[n].resp); CALL(make_session(&sess, single_serve_string, resp)); ne_set_server_auth(sess, fail_cb, buf); ret = any_2xx_request(sess, "/fish"); ONV(ret == NE_OK, ("request success; expecting error '%s'", ts[n].error)); ONV(strstr(ne_get_error(sess), ts[n].error) == NULL, ("request fails with error '%s'; expecting '%s'", ne_get_error(sess), ts[n].error)); if (ts[n].challs) { ONCMP(ts[n].challs, buf->data, "challenge callback", "invocation order"); } ne_session_destroy(sess); ne_buffer_destroy(buf); CALL(await_server()); } return OK; } struct multi_context { int id; ne_buffer *buf; }; static int multi_cb(void *userdata, const char *realm, int tries, char *un, char *pw) { struct multi_context *ctx = userdata; ne_buffer_snprintf(ctx->buf, 128, "[id=%d, realm=%s, tries=%d]", ctx->id, realm, tries); return -1; } static int multi_handler(void) { ne_session *sess; struct multi_context c[2]; unsigned n; ne_buffer *buf = ne_buffer_create(); CALL(make_session(&sess, single_serve_string, "HTTP/1.1 401 Auth Denied\r\n" "WWW-Authenticate: Basic realm='fish'," " Digest realm='food', algorithm=MD5, qop=auth, nonce=gaga\r\n" "Content-Length: 0\r\n" "\r\n")); for (n = 0; n < 2; n++) { c[n].buf = buf; c[n].id = n + 1; } ne_add_server_auth(sess, NE_AUTH_BASIC, multi_cb, &c[0]); ne_add_server_auth(sess, NE_AUTH_DIGEST, multi_cb, &c[1]); any_request(sess, "/fish"); ONCMP("[id=2, realm=food, tries=0]" "[id=1, realm=fish, tries=0]", buf->data, "multiple callback", "invocation order"); ne_session_destroy(sess); ne_buffer_destroy(buf); return await_server(); } static int domains(void) { ne_session *sess; struct digest_parms parms; memset(&parms, 0, sizeof parms); parms.realm = "WallyWorld"; parms.rfc2617 = 1; parms.nonce = "agoog"; parms.domain = "http://localhost:7777/fish/ https://example.com /agaor /other"; parms.num_requests = 6; CALL(make_session(&sess, serve_digest, &parms)); ne_set_server_auth(sess, auth_cb, NULL); ne_session_proxy(sess, "localhost", 7777); CALL(any_2xx_request(sess, "/fish/0")); CALL(any_2xx_request(sess, "/outside")); CALL(any_2xx_request(sess, "/others")); CALL(any_2xx_request(sess, "/fish")); CALL(any_2xx_request(sess, "/fish/2")); CALL(any_2xx_request(sess, "*")); ne_session_destroy(sess); return await_server(); } /* This segfaulted with 0.28.0 through 0.28.2 inclusive. */ static int CVE_2008_3746(void) { ne_session *sess; struct digest_parms parms; memset(&parms, 0, sizeof parms); parms.realm = "WallyWorld"; parms.rfc2617 = 1; parms.nonce = "agoog"; parms.domain = "foo"; parms.num_requests = 1; CALL(make_session(&sess, serve_digest, &parms)); ne_set_server_auth(sess, auth_cb, NULL); ne_session_proxy(sess, "localhost", 7777); any_2xx_request(sess, "/fish/0"); ne_session_destroy(sess); return await_server(); } static int defaults(void) { ne_session *sess; CALL(make_session(&sess, auth_serve, CHAL_WALLY)); ne_add_server_auth(sess, NE_AUTH_DEFAULT, auth_cb, NULL); CALL(any_2xx_request(sess, "/norman")); ne_session_destroy(sess); CALL(await_server()); CALL(make_session(&sess, auth_serve, CHAL_WALLY)); ne_add_server_auth(sess, NE_AUTH_ALL, auth_cb, NULL); CALL(any_2xx_request(sess, "/norman")); ne_session_destroy(sess); return await_server(); } static void fail_hdr(char *value) { auth_failed = 1; } static int serve_forgotten(ne_socket *sock, void *userdata) { auth_failed = 0; got_header = fail_hdr; want_header = "Authorization"; CALL(discard_request(sock)); if (auth_failed) { /* Should not get initial Auth header. Eek. */ send_response(sock, NULL, 403, 1); return 0; } send_response(sock, CHAL_WALLY, 401, 0); got_header = auth_hdr; CALL(discard_request(sock)); if (auth_failed) { send_response(sock, NULL, 403, 1); return 0; } send_response(sock, NULL, 200, 0); ne_sock_read_timeout(sock, 5); /* Last time; should get no Auth header. */ got_header = fail_hdr; CALL(discard_request(sock)); send_response(sock, NULL, auth_failed ? 500 : 200, 1); return 0; } static int forget(void) { ne_session *sess; CALL(make_session(&sess, serve_forgotten, NULL)); ne_set_server_auth(sess, auth_cb, NULL); CALL(any_2xx_request(sess, "/norman")); ne_forget_auth(sess); CALL(any_2xx_request(sess, "/norman")); ne_session_destroy(sess); return await_server(); } /* proxy auth, proxy AND origin */ ne_test tests[] = { T(lookup_localhost), T(basic), T(retries), T(forget_regress), T(tunnel_regress), T(negotiate_regress), T(digest), T(digest_failures), T(fail_challenge), T(multi_handler), T(domains), T(defaults), T(CVE_2008_3746), T(forget), T(NULL) }; davix-R_0_5_0/deps/libneon/test/basic.c000066400000000000000000000172351257152637300200620ustar00rootroot00000000000000/* Tests for high-level HTTP interface (ne_basic.h) Copyright (C) 2002-2008, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include "ne_basic.h" #include "tests.h" #include "child.h" #include "utils.h" static int content_type(void) { int n; static const struct { const char *value, *type, *subtype, *charset; } ctypes[] = { { "foo/bar", "foo", "bar", NULL }, { "foo/bar ", "foo", "bar", NULL }, { "application/xml", "application", "xml", NULL }, /* text/ subtypes default to charset ISO-8859-1, per 2616. */ { "text/lemon", "text", "lemon", "ISO-8859-1" }, /* text/xml defaults to charset us-ascii, per 3280 */ { "text/xml", "text", "xml", "us-ascii" }, #undef TXU #define TXU "text", "xml", "utf-8" /* 2616 doesn't *say* that charset can be quoted, but bets are * that some servers do it anyway. */ { "text/xml; charset=utf-8", TXU }, { "text/xml; charset=utf-8; foo=bar", TXU }, { "text/xml;charset=utf-8", TXU }, { "text/xml ;charset=utf-8", TXU }, { "text/xml;charset=utf-8;foo=bar", TXU }, { "text/xml; foo=bar; charset=utf-8", TXU }, { "text/xml; foo=bar; charset=utf-8; bar=foo", TXU }, { "text/xml; charset=\"utf-8\"", TXU }, { "text/xml; charset='utf-8'", TXU }, { "text/xml; foo=bar; charset=\"utf-8\"; bar=foo", TXU }, #undef TXU /* badly quoted charset should come out as NULL */ { "foo/lemon; charset=\"utf-8", "foo", "lemon", NULL }, { NULL } }; for (n = 0; ctypes[n].value != NULL; n++) { ne_content_type ct; ne_session *sess; ne_request *req; char resp[200]; int rv; ct.type = ct.subtype = ct.charset = ct.value = "unset"; ne_snprintf(resp, sizeof resp, "HTTP/1.0 200 OK\r\n" "Content-Length: 0\r\n" "Content-Type: %s\r\n" "\r\n", ctypes[n].value); CALL(make_session(&sess, single_serve_string, resp)); req = ne_request_create(sess, "GET", "/anyfoo"); ONREQ(ne_request_dispatch(req)); rv = ne_get_content_type(req, &ct); ONV(rv == 0 && !ctypes[n].type, ("expected c-t parse failure for %s", ctypes[n].value)); ONV(rv != 0 && ctypes[n].type, ("c-t parse failure %d for %s", rv, ctypes[n].value)); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); if (rv) continue; ONV(strcmp(ct.type, ctypes[n].type), ("for `%s': type was `%s'", ctypes[n].value, ct.type)); ONV(strcmp(ct.subtype, ctypes[n].subtype), ("for `%s': subtype was `%s'", ctypes[n].value, ct.subtype)); ONV(ctypes[n].charset && ct.charset == NULL, ("for `%s': charset unset", ctypes[n].value)); ONV(ctypes[n].charset == NULL && ct.charset != NULL, ("for `%s': unexpected charset `%s'", ctypes[n].value, ct.charset)); ONV(ctypes[n].charset && ct.charset && strcmp(ctypes[n].charset, ct.charset), ("for `%s': charset was `%s'", ctypes[n].value, ct.charset)); ne_free(ct.value); } return OK; } /* Do ranged GET for range 'start' to 'end'; with 'resp' as response. * If 'fail' is non-NULL, expect ne_get_range to fail, and fail the * test with given message if it doesn't. */ static int do_range(off_t start, off_t end, const char *fail, char *resp) { ne_session *sess; ne_content_range range = {0}; int fd, ret; CALL(make_session(&sess, single_serve_string, resp)); range.start = start; range.end = end; fd = open("/dev/null", O_WRONLY); ret = ne_get_range(sess, "/foo", &range, fd); close(fd); CALL(await_server()); if (fail) { #if 0 t_warning("error was %s", ne_get_error(sess)); #endif ONV(ret == NE_OK, ("%s", fail)); } else { ONREQ(ret); } ne_session_destroy(sess); return OK; } static int get_range(void) { return do_range(1, 10, NULL, "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n" "Content-Range: bytes 1-10/10\r\n" "Content-Length: 10\r\n\r\nabcdefghij"); } static int get_eof_range(void) { return do_range(1, -1, NULL, "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n" "Content-Range: bytes 1-10/10\r\n" "Content-Length: 10\r\n\r\nabcdefghij"); } static int fail_range_length(void) { return do_range(1, 10, "range response length mismatch should fail", "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n" "Content-Range: bytes 1-2/2\r\n" "Content-Length: 2\r\n\r\nab"); } static int fail_range_units(void) { return do_range(1, 2, "range response units check should fail", "HTTP/1.1 206 Widgets\r\n" "Connection: close\r\n" "Content-Range: fish 1-2/2\r\n" "Content-Length: 2\r\n\r\nab"); } static int fail_range_notrange(void) { return do_range(1, 2, "non-ranged response should fail", "HTTP/1.1 200 Widgets\r\n" "Connection: close\r\n" "Content-Range: bytes 1-2/2\r\n" "Content-Length: 2\r\n\r\nab"); } static int fail_range_unsatify(void) { return do_range(1, 2, "unsatisfiable range should fail", "HTTP/1.1 416 No Go\r\n" "Connection: close\r\n" "Content-Length: 2\r\n\r\nab"); } static int dav_capabilities(void) { static const struct { const char *hdrs; unsigned int class1, class2, exec; } caps[] = { { "DAV: 1,2\r\n", 1, 1, 0 }, { "DAV: 1 2\r\n", 0, 0, 0 }, /* these aren't strictly legal DAV: headers: */ { "DAV: 2,1\r\n", 1, 1, 0 }, { "DAV: 1, 2 \r\n", 1, 1, 0 }, { "DAV: 1\r\nDAV:2\r\n", 1, 1, 0 }, { NULL, 0, 0, 0 } }; char resp[BUFSIZ]; int n; for (n = 0; caps[n].hdrs != NULL; n++) { ne_server_capabilities c = {0}; ne_session *sess; ne_snprintf(resp, BUFSIZ, "HTTP/1.0 200 OK\r\n" "Connection: close\r\n" "%s" "\r\n", caps[n].hdrs); CALL(make_session(&sess, single_serve_string, resp)); ONREQ(ne_options(sess, "/foo", &c)); ONV(c.dav_class1 != caps[n].class1, ("class1 was %d not %d", c.dav_class1, caps[n].class1)); ONV(c.dav_class2 != caps[n].class2, ("class2 was %d not %d", c.dav_class2, caps[n].class2)); ONV(c.dav_executable != caps[n].exec, ("class2 was %d not %d", c.dav_executable, caps[n].exec)); CALL(await_server()); ne_session_destroy(sess); } return OK; } static int get(void) { ne_session *sess; int fd; CALL(make_session(&sess, single_serve_string, "HTTP/1.0 200 OK\r\n" "Content-Length: 5\r\n" "\r\n" "abcde")); fd = open("/dev/null", O_WRONLY); ONREQ(ne_get(sess, "/getit", fd)); close(fd); ne_session_destroy(sess); CALL(await_server()); return OK; } ne_test tests[] = { T(lookup_localhost), T(content_type), T(get_range), T(get_eof_range), T(fail_range_length), T(fail_range_units), T(fail_range_notrange), T(fail_range_unsatify), T(dav_capabilities), T(get), T(NULL) }; davix-R_0_5_0/deps/libneon/test/common/000077500000000000000000000000001257152637300201155ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/test/common/ChangeLog000066400000000000000000000163221257152637300216730ustar00rootroot00000000000000Wed Aug 25 19:27:26 2004 Joe Orton * child.c (reset_socket): New function. Mon Jul 5 18:38:08 2004 Joe Orton * tests.c (main): Print 'xfail' for expected failures. Tue Oct 7 21:19:56 2003 Joe Orton * child.c (close_socket): New function. (server_child, spawn_server_repeat): Use it. Fri Jul 25 12:13:59 2003 Joe Orton Add support for test type which is expected to fail memory leak checks. * tests.h (T_XLEAKY, T_EXPECT_LEAKS): New defines. * test.c (main) [NEON_MEMLEAK]: If T_EXPECT_LEAKS is set, fail if the test did not leak memory. Wed Jun 18 20:10:45 2003 Joe Orton * child.c (server_child, spawn_server_repeat): Adapt for new socket API. Sun Mar 9 17:52:11 2003 Joe Orton * test.h (T_EXPECT_FAIL): New constant. (T_XFAIL): New test function wrapper. * tests.c (main): Handle expected failures. Sat Mar 1 21:04:35 2003 Joe Orton Extend the ne_test structure with a 'flags' field which can optionally request leak checking at run-time. * tests.h (ne_test): Add 'flags' field. (T_CHECK_LEAKS): New flag. (T): Use T_CHECK_LEAKS flag by default. (T_LEAKY): Like T, but with no flags set. * tests.c (main) [NEON_MEMLEAK]: If leak checking is requested, if a test passes, but leaks memory, fail the test. Wed Feb 26 21:52:15 2003 Joe Orton * tests.c (main): Test the "disable debugging" mode of ne_debug_init, NE_DBG_FLUSH, and a ne_debug() with no output. Fri Aug 23 22:54:35 2002 Joe Orton * tests.c (main): Call ne_sock_init after ne_debug_init, so that debugging messages are caught from ne_sock_init. Print a warning message if ne_sock_init fails. Wed Aug 21 13:29:20 2002 Joe Orton * tests.h (ONCMP): New macro. Mon Aug 19 16:53:20 2002 Joe Orton * child.c (lookup_localhost): Just use inet_addr to resolve 127.0.0.1. Sun Aug 18 13:50:30 2002 Joe Orton * tests.c (TEST_DEBUG): Add NE_DBG_SSL. Sat Aug 10 10:19:18 2002 Joe Orton * child.c (server_send): Fix declaration. (discard_body): Use NE_FMT_SSIZE_T for print ssize_t's. Sat Jul 6 08:42:37 2002 Joe Orton * child.c (discard_body): New function. Sun Jun 30 10:26:33 2002 Joe Orton * child.c (server_send): New function. (discard_request): Fail with appropriate error. Sun Jun 30 09:03:51 2002 Joe Orton * tests.c (main): Reap server after each test has run. Sun Jun 30 09:00:43 2002 Joe Orton * child.c (reap_server): Set `child' to 0 so child can't be reaped twice. Sun Jun 23 12:09:09 2002 Joe Orton * child.c (serve_file): Use large buffer when sending in chunked mode to support large chunk sizes. Sun Jun 23 09:35:09 2002 Joe Orton * child.c (serve_file): Use NE_FMT_OFF_T and NE_FMT_SSIZE_T. Thu May 30 21:57:39 2002 Joe Orton * child.c (minisleep): Export function. Sun May 19 18:23:19 2002 Joe Orton * child.c, tests.c: s/sock_/ne_sock_/, s/SOCK_/NE_SOCK_/ for socket layer API change. * child.h (SEND_STRING): New macro. Sun May 19 08:57:21 2002 Joe Orton * child.c (lookup_hostname): Conditionally use hstrerror(). Mon Feb 25 20:54:56 2002 Joe Orton * tests.c (t_context): Use ne_vsnprintf. Mon Feb 11 21:52:23 2002 Joe Orton * child.c (lookup_hostname): New function. (server_child, do_listen): Pass around struct in_addr argument. (spawn_server_addr): Renamed from spawn_server, take bind_local flag to use localhost or "real" hostname to bind to. (spawn_server): New function, use spawn_server Mon Feb 11 20:51:27 2002 Joe Orton * child.c (minisleep) [HAVE_USLEEP]: Use nice short usleep() rather than boring long sleep(). Sat Feb 2 14:15:25 2002 Joe Orton * child.c (spawn_server_repeat): Exit child process (with failure) if the server callback fails. Fri Jan 4 22:06:17 2002 Joe Orton * tests.h: Add SKIPREST result value. * tests.c (TEST_DEBUG): Add NE_DBG_LOCKS. (main): Support SKIPREST. Tue Jan 1 20:36:58 2002 Joe Orton * tests.h: Make test_suite symbol have external linkage. Sat Nov 10 22:28:55 2001 Joe Orton * tests.c, test.h: Export name of test suite. Sun Nov 4 13:56:42 2001 Joe Orton * child.c (discard_request): Support retrieving arbitrary header values from request via want_request, got_request globals. Wed Oct 24 21:41:39 2001 Joe Orton * tests.h (ONV): New macro. (ON, ONN): Redefine in terms of ONV. Wed Oct 24 20:44:59 2001 Joe Orton * tests.c (main, t_warning, segv): Use colours when stdout is a terminal device. Wed Oct 24 20:36:38 2001 Joe Orton * tests.c (t_context, t_warning): Renamed from i_am, warning. (t_context): Take printf varargs. * tests.h (ONN, ON): Update, simplify. * child.c: Update. Tue Oct 23 22:15:17 2001 Joe Orton * tests.c (main): Vertically align results after warnings. Tue Oct 2 23:36:44 2001 Joe Orton * child.c (do_listen): Refactored from server_socket, only does bind/listen. (spawn_server): Moved awaken/accept calls here. (spawn_server_repeat, dead_server): New functions. Sun Sep 30 10:14:35 2001 Joe Orton * tests.h: Use a function/name structure for tests, add 'T' macro for easily writing initializers. Rename 'name' global variable to 'test_context' to avoid parameter name collisions. * child.c (spawn_server): Update accordingly. * tests.c (i_am): Update accordingly. (main): Update; prettify output using new 'name' from test structure. Cope better when all tests in a suite are skipped. Sat Sep 29 11:04:40 2001 Joe Orton * child.c (serve_file): If 'chunks' is set in argument object, then deliver the file as a series of chunks. Thu Sep 27 20:28:45 2001 Joe Orton * child.c (serve_file): New function. Thu Sep 27 20:28:41 2001 Joe Orton * child.c (discard_request): Reset clength. Mon Aug 27 00:31:09 2001 Joe Orton * tests.c (test_num): Expose test counter. (segv): Handle segfault nicely. Mon Aug 27 00:30:20 2001 Joe Orton * child.c (discard_request): New function, from request.c in neon/test. Wed Aug 8 22:09:21 2001 Joe Orton * tests.c, test.h: Only define test_argc/argv once. Mon Jul 16 16:30:28 2001 Joe Orton * tests.c (warning): Take printf-style arguments list. Mon Jul 16 16:16:08 2001 Joe Orton * tests.c (main): Cope with skipped tests properly. Mon Jul 16 16:00:59 2001 Joe Orton * tests.c (warning): New function. (main): Cope with warnings. Sun Jul 8 16:09:33 2001 Joe Orton * tests.c (main): Export argc/argv as test_argc, test_argv. davix-R_0_5_0/deps/libneon/test/common/README000066400000000000000000000001401257152637300207700ustar00rootroot00000000000000 Simple test framework for neon; licensed under the GNU GPL. Copyright (C) 2001-2002 Joe Orton davix-R_0_5_0/deps/libneon/test/common/child.c000066400000000000000000000244231257152637300213510ustar00rootroot00000000000000/* Framework for testing with a server process Copyright (C) 2001-2008, Joe Orton 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 "config.h" #include #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include #include "ne_socket.h" #include "ne_utils.h" #include "ne_string.h" #include "tests.h" #include "child.h" static pid_t child = 0; int clength; static struct in_addr lh_addr = {0}, hn_addr = {0}; const char *want_header = NULL; got_header_fn got_header = NULL; char *local_hostname = NULL; /* If we have pipe(), then use a pipe between the parent and child to * know when the child is ready to accept incoming connections. * Otherwise use boring sleep()s trying to avoid the race condition * between listen() and connect() in the two processes. */ #ifdef HAVE_PIPE #define USE_PIPE 1 #endif int lookup_localhost(void) { /* this will break if a system is set up so that `localhost' does * not resolve to 127.0.0.1, but... */ lh_addr.s_addr = inet_addr("127.0.0.1"); return OK; } int lookup_hostname(void) { char buf[BUFSIZ]; struct hostent *ent; local_hostname = NULL; ONV(gethostname(buf, BUFSIZ) < 0, ("gethostname failed: %s", strerror(errno))); ent = gethostbyname(buf); #ifdef HAVE_HSTRERROR ONV(ent == NULL, ("could not resolve `%s': %s", buf, hstrerror(h_errno))); #else ONV(ent == NULL, ("could not resolve `%s'", buf)); #endif local_hostname = ne_strdup(ent->h_name); return OK; } static int do_listen(struct in_addr addr, int port) { int ls = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in saddr = {0}; int val = 1; setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int)); saddr.sin_addr = addr; saddr.sin_port = htons(port); saddr.sin_family = AF_INET; if (bind(ls, (struct sockaddr *)&saddr, sizeof(saddr))) { printf("bind failed: %s\n", strerror(errno)); return -1; } if (listen(ls, 5)) { printf("listen failed: %s\n", strerror(errno)); return -1; } return ls; } void minisleep(void) { #ifdef HAVE_USLEEP usleep(500); #else sleep(1); #endif } int reset_socket(ne_socket *sock) { #ifdef SO_LINGER /* Stevens' magic trick to send an RST on close(). */ struct linger l = {1, 0}; return setsockopt(ne_sock_fd(sock), SOL_SOCKET, SO_LINGER, &l, sizeof l); #else return 1; #endif } /* close 'sock', performing lingering close to avoid premature RST. */ static int close_socket(ne_socket *sock) { #ifdef HAVE_SHUTDOWN char buf[20]; int fd = ne_sock_fd(sock); shutdown(fd, 0); while (ne_sock_read(sock, buf, sizeof buf) > 0); #endif return ne_sock_close(sock); } /* This runs as the child process. */ static int server_child(int readyfd, struct in_addr addr, int port, server_fn callback, void *userdata) { ne_socket *s = ne_sock_create(); int ret, listener; in_child(); listener = do_listen(addr, port); if (listener < 0) return FAIL; #ifdef USE_PIPE /* Tell the parent we're ready for the request. */ if (write(readyfd, "a", 1) != 1) abort(); #endif ONN("accept failed", ne_sock_accept(s, listener)); ret = callback(s, userdata); close_socket(s); return ret; } int spawn_server(int port, server_fn fn, void *ud) { return spawn_server_addr(1, port, fn, ud); } int spawn_server_addr(int bind_local, int port, server_fn fn, void *ud) { int fds[2]; struct in_addr addr; addr = bind_local?lh_addr:hn_addr; #ifdef USE_PIPE if (pipe(fds)) { perror("spawn_server: pipe"); return FAIL; } #else /* avoid using uninitialized variable. */ fds[0] = fds[1] = 0; #endif child = fork(); ONN("fork server", child == -1); if (child == 0) { /* this is the child. */ int ret; ret = server_child(fds[1], addr, port, fn, ud); #ifdef USE_PIPE close(fds[0]); close(fds[1]); #endif /* print the error out otherwise it gets lost. */ if (ret) { printf("server child failed: %s\n", test_context); } /* and quit the child. */ NE_DEBUG(NE_DBG_HTTP, "child exiting with %d\n", ret); exit(ret); } else { char ch; #ifdef USE_PIPE if (read(fds[0], &ch, 1) < 0) perror("parent read"); close(fds[0]); close(fds[1]); #else minisleep(); #endif return OK; } } int spawn_server_repeat(int port, server_fn fn, void *userdata, int n) { int fds[2]; #ifdef USE_PIPE if (pipe(fds)) { perror("spawn_server: pipe"); return FAIL; } #else /* avoid using uninitialized variable. */ fds[0] = fds[1] = 0; #endif child = fork(); if (child == 0) { /* this is the child. */ int listener, count = 0; in_child(); listener = do_listen(lh_addr, port); #ifdef USE_PIPE if (write(fds[1], "Z", 1) != 1) abort(); #endif close(fds[1]); close(fds[0]); /* Loop serving requests. */ while (++count < n) { ne_socket *sock = ne_sock_create(); int ret; NE_DEBUG(NE_DBG_HTTP, "child awaiting connection #%d.\n", count); ONN("accept failed", ne_sock_accept(sock, listener)); ret = fn(sock, userdata); close_socket(sock); NE_DEBUG(NE_DBG_HTTP, "child served request, %d.\n", ret); if (ret) { printf("server child failed: %s\n", test_context); exit(-1); } /* don't send back notification to parent more than * once. */ } NE_DEBUG(NE_DBG_HTTP, "child aborted.\n"); close(listener); exit(-1); } else { char ch; /* this is the parent. wait for the child to get ready */ #ifdef USE_PIPE if (read(fds[0], &ch, 1) < 0) perror("parent read"); close(fds[0]); close(fds[1]); #else minisleep(); #endif } return OK; } int dead_server(void) { int status; if (waitpid(child, &status, WNOHANG)) { /* child quit already! */ return FAIL; } NE_DEBUG(NE_DBG_HTTP, "child has not quit.\n"); return OK; } int await_server(void) { int status, code; (void) wait(&status); /* so that we aren't reaped by mistake. */ child = 0; if (WIFEXITED(status)) { code = WEXITSTATUS(status); ONV(code, ("server process terminated abnormally: %s (%d)", code == FAIL ? "FAIL" : "error", code)); } else { ONV(WIFSIGNALED(status), ("server process terminated by signal %d", WTERMSIG(status))); } return OK; } int reap_server(void) { int status; if (child != 0) { (void) kill(child, SIGTERM); minisleep(); (void) wait(&status); child = 0; } return OK; } ssize_t server_send(ne_socket *sock, const char *str, size_t len) { NE_DEBUG(NE_DBG_HTTP, "Sending: %.*s\n", (int)len, str); return ne_sock_fullwrite(sock, str, len); } int discard_request(ne_socket *sock) { char buffer[1024]; size_t offset = want_header?strlen(want_header):0; clength = 0; NE_DEBUG(NE_DBG_HTTP, "Discarding request...\n"); do { ONV(ne_sock_readline(sock, buffer, 1024) < 0, ("error reading line: %s", ne_sock_error(sock))); NE_DEBUG(NE_DBG_HTTP, "[req] %s", buffer); if (strncasecmp(buffer, "content-length:", 15) == 0) { clength = atoi(buffer + 16); } if (got_header != NULL && want_header != NULL && strncasecmp(buffer, want_header, offset) == 0 && buffer[offset] == ':') { char *value = buffer + offset + 1; if (*value == ' ') value++; got_header(ne_shave(value, "\r\n")); } } while (strcmp(buffer, "\r\n") != 0); return OK; } int discard_body(ne_socket *sock) { while (clength > 0) { char buf[BUFSIZ]; size_t bytes = clength; ssize_t ret; if (bytes > sizeof(buf)) bytes = sizeof(buf); NE_DEBUG(NE_DBG_HTTP, "Discarding %" NE_FMT_SIZE_T " bytes.\n", bytes); ret = ne_sock_read(sock, buf, bytes); ONV(ret < 0, ("socket read failed (%" NE_FMT_SSIZE_T "): %s", ret, ne_sock_error(sock))); clength -= ret; NE_DEBUG(NE_DBG_HTTP, "Got %" NE_FMT_SSIZE_T " bytes.\n", ret); } NE_DEBUG(NE_DBG_HTTP, "Discard successful.\n"); return OK; } int serve_file(ne_socket *sock, void *ud) { char buffer[BUFSIZ]; struct stat st; struct serve_file_args *args = ud; ssize_t ret; int fd; CALL(discard_request(sock)); ne_sock_fullread(sock, buffer, clength); fd = open(args->fname, O_RDONLY); if (fd < 0) { SEND_STRING(sock, "HTTP/1.0 404 File Not Found\r\n" "Content-Length: 0\r\n\r\n"); return 0; } ONN("fstat fd", fstat(fd, &st)); SEND_STRING(sock, "HTTP/1.0 200 OK\r\n"); if (args->chunks) { sprintf(buffer, "Transfer-Encoding: chunked\r\n"); } else { sprintf(buffer, "Content-Length: %" NE_FMT_OFF_T "\r\n", st.st_size); } if (args->headers) { strcat(buffer, args->headers); } strcat(buffer, "\r\n"); SEND_STRING(sock, buffer); NE_DEBUG(NE_DBG_HTTP, "Serving %s (%" NE_FMT_OFF_T " bytes).\n", args->fname, st.st_size); if (args->chunks) { char buf[1024]; while ((ret = read(fd, &buf, args->chunks)) > 0) { /* this is a small integer, cast it explicitly to avoid * warnings with printing an ssize_t. */ sprintf(buffer, "%x\r\n", (unsigned int)ret); SEND_STRING(sock, buffer); ONN("writing body", ne_sock_fullwrite(sock, buf, ret)); SEND_STRING(sock, "\r\n"); } SEND_STRING(sock, "0\r\n\r\n"); } else { while ((ret = read(fd, buffer, BUFSIZ)) > 0) { ONN("writing body", ne_sock_fullwrite(sock, buffer, ret)); } } ONN("error reading from file", ret < 0); (void) close(fd); return OK; } davix-R_0_5_0/deps/libneon/test/common/child.h000066400000000000000000000075641257152637300213650ustar00rootroot00000000000000/* Framework for testing with a server process Copyright (C) 2001-2004, Joe Orton 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 CHILD_H #define CHILD_H 1 #include "config.h" #ifdef HAVE_STRING_H #include /* for strlen() */ #endif #include "ne_socket.h" /* Test which does DNS lookup on "localhost": this must be the first * named test. */ int lookup_localhost(void); /* Test which looks up real local hostname. */ int lookup_hostname(void); /* set to local hostname if lookup_hostname succeeds. */ extern char *local_hostname; /* Callback for spawn_server. */ typedef int (*server_fn)(ne_socket *sock, void *userdata); /* Spawns server child process: * - forks child process. * - child process listens on localhost at given port. * - when you connect to it, 'fn' is run... * fn is passed the client/server socket as first argument, * and userdata as second. * - the socket is closed when 'fn' returns, so don't close in in 'fn'. */ int spawn_server(int port, server_fn fn, void *userdata); /* Like spawn_server; if bind_local is non-zero, binds server to * localhost, otherwise, binds server to real local hostname. (must * have called lookup_localhost or lookup_hostname as approprate * beforehand). */ int spawn_server_addr(int bind_local, int port, server_fn fn, void *userdata); /* Like spawn server except will continue accepting connections and * processing requests, up to 'n' times. If 'n' is reached, then the * child process exits with a failure status. */ int spawn_server_repeat(int port, server_fn fn, void *userdata, int n); /* Blocks until child process exits, and gives return code of 'fn'. */ int await_server(void); /* Kills child process. */ int reap_server(void); /* Returns non-zero if server process has already died. */ int dead_server(void); /* If discard_request comes across a header called 'want_header', it * will call got_header passing the header field value. */ extern const char *want_header; typedef void (*got_header_fn)(char *value); extern got_header_fn got_header; /* Send string to child; ne_sock_fullwrite with debugging. */ ssize_t server_send(ne_socket *sock, const char *data, size_t len); /* Utility macro: send given string down socket. */ #define SEND_STRING(sock, str) server_send((sock), (str), strlen((str))) /* Tries to ensure that the socket will be closed using RST rather * than FIN. */ int reset_socket(ne_socket *sock); /* Utility function: discard request. Sets context on error. */ int discard_request(ne_socket *sock); /* Utility function: discard request body. Sets context on error. */ int discard_body(ne_socket *sock); struct serve_file_args { const char *fname; const char *headers; int chunks; }; /* Utility function: callback for spawn_server: pass pointer to * serve_file_args as userdata, and args->fname is served as a 200 * request. If args->headers is non-NULL, it must be a set of * CRLF-terminated lines which is added in to the response headers. * If args->chunks is non-zero, the file is delivered using chunks of * that size. */ int serve_file(ne_socket *sock, void *ud); /* set to value of C-L header by discard_request. */ extern int clength; /* Sleep for a short time. */ void minisleep(void); #endif /* CHILD_H */ davix-R_0_5_0/deps/libneon/test/common/run.sh000077500000000000000000000003371257152637300212630ustar00rootroot00000000000000#!/bin/sh rm -f debug.log rm -f child.log # for shared builds. LD_LIBRARY_PATH=../src/.libs:$LD_LIBRARY_PATH export LD_LIBRARY_PATH for f in $*; do if ./$f; then : else echo FAILURE exit 1 fi done exit 0 davix-R_0_5_0/deps/libneon/test/common/tests.c000066400000000000000000000257061257152637300214350ustar00rootroot00000000000000/* Stupidly simple test framework Copyright (C) 2001-2009, Joe Orton 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 "config.h" #include #include #ifdef HAVE_SIGNAL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_LOCALE_H #include #endif #include "ne_string.h" #include "ne_utils.h" #include "ne_socket.h" #include "ne_i18n.h" #include "tests.h" #include "child.h" char test_context[BUFSIZ]; int have_context = 0; static FILE *child_debug, *debug; char **test_argv; int test_argc; const char *test_suite; int test_num; static int quiet, count; /* statistics for all tests so far */ static int passes = 0, fails = 0, skipped = 0, warnings = 0; /* per-test globals: */ static int warned, aborted = 0; static const char *test_name; /* current test name */ static int use_colour = 0; static int flag_child; /* resource for ANSI escape codes: * http://www.isthe.com/chongo/tech/comp/ansi_escapes.html */ #define COL(x) do { if (use_colour) printf("\033[" x "m"); } while (0) #define NOCOL COL("00") void t_context(const char *context, ...) { va_list ap; va_start(ap, context); ne_vsnprintf(test_context, BUFSIZ, context, ap); va_end(ap); if (flag_child) { NE_DEBUG(NE_DBG_HTTP, "context: %s\n", test_context); } have_context = 1; } void t_warning(const char *str, ...) { va_list ap; COL("43;01"); printf("WARNING:"); NOCOL; putchar(' '); va_start(ap, str); vprintf(str, ap); va_end(ap); warnings++; warned++; putchar('\n'); } #define TEST_DEBUG \ (NE_DBG_HTTP | NE_DBG_SOCKET | NE_DBG_HTTPBODY | NE_DBG_HTTPAUTH | \ NE_DBG_LOCKS | NE_DBG_XMLPARSE | NE_DBG_XML | NE_DBG_SSL | \ NE_DBG_HTTPPLAIN) #define W(m) do { if (write(0, m, strlen(m)) < 0) exit(99); } while(0) #define W_RED(m) do { if (use_colour) W("\033[41;37;01m"); \ W(m); if (use_colour) W("\033[00m\n"); } while (0); /* Signal handler for child processes. */ static void child_segv(int signo) { signal(SIGSEGV, SIG_DFL); signal(SIGABRT, SIG_DFL); W_RED("Fatal signal in child!"); kill(getpid(), SIGSEGV); minisleep(); } /* Signal handler for parent process. */ static void parent_segv(int signo) { signal(SIGSEGV, SIG_DFL); signal(SIGABRT, SIG_DFL); if (signo == SIGSEGV) { W_RED("FAILED - segmentation fault"); } else if (signo == SIGABRT) { W_RED("ABORTED"); } reap_server(); kill(getpid(), SIGSEGV); minisleep(); } void in_child(void) { ne_debug_init(child_debug, TEST_DEBUG); NE_DEBUG(TEST_DEBUG, "**** Child forked for test %s ****\n", test_name); signal(SIGSEGV, child_segv); signal(SIGABRT, child_segv); flag_child = 1; } static const char dots[] = "......................"; static void print_prefix(int n) { if (quiet) { printf("\r%s%.*s %2u/%2u ", test_suite, (int) (strlen(dots) - strlen(test_suite)), dots, n + 1, count); } else { if (warned) { printf(" %s ", dots); } else { printf("\r%2d. %s%.*s ", n, test_name, (int) (strlen(dots) - strlen(test_name)), dots); } } fflush(stdout); } int main(int argc, char *argv[]) { int n; char *tmp; /* get basename(argv[0]) */ test_suite = strrchr(argv[0], '/'); if (test_suite == NULL) { test_suite = argv[0]; } else { test_suite++; } #ifdef HAVE_SETLOCALE setlocale(LC_MESSAGES, ""); #endif ne_i18n_init(NULL); #if defined(HAVE_ISATTY) && defined(STDOUT_FILENO) if (isatty(STDOUT_FILENO)) { use_colour = 1; } #endif test_argc = argc; test_argv = argv; debug = fopen("debug.log", "a"); if (debug == NULL) { fprintf(stderr, "%s: Could not open debug.log: %s\n", test_suite, strerror(errno)); return -1; } child_debug = fopen("child.log", "a"); if (child_debug == NULL) { fprintf(stderr, "%s: Could not open child.log: %s\n", test_suite, strerror(errno)); fclose(debug); return -1; } if (tests[0].fn == NULL) { printf("-> no tests found in `%s'\n", test_suite); return -1; } /* install special SEGV handler. */ signal(SIGSEGV, parent_segv); signal(SIGABRT, parent_segv); /* test the "no-debugging" mode of ne_debug. */ ne_debug_init(NULL, 0); NE_DEBUG(TEST_DEBUG, "This message should go to /dev/null"); /* enable debugging for real. */ ne_debug_init(debug, TEST_DEBUG); NE_DEBUG(TEST_DEBUG | NE_DBG_FLUSH, "Version string: %s\n", ne_version_string()); /* another silly test. */ NE_DEBUG(0, "This message should also go to /dev/null"); if (ne_sock_init()) { COL("43;01"); printf("WARNING:"); NOCOL; printf(" Socket library initalization failed.\n"); } if ((tmp = getenv("TEST_QUIET")) != NULL && strcmp(tmp, "1") == 0) { quiet = 1; } if (!quiet) printf("-> running `%s':\n", test_suite); for (count = 0; tests[count].fn; count++) /* nullop */; for (n = 0; !aborted && tests[n].fn != NULL; n++) { int result, is_xfail = 0; #ifdef NEON_MEMLEAK size_t allocated = ne_alloc_used; int is_xleaky = 0; #endif test_name = tests[n].name; print_prefix(n); have_context = 0; test_num = n; warned = 0; fflush(stdout); NE_DEBUG(TEST_DEBUG, "******* Running test %d: %s ********\n", n, test_name); /* run the test. */ result = tests[n].fn(); #ifdef NEON_MEMLEAK /* issue warnings for memory leaks, if requested */ if ((tests[n].flags & T_CHECK_LEAKS) && result == OK && ne_alloc_used > allocated) { t_context("memory leak of %" NE_FMT_SIZE_T " bytes", ne_alloc_used - allocated); fprintf(debug, "Blocks leaked: "); ne_alloc_dump(debug); result = FAIL; } else if (tests[n].flags & T_EXPECT_LEAKS && result == OK && ne_alloc_used == allocated) { t_context("expected memory leak not detected"); result = FAIL; } else if (tests[n].flags & T_EXPECT_LEAKS && result == OK) { fprintf(debug, "Blocks leaked (expected): "); ne_alloc_dump(debug); is_xleaky = 1; } #endif if (tests[n].flags & T_EXPECT_FAIL) { if (result == OK) { t_context("test passed but expected failure"); result = FAIL; } else if (result == FAIL) { result = OK; is_xfail = 1; } } print_prefix(n); switch (result) { case OK: passes++; if (is_xfail) { COL("32;07"); printf("XFAIL"); } else if (!quiet) { COL("32"); printf("pass"); } NOCOL; if (quiet && is_xfail) { printf(" - %s", test_name); if (have_context) { printf(" (%s)", test_context); } } if (warned && !quiet) { printf(" (with %d warning%s)", warned, (warned > 1)?"s":""); } #ifdef NEON_MEMLEAK if (is_xleaky) { if (quiet) { printf("expected leak - %s: %" NE_FMT_SIZE_T " bytes", test_name, ne_alloc_used - allocated); } else { printf(" (expected leak, %" NE_FMT_SIZE_T " bytes)", ne_alloc_used - allocated); } } #endif if (!quiet || is_xfail) putchar('\n'); break; case FAILHARD: aborted = 1; /* fall-through */ case FAIL: COL("41;37;01"); printf("FAIL"); NOCOL; if (quiet) { printf(" - %s", test_name); } if (have_context) { printf(" (%s)", test_context); } putchar('\n'); fails++; break; case SKIPREST: aborted = 1; /* fall-through */ case SKIP: COL("44;37;01"); printf("SKIPPED"); NOCOL; if (quiet) { printf(" - %s", test_name); } if (have_context) { printf(" (%s)", test_context); } putchar('\n'); skipped++; break; default: COL("41;37;01"); printf("OOPS"); NOCOL; printf(" unexpected test result `%d'\n", result); break; } reap_server(); if (quiet) { print_prefix(n); } } /* discount skipped tests */ if (skipped) { if (!quiet) printf("-> %d %s.\n", skipped, skipped == 1 ? "test was skipped" : "tests were skipped"); n -= skipped; } /* print the summary. */ if (skipped && n == 0) { if (quiet) puts("(all skipped)"); else printf("<- all tests skipped for `%s'.\n", test_suite); } else { if (quiet) { printf("\r%s%.*s %2u/%2u ", test_suite, (int) (strlen(dots) - strlen(test_suite)), dots, passes, count); if (fails == 0) { COL("32"); printf("passed"); NOCOL; putchar(' '); } else { printf("passed, %d failed ", fails); } if (skipped) printf("(%d skipped) ", skipped); } else /* !quiet */ printf("<- summary for `%s': " "of %d tests run: %d passed, %d failed. %.1f%%\n", test_suite, n, passes, fails, 100*(float)passes/n); if (warnings) { if (quiet) { printf("(%d warning%s)\n", warnings, warnings==1?"s":""); } else { printf("-> %d warning%s issued.\n", warnings, warnings==1?" was":"s were"); } } else if (quiet) { putchar('\n'); } } if (fclose(debug)) { fprintf(stderr, "Error closing debug.log: %s\n", strerror(errno)); fails = 1; } if (fclose(child_debug)) { fprintf(stderr, "Error closing child.log: %s\n", strerror(errno)); fails = 1; } ne_sock_exit(); return fails; } davix-R_0_5_0/deps/libneon/test/common/tests.h000066400000000000000000000105401257152637300214300ustar00rootroot00000000000000/* Stupidly simple test framework Copyright (C) 2001-2004, Joe Orton This 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. This 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 this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef TESTS_H #define TESTS_H 1 #ifdef HAVE_STRING_H #include #endif #include #define OK 0 #define FAIL 1 #define FAILHARD 2 /* fail and skip all succeeding tests in this suite. */ #define SKIP 3 /* test was skipped because precondition was not met */ #define SKIPREST 4 /* skipped, and skip all succeeding tests in suite */ /* A test function. Must return any of OK, FAIL, FAILHARD, SKIP, or * SKIPREST. May call t_warning() any number of times. If not * returning OK, optionally call t_context to provide an error * message. */ typedef int (*test_func)(void); typedef struct { test_func fn; /* the function to test. */ const char *name; /* the name of the test. */ int flags; } ne_test; /* possible values for flags: */ #define T_CHECK_LEAKS (1) /* check for memory leaks */ #define T_EXPECT_FAIL (2) /* expect failure */ #define T_EXPECT_LEAKS (4) /* expect memory leak failures */ /* array of tests to run: must be defined by each test suite. */ extern ne_test tests[]; /* define a test function which has the same name as the function, * and does check for memory leaks. */ #define T(fn) { fn, #fn, T_CHECK_LEAKS } /* define a test function which is expected to return FAIL. */ #define T_XFAIL(fn) { fn, #fn, T_EXPECT_FAIL | T_CHECK_LEAKS } /* define a test function which isn't checked for memory leaks. */ #define T_LEAKY(fn) { fn, #fn, 0 } /* define a test function which is expected to fail memory leak checks */ #define T_XLEAKY(fn) { fn, #fn, T_EXPECT_LEAKS } /* current test number */ extern int test_num; /* name of test suite */ extern const char *test_suite; /* Provide result context message. */ void t_context(const char *ctx, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 1, 2))) #endif /* __GNUC__ */ ; extern char test_context[]; /* the command-line arguments passed in to the test suite: */ extern char **test_argv; extern int test_argc; /* child process should call this. */ void in_child(void); /* issue a warning. */ void t_warning(const char *str, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 1, 2))) #endif /* __GNUC__ */ ; /* Macros for easily writing is-not-zero comparison tests; the ON* * macros fail the function if a comparison is not zero. * * ONV(x,vs) takes a comparison X, and a printf varargs list for * the failure message. * e.g. ONV(strcmp(bar, "foo"), ("bar was %s not 'foo'", bar)) * * ON(x) takes a comparison X, and uses the line number for the failure * message. e.g. ONV(strcmp(bar, "foo")) * * ONN(n, x) takes a comparison X, and a flat string failure message. * e.g. ONN("foo was wrong", strcmp(bar, "foo")) */ #define ONV(x,vs) do { if ((x)) { t_context vs; return FAIL; } } while (0) #define ON(x) ONV((x), ("line %d", __LINE__ )) #define ONN(n,x) ONV((x), (n)) /* ONCMP(exp, act, name): 'exp' is the expected string, 'act' is the * actual string for some field 'name'. Succeeds if strcmp(exp,act) * == 0 or both are NULL. */ #define ONCMP(exp, act, ctx, name) do { \ ONV(exp && !act, ("%s: " name " was NULL, expected '%s'", ctx, exp)); \ ONV(!exp && act, ("%s: " name " was '%s', expected NULL", ctx, act)); \ ONV(exp && strcmp(exp, act), ("%s: " name " was '%s' not '%s'", ctx, act, exp)); \ } while (0) /* return immediately with result of test 'x' if it fails. */ #define CALL(x) do { int t_ret = (x); if (t_ret != OK) return t_ret; } while (0) /* PRECOND: skip current test if condition 'x' is not true. */ #define PRECOND(x) do { if (!(x)) { return SKIP; } } while (0) #endif /* TESTS_H */ davix-R_0_5_0/deps/libneon/test/compress.c000066400000000000000000000251311257152637300206260ustar00rootroot00000000000000/* tests for compressed response handling. Copyright (C) 2001-2008, Joe Orton 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 "config.h" #ifdef HAVE_UNISTD_H #include #endif #include #include "ne_compress.h" #include "ne_auth.h" #include "tests.h" #include "child.h" #include "utils.h" static enum { f_partial = 0, f_mismatch, f_complete } failed; static const char *newsfn = "random.txt"; static int init(void) { return lookup_localhost(); } #define EXTRA_DEBUG 0 /* disabled by default */ static int reader(void *ud, const char *block, size_t len) { struct string *b = ud; #if EXTRA_DEBUG NE_DEBUG(NE_DBG_HTTP, "reader: got (%d): [[[%.*s]]]\n", (int)len, (int)len, block); #endif if (failed == f_mismatch) return -1; /* catch multiple len == 0 call as issued by 0.25.0 only: */ if (failed == f_complete) { NE_DEBUG(NE_DBG_HTTP, "reader: called after complete, len=%d\n", (int)len); failed = f_mismatch; return -1; } if (failed == f_partial && len == 0) { if (b->len != 0) { NE_DEBUG(NE_DBG_HTTP, "reader: got length %d at EOF\n", (int)b->len); failed = f_mismatch; } else { failed = f_complete; } return 0; } if (len > b->len || memcmp(b->data, block, len) != 0) { NE_DEBUG(NE_DBG_HTTP, "reader: failed, got [[%.*s]] not [[%.*s]]\n", (int)len, block, (int)b->len, b->data); failed = f_mismatch; return -1; } else { b->data += len; b->len -= len; #if EXTRA_DEBUG NE_DEBUG(NE_DBG_HTTP, "reader: OK, %d bytes remaining\n", (int)b->len); #endif } return 0; } static int file2buf(int fd, ne_buffer *buf) { char buffer[BUFSIZ]; ssize_t n; while ((n = read(fd, buffer, BUFSIZ)) > 0) { ne_buffer_append(buf, buffer, n); } return 0; } static int do_fetch(const char *realfn, const char *gzipfn, int chunked, int expect_fail) { ne_session *sess; ne_request *req; int fd, ret; ne_buffer *buf = ne_buffer_create(); struct serve_file_args sfargs; ne_decompress *dc; struct string body; fd = open(realfn, O_RDONLY); ONN("failed to open file", fd < 0); file2buf(fd, buf); (void) close(fd); body.data = buf->data; body.len = buf->used - 1; failed = f_partial; if (gzipfn) { sfargs.fname = gzipfn; sfargs.headers = "Content-Encoding: gzip\r\n"; } else { sfargs.fname = realfn; sfargs.headers = NULL; } sfargs.chunks = chunked; CALL(make_session(&sess, serve_file, &sfargs)); req = ne_request_create(sess, "GET", "/"); dc = ne_decompress_reader(req, ne_accept_2xx, reader, &body); #ifdef NE_DEBUGGING ne_debug_init(ne_debug_stream, ne_debug_mask & ~NE_DBG_HTTPBODY); #endif ret = ne_request_dispatch(req); #ifdef NE_DEBUGGING ne_debug_init(ne_debug_stream, ne_debug_mask | NE_DBG_HTTPBODY); #endif ONN("file not served", ne_get_status(req)->code != 200); ONN("decompress succeeded", expect_fail && !ret); ONV(!expect_fail && ret, ("decompress failed: %s", ne_get_error(sess))); NE_DEBUG(NE_DBG_HTTP, "session error: %s\n", ne_get_error(sess)); ne_decompress_destroy(dc); ne_request_destroy(req); ne_session_destroy(sess); ne_buffer_destroy(buf); if (expect_fail) { /* if the decompress callback fails, the connection may * be aborted and hence the server will abort. */ reap_server(); } else { CALL(await_server()); } if (!expect_fail) { ONN("inflated response truncated", failed == f_partial); ONN("inflated response mismatch", failed == f_mismatch); } return OK; } static int fetch(const char *realfn, const char *gzipfn, int chunked) { return do_fetch(realfn, gzipfn, chunked, 0); } /* Test the no-compression case. */ static int not_compressed(void) { return fetch(newsfn, NULL, 0); } static int simple(void) { return fetch(newsfn, "file1.gz", 0); } /* file1.gz has an embedded filename. */ static int withname(void) { return fetch(newsfn, "file2.gz", 0); } /* deliver various different sizes of chunks: tests the various * decoding cases. */ static int chunked_1b_wn(void) { return fetch(newsfn, "file2.gz", 1); } static int chunked_1b(void) { return fetch(newsfn, "file1.gz", 1); } static int chunked_12b(void) { return fetch(newsfn, "file2.gz", 12); } static int chunked_20b(void) { return fetch(newsfn, "file2.gz", 20); } static int chunked_10b(void) { return fetch(newsfn, "file1.gz", 10); } static int chunked_10b_wn(void) { return fetch(newsfn, "file2.gz", 10); } static int fail_trailing(void) { return do_fetch(newsfn, "trailing.gz", 0, 1); } static int fail_trailing_1b(void) { return do_fetch(newsfn, "trailing.gz", 1, 1); } static int fail_truncate(void) { return do_fetch(newsfn, "truncated.gz", 0, 1); } static int fail_bad_csum(void) { return do_fetch(newsfn, "badcsum.gz", 0, 1); } static int fail_corrupt1(void) { return do_fetch(newsfn, "corrupt1.gz", 0, 1); } static int fail_corrupt2(void) { return do_fetch(newsfn, "corrupt2.gz", 0, 1); } static int fail_empty(void) { return do_fetch(newsfn, "empty.gz", 0, 1); } static int notcomp_empty(void) { return fetch("empty.gz", NULL, 0); } static int auth_cb(void *userdata, const char *realm, int tries, char *un, char *pw) { strcpy(un, "foo"); strcpy(pw, "bar"); return tries; } static int retry_compress_helper(ne_accept_response acceptor, struct double_serve_args *args, struct string *expect) { ne_session *sess; ne_request *req; ne_decompress *dc; CALL(make_session(&sess, double_serve_sstring, args)); ne_set_server_auth(sess, auth_cb, NULL); req = ne_request_create(sess, "GET", "/"); dc = ne_decompress_reader(req, acceptor, reader, expect); failed = f_partial; ONREQ(ne_request_dispatch(req)); ne_decompress_destroy(dc); ONN("got bad response body", failed != f_complete); CALL(await_server()); ne_request_destroy(req); ne_session_destroy(sess); return OK; } #define SSTRING(x) { x, sizeof(x) - 1 } static struct double_serve_args retry_gz_args = { SSTRING("HTTP/1.1 401 Get Away\r\n" "Content-Encoding: gzip\r\n" "WWW-Authenticate: Basic realm=WallyWorld\r\n" "Content-Length: 5\r\n" "\r\n" "abcde"), SSTRING("HTTP/1.1 200 OK\r\n" "Server: foo\r\n" "Content-Length: 5\r\n" "Connection: close\r\n" "\r\n" "hello") }; /* Test where the response to the retried request does *not* have * a content-encoding, whereas the original 401 response did. */ static int retry_notcompress(void) { struct string expect = { "hello", 5 }; return retry_compress_helper(ne_accept_2xx, &retry_gz_args, &expect); } static struct double_serve_args retry_gz_args2 = { SSTRING("HTTP/1.1 401 Get Away\r\n" "Content-Encoding: gzip\r\n" "WWW-Authenticate: Basic realm=WallyWorld\r\n" "Content-Length: 25\r\n" "\r\n" "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xcb\x48\xcd\xc9\xc9\x07" "\x00\x86\xa6\x10\x36\x05\x00\x00\x00"), SSTRING("HTTP/1.1 200 OK\r\n" "Server: foo\r\n" "Content-Encoding: gzip\r\n" "Content-Length: 25\r\n" "Connection: close\r\n" "\r\n" "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x2b\xcf\x2f\xca\x49\x01" "\x00\x43\x11\x77\x3a\x05\x00\x00\x00") }; static int retry_accept(void *ud, ne_request *req, const ne_status *st) { struct string *expect = ud; NE_DEBUG(NE_DBG_HTTP, "retry_accept callback for %d response\n", st->code); if (expect->len == 4 && strcmp(expect->data, "fish") == 0) { /* first time through */ expect->data = "hello"; } else { expect->data = "world"; } expect->len = 5; failed = f_partial; /* reset the state */ return 1; } /* Test where the response to the retried request *does* have a * content-encoding, as did the original 401 response. */ static int retry_compress(void) { struct string expect = { "fish", 4 }; return retry_compress_helper(retry_accept, &retry_gz_args2, &expect); } #define READER_ABORT_ERR "reader_abort error string" static int reader_abort(void *ud, const char *buf, size_t len) { ne_session *sess = ud; ne_set_error(sess, READER_ABORT_ERR); return len; } /* check that a callback abort does abort the response */ static int compress_abort(void) { ne_session *sess; ne_request *req; struct serve_file_args sfargs; ne_decompress *dc; int ret; sfargs.fname = "file1.gz"; sfargs.headers = "Content-Encoding: gzip\r\n"; sfargs.chunks = 0; CALL(make_session(&sess, serve_file, &sfargs)); req = ne_request_create(sess, "GET", "/abort"); dc = ne_decompress_reader(req, ne_accept_2xx, reader_abort, sess); ret = ne_request_dispatch(req); reap_server(); ONN("request was not aborted", ret != NE_ERROR); ONV(strcmp(ne_get_error(sess), READER_ABORT_ERR), ("session error was %s not %s", ne_get_error(sess), READER_ABORT_ERR)); reap_server(); ne_decompress_destroy(dc); ne_request_destroy(req); ne_session_destroy(sess); return OK; } ne_test tests[] = { T_LEAKY(init), T(not_compressed), T(simple), T(withname), T(fail_trailing), T(fail_trailing_1b), T(fail_bad_csum), T(fail_truncate), T(fail_corrupt1), T(fail_corrupt2), T(fail_empty), T(notcomp_empty), T(chunked_1b), T(chunked_1b_wn), T(chunked_12b), T(chunked_20b), T(chunked_10b), T(chunked_10b_wn), T(retry_notcompress), T(retry_compress), T(compress_abort), T(NULL) }; davix-R_0_5_0/deps/libneon/test/expired.pem000066400000000000000000000022301257152637300207650ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDODCCAuKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBoTELMAkGA1UEBhMCR0Ix FzAVBgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlkZ2UxGjAY BgNVBAoTEU5lb24gSGFja2VycyBMdGQuMRUwEwYDVQQLEwxOZW9uIFFBIERlcHQx EjAQBgNVBAMTCWxvY2FsaG9zdDEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYu b3JnMB4XDTAyMDEyMTIwMzkwNFoXDTAyMDEzMTIwMzkwNFowgaExCzAJBgNVBAYT AkdCMRcwFQYDVQQIEw5DYW1icmlkZ2VzaGlyZTESMBAGA1UEBxMJQ2FtYnJpZGdl MRowGAYDVQQKExFOZW9uIEhhY2tlcnMgTHRkLjEVMBMGA1UECxMMTmVvbiBRQSBE ZXB0MRIwEAYDVQQDEwlsb2NhbGhvc3QxHjAcBgkqhkiG9w0BCQEWD25lb25Ad2Vi ZGF2Lm9yZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDzRU5sZ8+CWQPvPkqJw9Kl oEgT2FqzZR9RT/qbJuRBmRphiRr0g7JOh5Mr7LXaKShedFLhGidutyKKwIZJnRht AgMBAAGjggEBMIH+MB0GA1UdDgQWBBRFA3ktzHSuD9uB6mJOWoElmOtknzCBzgYD VR0jBIHGMIHDgBRFA3ktzHSuD9uB6mJOWoElmOtkn6GBp6SBpDCBoTELMAkGA1UE BhMCR0IxFzAVBgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlk Z2UxGjAYBgNVBAoTEU5lb24gSGFja2VycyBMdGQuMRUwEwYDVQQLEwxOZW9uIFFB IERlcHQxEjAQBgNVBAMTCWxvY2FsaG9zdDEeMBwGCSqGSIb3DQEJARYPbmVvbkB3 ZWJkYXYub3JnggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQBDSFbe 9EjP+IyZ4vhJSk66gLSN8CnafoGm5JHpNOHy5gWLh7j0a/dxWRd4gpoBYBB6Y9rO YV6Eq3njdj0gu+NN -----END CERTIFICATE----- davix-R_0_5_0/deps/libneon/test/htdocs/000077500000000000000000000000001257152637300201115ustar00rootroot00000000000000davix-R_0_5_0/deps/libneon/test/htdocs/plain000066400000000000000000000000131257152637300211310ustar00rootroot00000000000000Test file. davix-R_0_5_0/deps/libneon/test/largefile.c000066400000000000000000000116771257152637300207370ustar00rootroot00000000000000/* Tests for LFS support in neon Copyright (C) 2004-2006, Joe Orton 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 "config.h" #include #include #include #ifdef HAVE_STDINT_H #include #endif #include "ne_request.h" #include "child.h" #include "utils.h" #include "tests.h" #ifndef INT64_C #define INT64_C(x) x ## LL #endif static const char data[] = "Hello, world.\n"; static off64_t point = INT64_C(2) << 32; #define SPARSE "sparse.bin" /* make a sparse large file */ static int make_sparse_file(void) { int fd = open64(SPARSE, O_CREAT | O_TRUNC | O_WRONLY, 0644); ONN("could not create large file " SPARSE, fd < 0); ONN("seek to point", lseek64(fd, point, SEEK_SET) != point); ONN("could not write to file", write(fd, data, strlen(data)) != (ssize_t)strlen(data)); ONN("close failed", close(fd)); return OK; } /* server function which checks that the request body sent was the * same as the 'data' array. */ static int serve_check_body(ne_socket *sock, void *userdata) { CALL(discard_request(sock)); if (clength != (ssize_t)strlen(data)) { CALL(discard_body(sock)); SEND_STRING(sock, "HTTP/1.0 400 Bad Request Body Length\r\n" "\r\n"); } else { char buf[20]; if (ne_sock_fullread(sock, buf, clength) == 0) { SEND_STRING(sock, "HTTP/1.0 200 OK Then!\r\n\r\n"); } } return 0; } /* sends a small segment of the file from a high offset. */ static int send_high_offset(void) { int ret, fd = open64(SPARSE, O_RDONLY); ne_session *sess; ne_request *req; ONN("could not open sparse file", fd < 0); CALL(make_session(&sess, serve_check_body, NULL)); req = ne_request_create(sess, "PUT", "/sparse"); ne_set_request_body_fd(req, fd, point, strlen(data)); ret = ne_request_dispatch(req); CALL(await_server()); ONV(ret != NE_OK || ne_get_status(req)->klass != 2, ("request failed: %s", ne_get_error(sess))); ne_request_destroy(req); ne_session_destroy(sess); close(fd); return OK; } #if 1 #define RESPSIZE INT64_C(4295008256) #define RESPSTR "4295008256" #else #define RESPSIZE INT64_C(2147491840) /* 2^31+8192 */ #define RESPSTR "2147491840" #endif /* Reads a request, sends a large response, reads a request, then * sends a little response. */ static int serve_large_response(ne_socket *sock, void *ud) { int n = 0; char empty[8192]; CALL(discard_request(sock)); SEND_STRING(sock, "HTTP/1.1 200 OK\r\n" "Content-Length: " RESPSTR "\r\n" "Server: BigFileServerTM\r\n" "\r\n"); memset(empty, 0, sizeof empty); for (n = 0; n < RESPSIZE/sizeof(empty); n++) { if (ne_sock_fullwrite(sock, empty, sizeof empty)) { NE_DEBUG(NE_DBG_SOCKET, "fullwrite failed\n"); return 1; } } NE_DEBUG(NE_DBG_SOCKET, "Wrote %d lots of %d\n", n, (int)sizeof empty); CALL(discard_request(sock)); SEND_STRING(sock, "HTTP/1.1 200 OK\r\n" "Connection: close\r\n\r\n"); return 0; } static int read_large_response(void) { ne_session *sess; ne_request *req; off64_t count = 0; int ret; char buf[8192]; #ifdef NE_DEBUGGING int old_mask = ne_debug_mask; #endif CALL(make_session(&sess, serve_large_response, NULL)); req = ne_request_create(sess, "GET", "/foo"); ret = ne_begin_request(req); #ifdef NE_DEBUGGING ne_debug_init(ne_debug_stream, ne_debug_mask & ~(NE_DBG_HTTPBODY|NE_DBG_HTTP)); #endif if (ret == NE_OK) { while ((ret = ne_read_response_block(req, buf, sizeof buf)) > 0) count += ret; if (ret == NE_OK) ret = ne_end_request(req); } #ifdef NE_DEBUGGING ne_debug_init(ne_debug_stream, old_mask); #endif ONV(ret, ("request failed: %s", ne_get_error(sess))); ONV(count != RESPSIZE, ("response body was %" NE_FMT_OFF64_T " not %" NE_FMT_OFF64_T, count, RESPSIZE)); ne_request_destroy(req); CALL(any_2xx_request(sess, "/bar")); CALL(await_server()); ne_session_destroy(sess); return OK; } ne_test tests[] = { T(make_sparse_file), T(send_high_offset), T(read_large_response), T(NULL), }; davix-R_0_5_0/deps/libneon/test/lock.c000066400000000000000000000417421257152637300177310ustar00rootroot00000000000000/* lock tests Copyright (C) 2002-2006, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_request.h" #include "ne_locks.h" #include "ne_socket.h" #include "ne_basic.h" #include "ne_auth.h" #include "tests.h" #include "child.h" #include "utils.h" #define EOL "\r\n" /* returns an activelock XML element. */ static char *activelock(enum ne_lock_scope scope, int depth, const char *owner, long timeout, const char *token_href) { static char buf[BUFSIZ]; ne_snprintf(buf, BUFSIZ, "\n" "\n" "\n" "%d\n" "%s\n" "Second-%ld\n" "%s\n" "", scope==ne_lockscope_exclusive?"exclusive":"shared", depth, owner, timeout, token_href); return buf; } /* return body of LOCK response for given lock. */ static char *lock_response(enum ne_lock_scope scope, int depth, const char *owner, long timeout, const char *token_href) { static char buf[BUFSIZ]; sprintf(buf, "\n" "" "%s\n", activelock(scope, depth, owner, timeout, token_href)); return buf; } /* return body of LOCK response where response gives multiple * activelocks (i.e. shared locks). */ static char *multi_lock_response(struct ne_lock **locks) { ne_buffer *buf = ne_buffer_create(); int n; ne_buffer_zappend(buf, "\n" "" ""); for (n = 0; locks[n] != NULL; n++) { char *lk = activelock(locks[n]->scope, locks[n]->depth, locks[n]->owner, locks[n]->timeout, locks[n]->token); ne_buffer_zappend(buf, lk); } ne_buffer_zappend(buf, ""); return ne_buffer_finish(buf); } static char *discover_response(const char *href, const struct ne_lock *lk) { static char buf[BUFSIZ]; ne_snprintf(buf, BUFSIZ, "\n" "\n" "%s\n" "%s\n" "HTTP/1.1 200 OK\n" "\n", href, activelock(lk->scope, lk->depth, lk->owner, 7200, lk->token)); return buf; } static struct ne_lock *make_lock(const char *path, const char *token, enum ne_lock_scope scope, int depth) { struct ne_lock *lock = ne_calloc(sizeof *lock); if (lock->token) lock->token = ne_strdup(token); lock->scope = scope; lock->depth = depth; lock->uri.host = ne_strdup("localhost"); lock->uri.scheme = ne_strdup("http"); lock->uri.path = ne_strdup(path); lock->uri.port = 7777; return lock; } /* Tests for lock store handling. */ static int store_single(void) { ne_lock_store *store = ne_lockstore_create(); struct ne_lock *lk = make_lock("/foo", "blah", ne_lockscope_exclusive, 0); struct ne_lock *lk2; ONN("create failed", store == NULL); ONN("new lock store not empty", ne_lockstore_first(store) != NULL); ne_lockstore_add(store, lk); ONN("lock not found in store", ne_lockstore_first(store) != lk); ONN(">1 locks in store?", ne_lockstore_next(store) != NULL); lk2 = ne_lockstore_findbyuri(store, &lk->uri); ONN("lock not found by URI", lk2 == NULL); ONN("other lock found by URI", lk2 != lk); ne_lockstore_remove(store, lk); ONN("store not empty after removing lock", ne_lockstore_first(store) != NULL); ONN("lock still found after removing lock", ne_lockstore_findbyuri(store, &lk->uri) != NULL); ne_lockstore_destroy(store); ne_lock_destroy(lk); return OK; } static int store_several(void) { ne_lock_store *store = ne_lockstore_create(); struct ne_lock *lk = make_lock("/foo", "blah", ne_lockscope_exclusive, 0); struct ne_lock *lk2 = make_lock("/bar", "blee", ne_lockscope_exclusive, 0); struct ne_lock *lf, *lf2; ONN("create failed", store == NULL); ne_lockstore_add(store, lk); ne_lockstore_add(store, lk2); lf = ne_lockstore_first(store); ONN("lock store empty", lf == NULL); lf2 = ne_lockstore_next(store); ONN("lock store >2 locks", ne_lockstore_next(store) != NULL); /* guarantee that _first, _next returned either of the * combinations: (lf, lf2) or (lf2, lf) */ ONN("found wrong locks", ((lf != lk && lf != lk2) || (lf2 != lk && lf2 != lk2) || (lf == lf2))); ONN("first find failed", ne_lockstore_findbyuri(store, &lk->uri) != lk); ONN("second find failed", ne_lockstore_findbyuri(store, &lk2->uri) != lk2); ne_lockstore_remove(store, lk); ne_lock_destroy(lk); ONN("remove left stray lock?", ne_lockstore_first(store) != lk2); ONN("remove left >1 lock?", ne_lockstore_next(store) != NULL); ne_lockstore_remove(store, lk2); ne_lock_destroy(lk2); ONN("store not empty after removing all locks", ne_lockstore_first(store) != NULL); ne_lockstore_destroy(store); return OK; } /* regression test for <= 0.18.2, where timeout field was not parsed correctly. */ static int lock_timeout(void) { ne_session *sess; char *resp, *rbody = lock_response(ne_lockscope_exclusive, 0, "me", 6500, "opaquelocktoken:foo"); struct ne_lock *lock = ne_lock_create(); resp = ne_concat("HTTP/1.1 200 OK\r\n" "Server: neon-test-server\r\n" "Content-type: application/xml" EOL "Lock-Token: " EOL "Connection: close\r\n\r\n", rbody, NULL); CALL(make_session(&sess, single_serve_string, resp)); ne_free(resp); ne_fill_server_uri(sess, &lock->uri); lock->uri.path = ne_strdup("/foo"); lock->timeout = 5; ONREQ(ne_lock(sess, lock)); ONN("lock timeout ignored in response", lock->timeout != 6500); ne_session_destroy(sess); ne_lock_destroy(lock); CALL(await_server()); return OK; } static int verify_if; static const char *verify_if_expect; static void got_if_header(char *value) { verify_if = !strcmp(verify_if_expect, value); NE_DEBUG(NE_DBG_HTTP, "Verified If header, %d: got [%s] expected [%s]\n", verify_if, value, verify_if_expect); } /* Server callback which checks that an If: header is recevied. */ static int serve_verify_if(ne_socket *sock, void *userdata) { /* tell us about If headers in the request. */ want_header = "If"; got_header = got_if_header; verify_if_expect = userdata; verify_if = 0; CALL(discard_request(sock)); if (verify_if) { ON(SEND_STRING(sock, "HTTP/1.1 200 OK" EOL)); } else { ON(SEND_STRING(sock, "HTTP/1.1 403 Wrong If Header" EOL)); } ON(SEND_STRING(sock, "Connection: close" EOL EOL)); return OK; } /* Make a request which will require a lock. */ static int do_request(ne_session *sess, const char *path, int depth, int modparent) { ne_request *req = ne_request_create(sess, "RANDOM", path); if (depth > 0) { ne_add_depth_header(req, depth); } if (depth != -1) ne_lock_using_resource(req, path, depth); if (modparent) ne_lock_using_parent(req, path); ONREQ(ne_request_dispatch(req)); ONV(ne_get_status(req)->code != 200, ("request failed: %s", ne_get_error(sess))); ne_request_destroy(req); return OK; } /* Tests If: header submission, for a lock of depth 'lockdepth' at * 'lockpath', with a request to 'reqpath' which Depth header of * 'reqdepth'. If modparent is non-zero; the request is flagged to * modify the parent resource too. */ static int submit_test(const char *lockpath, int lockdepth, const char *reqpath, int reqdepth, int modparent) { ne_lock_store *store = ne_lockstore_create(); ne_session *sess; struct ne_lock *lk = ne_lock_create(); char *expect_if; int ret; expect_if = ne_concat(" ()", NULL); CALL(make_session(&sess, serve_verify_if, expect_if)); ne_free(expect_if); ne_fill_server_uri(sess, &lk->uri); lk->uri.path = ne_strdup(lockpath); lk->token = ne_strdup("somelocktoken"); lk->depth = lockdepth; /* register the lock store, and add our lock for "/foo" to it. */ ne_lockstore_register(store, sess); ne_lockstore_add(store, lk); ret = do_request(sess, reqpath, reqdepth, modparent); CALL(await_server()); ne_lockstore_destroy(store); ne_session_destroy(sess); return ret; } static int if_simple(void) { return submit_test("/foo", 0, "/foo", 0, 0); } static int if_under_infinite(void) { return submit_test("/foo", NE_DEPTH_INFINITE, "/foo/bar", 0, 0); } static int if_infinite_over(void) { return submit_test("/foo/bar", 0, "/foo/", NE_DEPTH_INFINITE, 0); } static int if_child(void) { return submit_test("/foo/", 0, "/foo/bar", 0, 1); } /* this is a special test, where the PARENT resource of "/foo/bar" is * modified, but NOT "/foo/bar" itself. An UNLOCK request on a * lock-null resource can do this; see ne_unlock() for the comment. * Regression test for neon <= 0.19.3, which didn't handle this * correctly. */ static int if_covered_child(void) { return submit_test("/", NE_DEPTH_INFINITE, "/foo/bar", -1, 1); } static int serve_discovery(ne_socket *sock, void *userdata) { char buf[BUFSIZ], *resp = userdata; ON(discard_request(sock)); ONN("no PROPFIND body", clength == 0); ON(ne_sock_read(sock, buf, clength) < 0); ON(SEND_STRING(sock, "HTTP/1.0 207 OK" EOL "Connection: close" EOL EOL)); ON(SEND_STRING(sock, resp)); return OK; } struct result_args { struct ne_lock *lock; int result; }; static int lock_compare(const char *ctx, const struct ne_lock *a, const struct ne_lock *b) { ONV(!a->uri.host || !a->uri.scheme || !a->uri.path, ("URI structure incomplete in %s", ctx)); ONV(ne_uri_cmp(&a->uri, &b->uri) != 0, ("URI comparison failed for %s: %s not %s", ctx, ne_uri_unparse(&a->uri), ne_uri_unparse(&b->uri))); ONV(a->depth != b->depth, ("%s depth was %d not %d", ctx, a->depth, b->depth)); ONV(a->scope != b->scope, ("%s scope was %d not %d", ctx, a->scope, b->scope)); ONV(a->type != b->type, ("%s type was %d not %d", ctx, a->type, b->type)); return OK; } static void discover_result(void *userdata, const struct ne_lock *lk, const ne_uri *uri, const ne_status *st) { struct result_args *args = userdata; args->result = lock_compare("discovered lock", lk, args->lock); } static int discover(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); char *response; int ret; struct result_args args; args.lock = ne_lock_create(); args.lock->owner = ne_strdup("someowner"); args.lock->token = ne_strdup("sometoken"); /* default */ args.result = FAIL; t_context("results callback never invoked"); ne_fill_server_uri(sess, &args.lock->uri); args.lock->uri.path = ne_strdup("/lockme"); response = discover_response("/lockme", args.lock); CALL(spawn_server(7777, serve_discovery, response)); ret = ne_lock_discover(sess, "/lockme", discover_result, &args); CALL(await_server()); ONREQ(ret); ne_lock_destroy(args.lock); ne_session_destroy(sess); return args.result; } /* Check that the token for the response header */ static int lock_shared(void) { ne_session *sess; char *resp, *rbody; struct ne_lock *lock, *resplocks[3]; #define FILLK(l, s) do { \ (l)->token = strdup("opaquelocktoken:" s); \ (l)->owner = strdup("owner " s); \ (l)->uri.path = strdup("/" s); (l)->uri.host = strdup("localhost"); \ (l)->uri.scheme = strdup("http"); (l)->uri.port = 7777; } while (0) resplocks[0] = ne_lock_create(); resplocks[1] = ne_lock_create(); resplocks[2] = NULL; FILLK(resplocks[0], "alpha"); FILLK(resplocks[1], "beta"); resplocks[0]->timeout = 100; resplocks[1]->timeout = 200; rbody = multi_lock_response(resplocks); resp = ne_concat("HTTP/1.1 200 OK\r\n" "Server: neon-test-server\r\n" "Content-type: application/xml" EOL "Lock-Token: " EOL "Connection: close\r\n\r\n", rbody, NULL); ne_free(rbody); CALL(make_session(&sess, single_serve_string, resp)); ne_free(resp); lock = ne_lock_create(); ne_fill_server_uri(sess, &lock->uri); lock->uri.path = ne_strdup("/beta"); ONREQ(ne_lock(sess, lock)); CALL(await_server()); CALL(lock_compare("returned lock", resplocks[1], lock)); ne_session_destroy(sess); ne_lock_destroy(lock); ne_lock_destroy(resplocks[0]); ne_lock_destroy(resplocks[1]); return OK; } static void dummy_discover(void *userdata, const struct ne_lock *lock, const ne_uri *uri, const ne_status *status) { } /* This failed with neon 0.25.x and earlier when memory leak detection * is enabled. */ static int fail_discover(void) { ne_session *sess; int ret; CALL(make_session(&sess, single_serve_string, "HTTP/1.0 207 OK\r\n" "Connection: close\r\n" "\r\n" "\n" "\n" "/foo/bar\n" "\n")); ret = ne_lock_discover(sess, "/foo", dummy_discover, NULL); CALL(await_server()); ONN("discovery okay for response with invalid XML!?", ret != NE_ERROR); ne_session_destroy(sess); return OK; } static int no_creds(void *ud, const char *realm, int attempt, char *username, char *password) { return -1; } static int fail_lockauth(void) { ne_session *sess; struct ne_lock *lock; int ret; struct many_serve_args args; args.str = "HTTP/1.1 401 Auth Denied\r\n" "WWW-Authenticate: Basic realm=\"realm@host\"\r\n" "Content-Length: 0\r\n" "\r\n"; args.count = 2; CALL(make_session(&sess, many_serve_string, &args)); ne_set_server_auth(sess, no_creds, NULL); lock = make_lock("/foo", NULL, ne_lockscope_exclusive, NE_DEPTH_ZERO); ret = ne_lock(sess, lock); ONV(ret != NE_AUTH, ("attempt to lock did not fail with NE_AUTH: %d (%s)", ret, ne_get_error(sess))); ne_lock_destroy(lock); lock = make_lock("/bar", "fish", ne_lockscope_exclusive, NE_DEPTH_ZERO); lock->token = ne_strdup("opaquelocktoken:gah"); ret = ne_unlock(sess, lock); ONV(ret != NE_AUTH, ("attempt to unlock did not fail with NE_AUTH: %d (%s)", ret, ne_get_error(sess))); ne_lock_destroy(lock); CALL(await_server()); ne_session_destroy(sess); return OK; } /* Regression test for neon 0.25.0 regression in ne_lock() error * handling. */ static int fail_noheader(void) { ne_session *sess; char *resp, *rbody = lock_response(ne_lockscope_exclusive, 0, "me", 6500, "opaquelocktoken:foo"); struct ne_lock *lock = ne_lock_create(); int ret; resp = ne_concat("HTTP/1.1 200 OK\r\n" "Server: neon-test-server\r\n" "Content-type: application/xml" EOL "Connection: close\r\n\r\n", rbody, NULL); CALL(make_session(&sess, single_serve_string, resp)); ne_free(resp); ne_fill_server_uri(sess, &lock->uri); lock->uri.path = ne_strdup("/foo"); lock->timeout = NE_TIMEOUT_INFINITE; ret = ne_lock(sess, lock); ONN("LOCK request did not fail", ret != NE_ERROR); ONV(strstr(ne_get_error(sess), "LOCK response missing Lock-Token header") == NULL, ("unexpected error: %s", ne_get_error(sess))); ne_session_destroy(sess); ne_lock_destroy(lock); return await_server(); } ne_test tests[] = { T(lookup_localhost), T(store_single), T(store_several), T(if_simple), T(if_under_infinite), T(if_infinite_over), T(if_child), T(if_covered_child), T(lock_timeout), T(lock_shared), T(discover), T(fail_discover), T(fail_lockauth), T(fail_noheader), T(NULL) }; davix-R_0_5_0/deps/libneon/test/makekeys000077500000000000000000000177421257152637300203770ustar00rootroot00000000000000#!/bin/sh # Helper script to create CA and server certificates. srcdir=${1-.} OPENSSL=/usr/bin/openssl CONF=${srcdir}/openssl.conf REQ="${OPENSSL} req -config ${CONF}" CA="${OPENSSL} ca -config ${CONF} -batch" # MKCERT makes a self-signed cert MKCERT="${REQ} -x509 -new -days 900" REQDN=reqDN STRMASK=default CADIR=./ca export REQDN STRMASK CADIR asn1date() { date -d "$1" "+%y%m%d%H%M%SZ" } openssl version 1>&2 set -ex for i in ca ca1 ca2 ca3; do rm -rf $i mkdir $i touch $i/index.txt echo 01 > $i/serial ${OPENSSL} genrsa -rand ${srcdir}/../configure > $i/key.pem done ${OPENSSL} genrsa -rand ${srcdir}/../configure > client.key ${OPENSSL} dsaparam -genkey -rand ${srcdir}/../configure 1024 > client.dsap ${OPENSSL} gendsa client.dsap > clientdsa.key ${MKCERT} -key ca/key.pem -out ca/cert.pem < T61String csr_fields "`echo -e 'H\0350llo World'`" localhost | ${REQ} -new -key ${srcdir}/server.key -out t61subj.csr STRMASK=pkix # => BMPString csr_fields "`echo -e 'H\0350llo World'`" localhost | ${REQ} -new -key ${srcdir}/server.key -out bmpsubj.csr STRMASK=utf8only # => UTF8String csr_fields "`echo -e 'H\0350llo World'`" localhost | ${REQ} -new -key ${srcdir}/server.key -out utf8subj.csr STRMASK=default ### produce a set of CA certs csr_fields "First Random CA" "first.example.com" "CAs Ltd." Lincoln Lincolnshire | \ ${MKCERT} -key ${srcdir}/server.key -out ca1.pem csr_fields "Second Random CA" "second.example.com" "CAs Ltd." Falmouth Cornwall | \ ${MKCERT} -key ${srcdir}/server.key -out ca2.pem csr_fields "Third Random CA" "third.example.com" "CAs Ltd." Ipswich Suffolk | \ ${MKCERT} -key ${srcdir}/server.key -out ca3.pem csr_fields "Fourth Random CA" "fourth.example.com" "CAs Ltd." Norwich Norfolk | \ ${MKCERT} -key ${srcdir}/server.key -out ca4.pem cat ca/cert.pem ca[1234].pem > calist.pem csr_fields "Wildcard Cert Dept" "*.example.com" | \ ${REQ} -new -key ${srcdir}/server.key -out wildcard.csr csr_fields "Wildcard IP Cert" "*.0.0.1" | \ ${REQ} -new -key ${srcdir}/server.key -out wildip.csr csr_fields "Neon Client Cert" ignored.example.com | \ ${REQ} -new -key client.key -out client.csr csr_fields "Neon Client Cert" ignored.example.com | \ ${REQ} -new -key clientdsa.key -out clientdsa.csr ### requests using special DN. REQDN=reqDN.doubleCN csr_fields "Double CN Dept" "nohost.example.com localhost" | ${REQ} -new -key ${srcdir}/server.key -out twocn.csr REQDN=reqDN.CNfirst echo localhost | ${REQ} -new -key ${srcdir}/server.key -out cnfirst.csr REQDN=reqDN.missingCN echo GB | ${REQ} -new -key ${srcdir}/server.key -out missingcn.csr REQDN=reqDN.justEmail echo blah@example.com | ${REQ} -new -key ${srcdir}/server.key -out justmail.csr # presume AVAs will come out in least->most specific order still... REQDN=reqDN.twoOU csr_fields "Second OU Dept First OU Dept" | ${REQ} -new -key ${srcdir}/server.key -out twoou.csr ### don't put ${REQ} invocations after here for f in server client clientdsa twocn caseless cnfirst \ t61subj bmpsubj utf8subj \ missingcn justmail twoou wildcard wildip wrongcn; do ${CA} -days 900 -in ${f}.csr -out ${f}.cert done ${CA} -startdate `asn1date "2 days ago"` -enddate `asn1date "yesterday"` -in expired.csr -out expired.cert ${CA} -startdate `asn1date "tomorrow"` -enddate `asn1date "2 days"` -in notyet.csr -out notyet.cert for n in 1 2 3 4 5 6 7 8 9; do ${CA} -extensions altExt${n} -days 900 \ -in altname${n}.csr -out altname${n}.cert done # Sign this CSR using the intermediary CA CADIR=./ca2 ${CA} -days 900 -in server.csr -out ca2server.cert # And create a file with the concatenation of both EE and intermediary # cert. cat ca2server.cert ca2/cert.pem > ca2server.pem # sign with expired CA CADIR=./ca1 ${CA} -days 3 -in server.csr -out ca1server.cert # sign with not yet valid CA CADIR=./ca3 ${CA} -days 3 -in server.csr -out ca3server.cert MKPKCS12="${OPENSSL} pkcs12 -export -passout stdin -in client.cert -inkey client.key" # generate a PKCS12 cert from the client cert: -passOUT because it's the # passphrase on the OUTPUT cert, confusing... echo foobar | ${MKPKCS12} -name "Just A Neon Client Cert" -out client.p12 # generate a PKCS#12 cert with no password and a friendly name echo | ${MKPKCS12} -name "An Unencrypted Neon Client Cert" -out unclient.p12 # PKCS#12 cert with DSA key echo | ${OPENSSL} pkcs12 -name "An Unencrypted Neon DSA Client Cert" \ -export -passout stdin \ -in clientdsa.cert -inkey clientdsa.key \ -out dsaclient.p12 # generate a PKCS#12 cert with no friendly name echo | ${MKPKCS12} -out noclient.p12 # generate a PKCS#12 cert with no private keys echo | ${MKPKCS12} -nokeys -out nkclient.p12 # generate a PKCS#12 cert without the cert echo | ${MKPKCS12} -nokeys -out ncclient.p12 # generate an encoded PKCS#12 cert with no private keys echo foobar | ${MKPKCS12} -nokeys -out enkclient.p12 # a PKCS#12 cert including a bundled CA cert echo foobar | ${MKPKCS12} -certfile ca/cert.pem -name "A Neon Client Cert With CA" -out clientca.p12 ### a file containing a complete chain cat ca/cert.pem server.cert > chain.pem ### NSS database initialization, for testing PKCS#11. CERTUTIL=notfound PK12UTIL=notfound if [ ${CERTUTIL} != "notfound" -a ${PK12UTIL} != "notfound" ]; then rm -rf nssdb nssdb-dsa mkdir nssdb nssdb-dsa echo foobar > nssdb.pw ${CERTUTIL} -d nssdb -N -f nssdb.pw ${PK12UTIL} -d nssdb -K foobar -W '' -i unclient.p12 ${CERTUTIL} -d nssdb-dsa -N -f nssdb.pw ${PK12UTIL} -d nssdb-dsa -K foobar -W '' -i dsaclient.p12 rm -f nssdb.pw fi davix-R_0_5_0/deps/libneon/test/makekeys.sh000077500000000000000000000177371257152637300210140ustar00rootroot00000000000000#!/bin/sh # Helper script to create CA and server certificates. srcdir=${1-.} OPENSSL=@OPENSSL@ CONF=${srcdir}/openssl.conf REQ="${OPENSSL} req -config ${CONF}" CA="${OPENSSL} ca -config ${CONF} -batch" # MKCERT makes a self-signed cert MKCERT="${REQ} -x509 -new -days 900" REQDN=reqDN STRMASK=default CADIR=./ca export REQDN STRMASK CADIR asn1date() { date -d "$1" "+%y%m%d%H%M%SZ" } openssl version 1>&2 set -ex for i in ca ca1 ca2 ca3; do rm -rf $i mkdir $i touch $i/index.txt echo 01 > $i/serial ${OPENSSL} genrsa -rand ${srcdir}/../configure > $i/key.pem done ${OPENSSL} genrsa -rand ${srcdir}/../configure > client.key ${OPENSSL} dsaparam -genkey -rand ${srcdir}/../configure 1024 > client.dsap ${OPENSSL} gendsa client.dsap > clientdsa.key ${MKCERT} -key ca/key.pem -out ca/cert.pem < T61String csr_fields "`echo -e 'H\0350llo World'`" localhost | ${REQ} -new -key ${srcdir}/server.key -out t61subj.csr STRMASK=pkix # => BMPString csr_fields "`echo -e 'H\0350llo World'`" localhost | ${REQ} -new -key ${srcdir}/server.key -out bmpsubj.csr STRMASK=utf8only # => UTF8String csr_fields "`echo -e 'H\0350llo World'`" localhost | ${REQ} -new -key ${srcdir}/server.key -out utf8subj.csr STRMASK=default ### produce a set of CA certs csr_fields "First Random CA" "first.example.com" "CAs Ltd." Lincoln Lincolnshire | \ ${MKCERT} -key ${srcdir}/server.key -out ca1.pem csr_fields "Second Random CA" "second.example.com" "CAs Ltd." Falmouth Cornwall | \ ${MKCERT} -key ${srcdir}/server.key -out ca2.pem csr_fields "Third Random CA" "third.example.com" "CAs Ltd." Ipswich Suffolk | \ ${MKCERT} -key ${srcdir}/server.key -out ca3.pem csr_fields "Fourth Random CA" "fourth.example.com" "CAs Ltd." Norwich Norfolk | \ ${MKCERT} -key ${srcdir}/server.key -out ca4.pem cat ca/cert.pem ca[1234].pem > calist.pem csr_fields "Wildcard Cert Dept" "*.example.com" | \ ${REQ} -new -key ${srcdir}/server.key -out wildcard.csr csr_fields "Wildcard IP Cert" "*.0.0.1" | \ ${REQ} -new -key ${srcdir}/server.key -out wildip.csr csr_fields "Neon Client Cert" ignored.example.com | \ ${REQ} -new -key client.key -out client.csr csr_fields "Neon Client Cert" ignored.example.com | \ ${REQ} -new -key clientdsa.key -out clientdsa.csr ### requests using special DN. REQDN=reqDN.doubleCN csr_fields "Double CN Dept" "nohost.example.com localhost" | ${REQ} -new -key ${srcdir}/server.key -out twocn.csr REQDN=reqDN.CNfirst echo localhost | ${REQ} -new -key ${srcdir}/server.key -out cnfirst.csr REQDN=reqDN.missingCN echo GB | ${REQ} -new -key ${srcdir}/server.key -out missingcn.csr REQDN=reqDN.justEmail echo blah@example.com | ${REQ} -new -key ${srcdir}/server.key -out justmail.csr # presume AVAs will come out in least->most specific order still... REQDN=reqDN.twoOU csr_fields "Second OU Dept First OU Dept" | ${REQ} -new -key ${srcdir}/server.key -out twoou.csr ### don't put ${REQ} invocations after here for f in server client clientdsa twocn caseless cnfirst \ t61subj bmpsubj utf8subj \ missingcn justmail twoou wildcard wildip wrongcn; do ${CA} -days 900 -in ${f}.csr -out ${f}.cert done ${CA} -startdate `asn1date "2 days ago"` -enddate `asn1date "yesterday"` -in expired.csr -out expired.cert ${CA} -startdate `asn1date "tomorrow"` -enddate `asn1date "2 days"` -in notyet.csr -out notyet.cert for n in 1 2 3 4 5 6 7 8 9; do ${CA} -extensions altExt${n} -days 900 \ -in altname${n}.csr -out altname${n}.cert done # Sign this CSR using the intermediary CA CADIR=./ca2 ${CA} -days 900 -in server.csr -out ca2server.cert # And create a file with the concatenation of both EE and intermediary # cert. cat ca2server.cert ca2/cert.pem > ca2server.pem # sign with expired CA CADIR=./ca1 ${CA} -days 3 -in server.csr -out ca1server.cert # sign with not yet valid CA CADIR=./ca3 ${CA} -days 3 -in server.csr -out ca3server.cert MKPKCS12="${OPENSSL} pkcs12 -export -passout stdin -in client.cert -inkey client.key" # generate a PKCS12 cert from the client cert: -passOUT because it's the # passphrase on the OUTPUT cert, confusing... echo foobar | ${MKPKCS12} -name "Just A Neon Client Cert" -out client.p12 # generate a PKCS#12 cert with no password and a friendly name echo | ${MKPKCS12} -name "An Unencrypted Neon Client Cert" -out unclient.p12 # PKCS#12 cert with DSA key echo | ${OPENSSL} pkcs12 -name "An Unencrypted Neon DSA Client Cert" \ -export -passout stdin \ -in clientdsa.cert -inkey clientdsa.key \ -out dsaclient.p12 # generate a PKCS#12 cert with no friendly name echo | ${MKPKCS12} -out noclient.p12 # generate a PKCS#12 cert with no private keys echo | ${MKPKCS12} -nokeys -out nkclient.p12 # generate a PKCS#12 cert without the cert echo | ${MKPKCS12} -nokeys -out ncclient.p12 # generate an encoded PKCS#12 cert with no private keys echo foobar | ${MKPKCS12} -nokeys -out enkclient.p12 # a PKCS#12 cert including a bundled CA cert echo foobar | ${MKPKCS12} -certfile ca/cert.pem -name "A Neon Client Cert With CA" -out clientca.p12 ### a file containing a complete chain cat ca/cert.pem server.cert > chain.pem ### NSS database initialization, for testing PKCS#11. CERTUTIL=@CERTUTIL@ PK12UTIL=@PK12UTIL@ if [ ${CERTUTIL} != "notfound" -a ${PK12UTIL} != "notfound" ]; then rm -rf nssdb nssdb-dsa mkdir nssdb nssdb-dsa echo foobar > nssdb.pw ${CERTUTIL} -d nssdb -N -f nssdb.pw ${PK12UTIL} -d nssdb -K foobar -W '' -i unclient.p12 ${CERTUTIL} -d nssdb-dsa -N -f nssdb.pw ${PK12UTIL} -d nssdb-dsa -K foobar -W '' -i dsaclient.p12 rm -f nssdb.pw fi davix-R_0_5_0/deps/libneon/test/notvalid.pem000066400000000000000000000022301257152637300211450ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDODCCAuKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBoTELMAkGA1UEBhMCR0Ix FzAVBgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlkZ2UxGjAY BgNVBAoTEU5lb24gSGFja2VycyBMdGQuMRUwEwYDVQQLEwxOZW9uIFFBIERlcHQx EjAQBgNVBAMTCWxvY2FsaG9zdDEeMBwGCSqGSIb3DQEJARYPbmVvbkB3ZWJkYXYu b3JnMB4XDTIzMTIyNzIwNDAyOVoXDTIzMTIyODIwNDAyOVowgaExCzAJBgNVBAYT AkdCMRcwFQYDVQQIEw5DYW1icmlkZ2VzaGlyZTESMBAGA1UEBxMJQ2FtYnJpZGdl MRowGAYDVQQKExFOZW9uIEhhY2tlcnMgTHRkLjEVMBMGA1UECxMMTmVvbiBRQSBE ZXB0MRIwEAYDVQQDEwlsb2NhbGhvc3QxHjAcBgkqhkiG9w0BCQEWD25lb25Ad2Vi ZGF2Lm9yZzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDzRU5sZ8+CWQPvPkqJw9Kl oEgT2FqzZR9RT/qbJuRBmRphiRr0g7JOh5Mr7LXaKShedFLhGidutyKKwIZJnRht AgMBAAGjggEBMIH+MB0GA1UdDgQWBBRFA3ktzHSuD9uB6mJOWoElmOtknzCBzgYD VR0jBIHGMIHDgBRFA3ktzHSuD9uB6mJOWoElmOtkn6GBp6SBpDCBoTELMAkGA1UE BhMCR0IxFzAVBgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlk Z2UxGjAYBgNVBAoTEU5lb24gSGFja2VycyBMdGQuMRUwEwYDVQQLEwxOZW9uIFFB IERlcHQxEjAQBgNVBAMTCWxvY2FsaG9zdDEeMBwGCSqGSIb3DQEJARYPbmVvbkB3 ZWJkYXYub3JnggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQA80TYV 2F4QLveuldmxGoIOq5hHGxCR6aVsdtm4PGY49R5/ObCAgdWw/JV/Tc448JAz5QvU ahr1x9kA4Vo5NZ4q -----END CERTIFICATE----- davix-R_0_5_0/deps/libneon/test/nulca.pem000066400000000000000000000112501257152637300204310ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: ce:4e:0c:d6:f7:2b:d6:6c Signature Algorithm: sha1WithRSAEncryption Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA Validity Not Before: Aug 4 06:49:34 2009 GMT Not After : Aug 2 06:49:34 2019 GMT Subject: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:ca:bc:b4:01:72:0a:f4:a3:ce:c0:04:8c:43:fd: 5d:27:4f:12:38:d3:11:ef:cc:1f:10:02:ef:e2:b8: 24:3c:dd:2f:bf:1f:d2:27:11:d9:51:59:d2:f7:a7: c0:3d:38:a4:ff:64:86:ef:dc:f5:95:ca:49:34:8f: 46:21:00:54:04:46:a0:d7:11:a1:48:a8:bd:68:27: f9:b2:72:c0:79:28:49:bb:55:b0:19:a0:6a:6f:70: 8e:8a:43:a8:a3:e7:d1:13:a0:af:38:4b:09:cb:29: ca:26:c6:0c:3c:4b:20:fd:2f:08:ca:90:c6:41:35: 31:ae:db:16:09:69:99:0c:fd:d1:ce:71:44:24:4f: 4a:d5:c2:e1:1b:7a:c0:e3:4f:ef:72:8c:1e:32:83: 5c:bc:2e:29:f1:3e:a6:7b:be:4b:10:d5:c9:5a:5a: 3b:c3:f7:c4:0a:44:f7:41:d9:e8:c7:8c:17:d8:a0: 86:5e:9c:5b:19:85:96:ca:68:db:d8:dc:3b:b2:26: 79:f8:b1:07:2d:c3:2c:fa:e5:51:8e:aa:da:15:5a: 56:fb:dc:f3:05:90:ac:05:d1:54:3b:6d:f5:14:fa: 9d:0e:85:da:e9:6f:5d:46:12:f3:02:0a:a2:fe:4b: 45:b6:4e:7e:41:34:cc:ab:cc:ca:b2:4a:7f:4d:66: 55:81 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A X509v3 Authority Key Identifier: keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A DirName:/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=CA/CN=NULL-friendly CA serial:CE:4E:0C:D6:F7:2B:D6:6C X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha1WithRSAEncryption 02:c9:aa:28:0b:d4:c6:34:2c:a9:b6:99:29:f9:b9:42:97:c5: c0:25:0d:1c:cc:35:65:a1:03:97:0d:88:7e:69:99:48:98:4b: 77:f6:09:1b:e6:fc:6e:52:ab:68:d1:8d:eb:2e:51:c5:7b:94: 7d:b5:b9:d2:1f:9a:85:67:04:51:21:97:ec:c1:1f:92:8b:74: c0:3d:69:17:c1:60:4a:b2:67:6f:47:51:ef:ca:38:d4:d2:c1: 4c:f8:8e:3c:ab:63:cd:84:67:1e:bf:5e:38:d0:89:f6:ee:a8: 2d:e6:51:72:c0:b3:ed:ca:5e:58:f7:a8:23:9c:64:dc:92:81: 56:e5:5e:2d:70:58:cc:f3:f1:3e:00:ff:41:9a:5f:01:28:22: da:55:39:4c:c2:50:e8:27:e5:89:55:c0:b6:b2:10:28:2d:9e: d6:27:b1:ec:d6:74:f8:a6:31:e9:f5:79:06:46:ab:a8:54:95: 8f:7e:33:45:5c:fa:32:a6:0b:2f:61:b6:0d:f9:42:66:9b:b8: 60:be:3d:1d:83:9d:0d:b7:04:13:4c:52:9c:e8:e1:a5:82:fd: 29:b0:2d:f4:f7:0a:30:a1:8d:01:cb:db:5d:dd:a4:b8:36:09: 84:56:a9:ea:54:80:3e:fa:18:be:13:89:c7:d4:38:1f:7f:25: ad:5b:22:23 -----BEGIN CERTIFICATE----- MIIERTCCAy2gAwIBAgIJAM5ODNb3K9ZsMA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNV BAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAV BgNVBAoTDk15IENvbXBhbnkgTHRkMQswCQYDVQQLEwJDQTEZMBcGA1UEAxMQTlVM TC1mcmllbmRseSBDQTAeFw0wOTA4MDQwNjQ5MzRaFw0xOTA4MDIwNjQ5MzRaMHQx CzAJBgNVBAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1 cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQswCQYDVQQLEwJDQTEZMBcGA1UE AxMQTlVMTC1mcmllbmRseSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMq8tAFyCvSjzsAEjEP9XSdPEjjTEe/MHxAC7+K4JDzdL78f0icR2VFZ0ven wD04pP9khu/c9ZXKSTSPRiEAVARGoNcRoUiovWgn+bJywHkoSbtVsBmgam9wjopD qKPn0ROgrzhLCcspyibGDDxLIP0vCMqQxkE1Ma7bFglpmQz90c5xRCRPStXC4Rt6 wONP73KMHjKDXLwuKfE+pnu+SxDVyVpaO8P3xApE90HZ6MeMF9ighl6cWxmFlspo 29jcO7ImefixBy3DLPrlUY6q2hVaVvvc8wWQrAXRVDtt9RT6nQ6F2ulvXUYS8wIK ov5LRbZOfkE0zKvMyrJKf01mVYECAwEAAaOB2TCB1jAdBgNVHQ4EFgQUCmk5X50w BBgILgIO5uqdsib24mowgaYGA1UdIwSBnjCBm4AUCmk5X50wBBgILgIO5uqdsib2 4mqheKR2MHQxCzAJBgNVBAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNV BAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQswCQYDVQQLEwJD QTEZMBcGA1UEAxMQTlVMTC1mcmllbmRseSBDQYIJAM5ODNb3K9ZsMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAALJqigL1MY0LKm2mSn5uUKXxcAlDRzM NWWhA5cNiH5pmUiYS3f2CRvm/G5Sq2jRjesuUcV7lH21udIfmoVnBFEhl+zBH5KL dMA9aRfBYEqyZ29HUe/KONTSwUz4jjyrY82EZx6/XjjQifbuqC3mUXLAs+3KXlj3 qCOcZNySgVblXi1wWMzz8T4A/0GaXwEoItpVOUzCUOgn5YlVwLayECgtntYnsezW dPimMen1eQZGq6hUlY9+M0Vc+jKmCy9htg35QmabuGC+PR2DnQ23BBNMUpzo4aWC /SmwLfT3CjChjQHL213dpLg2CYRWqepUgD76GL4TicfUOB9/Ja1bIiM= -----END CERTIFICATE----- davix-R_0_5_0/deps/libneon/test/nulcn.pem000066400000000000000000000104471257152637300204550ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA Validity Not Before: Aug 4 07:33:43 2009 GMT Not After : Aug 2 07:33:43 2019 GMT Subject: CN=www.bank.com\x00.badguy.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:cd:26:70:96:a9:a6:5d:3e:9c:ed:0f:08:15:5a: 7c:17:25:68:68:af:13:b9:ad:41:fa:12:54:e2:84: 72:7d:58:d1:e2:40:42:c1:59:ed:05:3d:aa:10:53: 70:00:88:3a:77:a0:c0:56:9e:ac:7d:21:2a:71:44: 51:08:bc:17:07:da:a8:a3:76:dc:51:bc:1b:8a:f6: 02:1a:55:bf:46:b4:44:6b:27:5e:be:e5:17:8b:56: b2:c6:82:36:11:83:a8:bf:f7:2f:0d:17:f6:cd:47: b5:6f:2b:a6:41:b6:8d:33:5f:ea:ea:8b:b1:1a:e2: 99:38:ff:59:5b:0a:a1:71:13:ca:37:3f:b9:b0:1e: 91:9a:c8:93:35:0c:4a:e0:9d:f4:d2:61:c7:4e:5b: 41:0a:7c:31:54:99:db:f5:65:ce:80:d3:c2:02:37: 64:fd:54:12:7b:ea:ac:85:59:5c:17:e1:2e:f6:d0: a8:f2:d0:2e:94:59:2f:c2:a6:5f:da:07:de:7b:2e: 14:07:ed:e4:27:24:37:9d:09:2e:b1:f9:5a:48:b9: 80:24:43:e6:cb:c7:6e:35:df:d5:69:34:ff:e6:d6: 9e:e8:76:66:6e:5f:59:01:3c:96:3b:ec:72:0b:3c: 1e:95:0f:ce:68:13:9c:22:dd:1b:b5:44:28:50:4a: 05:7f Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 33:15:24:BE:DA:66:3A:06:8B:D9:27:34:3A:AF:62:40:E4:95:66:5D X509v3 Authority Key Identifier: keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A Signature Algorithm: sha1WithRSAEncryption 32:65:23:1f:c8:d9:53:84:82:d0:0a:eb:14:51:24:03:bc:6c: 1b:2a:5a:fe:1b:f0:e8:69:0c:2b:19:86:cf:7f:32:76:d8:2b: d2:cf:8b:c4:d1:b6:5b:9c:60:a3:99:2e:92:72:06:ce:de:8b: d2:a2:d2:89:7c:13:a9:0b:4e:be:12:09:e5:d6:28:3a:ac:a7: 26:56:94:7f:13:ee:64:7d:de:94:60:75:c1:bc:55:97:d4:aa: 13:8e:02:d8:b0:b0:70:53:ae:18:53:ce:aa:b2:2c:85:3e:e3: f3:e1:26:f3:fa:5c:ee:f8:7b:0b:c6:39:b5:04:33:5e:ae:b8: 5e:0e:66:cc:a8:c0:6a:0d:ec:60:c1:c5:d9:39:ea:bd:1b:8f: 1c:7d:16:38:b1:e8:c8:37:01:aa:4b:99:df:e4:0f:10:be:61: ee:9a:cf:cd:27:05:46:00:60:d8:6a:74:08:32:3c:8b:90:01: 6a:07:33:0c:6c:90:db:ea:fb:6a:17:1a:76:bb:73:14:27:e1: a4:7e:d5:dd:30:b1:5d:f2:0e:aa:d4:b2:d5:4c:f6:4f:91:2a: 07:f4:37:c1:cf:48:19:c5:fe:7e:92:96:a8:df:50:6a:31:92: a3:b1:14:fe:41:cc:49:62:98:4d:ea:c5:ba:05:2d:49:c3:22: 72:ef:41:09 -----BEGIN CERTIFICATE----- MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEE5VTEwtZnJpZW5k bHkgQ0EwHhcNMDkwODA0MDczMzQzWhcNMTkwODAyMDczMzQzWjAjMSEwHwYDVQQD Exh3d3cuYmFuay5jb20ALmJhZGd1eS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDNJnCWqaZdPpztDwgVWnwXJWhorxO5rUH6ElTihHJ9WNHiQELB We0FPaoQU3AAiDp3oMBWnqx9ISpxRFEIvBcH2qijdtxRvBuK9gIaVb9GtERrJ16+ 5ReLVrLGgjYRg6i/9y8NF/bNR7VvK6ZBto0zX+rqi7Ea4pk4/1lbCqFxE8o3P7mw HpGayJM1DErgnfTSYcdOW0EKfDFUmdv1Zc6A08ICN2T9VBJ76qyFWVwX4S720Kjy 0C6UWS/Cpl/aB957LhQH7eQnJDedCS6x+VpIuYAkQ+bLx24139VpNP/m1p7odmZu X1kBPJY77HILPB6VD85oE5wi3Ru1RChQSgV/AgMBAAGjezB5MAkGA1UdEwQCMAAw LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G A1UdDgQWBBQzFSS+2mY6BovZJzQ6r2JA5JVmXTAfBgNVHSMEGDAWgBQKaTlfnTAE GAguAg7m6p2yJvbiajANBgkqhkiG9w0BAQUFAAOCAQEAMmUjH8jZU4SC0ArrFFEk A7xsGypa/hvw6GkMKxmGz38ydtgr0s+LxNG2W5xgo5kuknIGzt6L0qLSiXwTqQtO vhIJ5dYoOqynJlaUfxPuZH3elGB1wbxVl9SqE44C2LCwcFOuGFPOqrIshT7j8+Em 8/pc7vh7C8Y5tQQzXq64Xg5mzKjAag3sYMHF2TnqvRuPHH0WOLHoyDcBqkuZ3+QP EL5h7prPzScFRgBg2Gp0CDI8i5ABagczDGyQ2+r7ahcadrtzFCfhpH7V3TCxXfIO qtSy1Uz2T5EqB/Q3wc9IGcX+fpKWqN9QajGSo7EU/kHMSWKYTerFugUtScMicu9B CQ== -----END CERTIFICATE----- davix-R_0_5_0/deps/libneon/test/nulsan.pem000066400000000000000000000106211257152637300206300ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: sha1WithRSAEncryption Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA Validity Not Before: Aug 4 06:53:05 2009 GMT Not After : Aug 2 06:53:05 2019 GMT Subject: CN=www.badguy.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:cd:26:70:96:a9:a6:5d:3e:9c:ed:0f:08:15:5a: 7c:17:25:68:68:af:13:b9:ad:41:fa:12:54:e2:84: 72:7d:58:d1:e2:40:42:c1:59:ed:05:3d:aa:10:53: 70:00:88:3a:77:a0:c0:56:9e:ac:7d:21:2a:71:44: 51:08:bc:17:07:da:a8:a3:76:dc:51:bc:1b:8a:f6: 02:1a:55:bf:46:b4:44:6b:27:5e:be:e5:17:8b:56: b2:c6:82:36:11:83:a8:bf:f7:2f:0d:17:f6:cd:47: b5:6f:2b:a6:41:b6:8d:33:5f:ea:ea:8b:b1:1a:e2: 99:38:ff:59:5b:0a:a1:71:13:ca:37:3f:b9:b0:1e: 91:9a:c8:93:35:0c:4a:e0:9d:f4:d2:61:c7:4e:5b: 41:0a:7c:31:54:99:db:f5:65:ce:80:d3:c2:02:37: 64:fd:54:12:7b:ea:ac:85:59:5c:17:e1:2e:f6:d0: a8:f2:d0:2e:94:59:2f:c2:a6:5f:da:07:de:7b:2e: 14:07:ed:e4:27:24:37:9d:09:2e:b1:f9:5a:48:b9: 80:24:43:e6:cb:c7:6e:35:df:d5:69:34:ff:e6:d6: 9e:e8:76:66:6e:5f:59:01:3c:96:3b:ec:72:0b:3c: 1e:95:0f:ce:68:13:9c:22:dd:1b:b5:44:28:50:4a: 05:7f Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 33:15:24:BE:DA:66:3A:06:8B:D9:27:34:3A:AF:62:40:E4:95:66:5D X509v3 Authority Key Identifier: keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A X509v3 Subject Alternative Name: DNS:www.bank.com Signature Algorithm: sha1WithRSAEncryption 27:6e:7d:b3:a9:86:52:57:6a:a0:c6:30:6c:1e:94:09:a7:6f: ad:fe:11:9f:be:32:8d:01:7b:8b:94:66:d7:7c:b6:b1:90:fc: e4:f5:b6:32:bc:6c:71:23:b1:18:88:d6:47:bc:da:07:c7:5e: 46:71:3a:e6:40:6e:c1:7f:1d:56:96:70:65:d8:51:a9:dc:9e: a5:06:00:98:e7:1e:10:bc:82:ba:00:e5:4e:a2:0f:3e:ec:8a: dd:6f:c6:c9:c1:ec:ed:6d:7c:31:3e:66:87:47:a1:8b:15:3c: 21:7e:ec:21:78:3d:21:70:72:ba:70:c3:64:f8:1d:4f:d9:d0: 27:3c:3e:7e:a2:59:ae:be:9a:d3:00:44:a7:72:3a:e3:3f:c8: 9b:c5:8f:b1:94:fe:00:0f:6e:b8:14:88:f1:03:50:91:51:af: f0:1e:f7:b8:5a:a4:57:35:2d:f1:ad:c8:ae:dd:29:61:14:7d: ea:d1:34:80:5c:1b:fd:eb:43:dc:21:6d:c6:44:f9:3b:54:76: c4:91:5b:ac:a4:8e:72:e7:d8:24:ff:a7:5a:c0:ef:27:c3:d7: e4:f9:7f:55:8d:0d:30:ec:a2:d9:6d:c8:76:f4:be:94:3d:12: 32:4a:91:4f:db:c3:e7:76:07:5a:12:97:18:b7:15:00:98:59: 21:89:3e:35 -----BEGIN CERTIFICATE----- MIIDrTCCApWgAwIBAgIBADANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJHQjES MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N eSBDb21wYW55IEx0ZDELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEE5VTEwtZnJpZW5k bHkgQ0EwHhcNMDkwODA0MDY1MzA1WhcNMTkwODAyMDY1MzA1WjAZMRcwFQYDVQQD Ew53d3cuYmFkZ3V5LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AM0mcJappl0+nO0PCBVafBclaGivE7mtQfoSVOKEcn1Y0eJAQsFZ7QU9qhBTcACI OnegwFaerH0hKnFEUQi8FwfaqKN23FG8G4r2AhpVv0a0RGsnXr7lF4tWssaCNhGD qL/3Lw0X9s1HtW8rpkG2jTNf6uqLsRrimTj/WVsKoXETyjc/ubAekZrIkzUMSuCd 9NJhx05bQQp8MVSZ2/VlzoDTwgI3ZP1UEnvqrIVZXBfhLvbQqPLQLpRZL8KmX9oH 3nsuFAft5CckN50JLrH5Wki5gCRD5svHbjXf1Wk0/+bWnuh2Zm5fWQE8ljvscgs8 HpUPzmgTnCLdG7VEKFBKBX8CAwEAAaOBpDCBoTAJBgNVHRMEAjAAMCwGCWCGSAGG +EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU MxUkvtpmOgaL2Sc0Oq9iQOSVZl0wHwYDVR0jBBgwFoAUCmk5X50wBBgILgIO5uqd sib24mowJgYDVR0RBB8wHYIbd3d3LmJhbmsuY29tAHd3dy5iYWRndXkuY29tMA0G CSqGSIb3DQEBBQUAA4IBAQAnbn2zqYZSV2qgxjBsHpQJp2+t/hGfvjKNAXuLlGbX fLaxkPzk9bYyvGxxI7EYiNZHvNoHx15GcTrmQG7Bfx1WlnBl2FGp3J6lBgCY5x4Q vIK6AOVOog8+7Irdb8bJweztbXwxPmaHR6GLFTwhfuwheD0hcHK6cMNk+B1P2dAn PD5+olmuvprTAESncjrjP8ibxY+xlP4AD264FIjxA1CRUa/wHve4WqRXNS3xrciu 3SlhFH3q0TSAXBv960PcIW3GRPk7VHbEkVuspI5y59gk/6dawO8nw9fk+X9VjQ0w 7KLZbch29L6UPRIySpFP28PndgdaEpcYtxUAmFkhiT41 -----END CERTIFICATE----- davix-R_0_5_0/deps/libneon/test/nulsrv.key000066400000000000000000000032131257152637300206670ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAzSZwlqmmXT6c7Q8IFVp8FyVoaK8Tua1B+hJU4oRyfVjR4kBC wVntBT2qEFNwAIg6d6DAVp6sfSEqcURRCLwXB9qoo3bcUbwbivYCGlW/RrREayde vuUXi1ayxoI2EYOov/cvDRf2zUe1byumQbaNM1/q6ouxGuKZOP9ZWwqhcRPKNz+5 sB6RmsiTNQxK4J300mHHTltBCnwxVJnb9WXOgNPCAjdk/VQSe+qshVlcF+Eu9tCo 8tAulFkvwqZf2gfeey4UB+3kJyQ3nQkusflaSLmAJEPmy8duNd/VaTT/5tae6HZm bl9ZATyWO+xyCzwelQ/OaBOcIt0btUQoUEoFfwIDAQABAoIBAF55tl3b8O5+GDyf sIRM8FqkconLHtViccDdUlQi1KrfDYEZQOTUKfBA7qGoGytTkUFoOUtqtVrGvEn/ QSY5oI2QaBsncNz/ONvs4RkJphXEjMGgFuTokcgsfBYo/wdfz4XgKr3n7FOrE2YH /v/CNxKSuJedD0mnUxLJnXfs1F5DAE+nE88T2LsWLqo8Jxr/6wFnazaAYmtkQd3/ BNBn9a7K79G81e7FkRSIc+7De7iju6UMy010qY6UNyFw9hSWQgjxzxwiyFvRuu4C w4xRJo2z0vEL6TSnNZEpTVVAbBd8XYSjh/627uXBah8W50X4BWLOd1umgU1hJDXe cXIWVZkCgYEA9QXcOdOPzuQ6wQYEi7qvTKSRdUJ+D3BCbqSHyWEe4RotWqs9WV1F FFpaRO/aiIdqpVZE8YJlcAcKtIXBS/byKUfOFzHX2QvROmPlcavXrVtFnNsBQpIn hyYjs/z/vbFDgugLBKVsgEaZzlJeygbI61r2NjVnst7NzP9L8ZxFgDsCgYEA1ldI nZcXekaqpUAMCSdZPDcfocVUb8UjvRZf90EruWymbrJQxzym5HaX20MFFh1BKC+a JEexxhlbfth/zgX6Pux7fqxSJM11DBG1aik7t4GMRu1bfflpQjdQUXGn2YPI5Quz R6QPcXhLVLY8b8PJu2jSKjV0cDN02dFwEFv9340CgYBRpUhDBJow6KAjXav6G5T6 RwQpPKTg5Ble4PhWREST4bMnOVRSCOBR7eGSgxIg2G7S9TI3/6lpcQ9CJCfK9liv JLwpwnQYYPWxLURxYj+WBonlwJxk4GrHgA/5k95sCTtjzYqOW8kR3XS26X+odiZR NphAa/9H/TI6kv9tXRNTrQKBgGoREVciwLR6qdFSq2IQPcFlidq02r7gsHnOy7iA YJHGqWmYBg9B/ViLM0SGmsrBuU+Yls+jRt7AB53ypvQd0yM2RTp/LbsWjPhm/v5E 309E5VTn+mGRfbwNwUo8UxJ5e32U16f5EMdW/vgxoiCwo3CBQ5ctkqw/WnC7ipgd 3bi1AoGAbJSdtaFdF0kSikqvcPEJMFBR24dT7W+JIXeuFHYbRkQGSVZLGxuAkbL5 1mY+qclcvzfijH0wNFRP1Z3M5eFERALwI25YOrZGtI1ncIeKV+yFwkYC54XfZUvr hQO0wVIbTaE3N9fDIs0rHbSc1GJUhVr+2IsTW/ybHgdfDZMuXOI= -----END RSA PRIVATE KEY----- davix-R_0_5_0/deps/libneon/test/oldacl.c000066400000000000000000000041151257152637300202300ustar00rootroot00000000000000/* Dummy ACL tests Copyright (C) 2001-2003, Joe Orton 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 "ne_acl.h" #include "tests.h" #include "child.h" #include "utils.h" /**** DUMMY TESTS: just makes sure the stuff doesn't dump core. */ static int test_acl(const char *uri, ne_acl_entry *es, int nume) { ne_session *sess; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 OK\r\n" "Connection: close\r\n\r\n")); ON(ne_acl_set(sess, uri, es, nume)); CALL(await_server()); ne_session_destroy(sess); return OK; } static int grant_all(void) { ne_acl_entry e = {0}; e.apply = ne_acl_all; e.type = ne_acl_grant; CALL(test_acl("/foo", &e, 1)); return OK; } static int deny_all(void) { ne_acl_entry e = {0}; e.apply = ne_acl_all; e.type = ne_acl_deny; CALL(test_acl("/foo", &e, 1)); return OK; } static int deny_one(void) { ne_acl_entry e = {0}; e.apply = ne_acl_href; e.type = ne_acl_deny; e.principal = "http://webdav.org/users/joe"; CALL(test_acl("/foo", &e, 1)); return OK; } static int deny_byprop(void) { ne_acl_entry e = {0}; e.apply = ne_acl_property; e.type = ne_acl_deny; e.principal = "owner"; CALL(test_acl("/foo", &e, 1)); return OK; } ne_test tests[] = { T(grant_all), T(deny_all), T(deny_one), T(deny_byprop), T(NULL) }; davix-R_0_5_0/deps/libneon/test/openssl.conf000066400000000000000000000055371257152637300211710ustar00rootroot00000000000000[ca] default_ca = neonca [neonca] dir = ${ENV::CADIR} database = $dir/index.txt new_certs_dir = $dir certificate = $dir/cert.pem serial = $dir/serial private_key = $dir/key.pem policy = policy_any default_md = sha1 x509_extensions = issuedExt unique_subject = no # same as neonca1 just +basicConstraints and without certificate to # allow creation of the initial self signed certificate [neoncainit] dir = ${ENV::CADIR} database = $dir/index.txt new_certs_dir = $dir serial = $dir/serial private_key = $dir/key.pem policy = policy_any default_md = sha1 x509_extensions = issuedExt unique_subject = no basicConstraints = CA:TRUE [policy_any] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = optional emailAddress = optional [req] distinguished_name = $ENV::REQDN x509_extensions = caExt string_mask = $ENV::STRMASK [caExt] basicConstraints = CA:true [issuedExt] basicConstraints = CA:false # subjectAltName extension sections [altExt1] subjectAltName = DNS:localhost # 2+3: AltNames with multiple entries to test the matching logic [altExt2] subjectAltName = DNS:nohost.example.com, DNS:localhost [altExt3] subjectAltName = DNS:localhost, DNS:nohost.example.com # an AltName with no DNS entries; should use commonName instead for # identity check [altExt4] subjectAltName = email:neon@webdav.org # an AltName with IP address [altExt5] subjectAltName = IP:127.0.0.1 # an AltName with a bad IP address [altExt6] subjectAltName = IP:1.2.3.4 # an AltName with a good URI [altExt7] subjectAltName = URI:https://localhost:7777/ # an AltName with a bad URI [altExt8] subjectAltName = URI:http://nohost.example.com/ # AltName with wildcard [altExt9] subjectAltName = DNS:*.example.com [reqDN] countryName = Country Name stateOrProvinceName = State or Province Name localityName = Locality Name organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name (eg, your name or your server\'s hostname) emailAddress = Email Address # a DN which gives two commonName attributes. [reqDN.doubleCN] countryName = Country Name stateOrProvinceName = State or Province Name localityName = Locality Name organizationName = Organization Name organizationalUnitName = Organizational Unit Name 0.commonName = Common Name 1.commonName = Common Name emailAddress = Email Address [reqDN.twoOU] countryName = Country Name stateOrProvinceName = State or Province Name localityName = Locality Name organizationName = Organization Name 0.organizationalUnitName = Organizational Unit Name 1.organizationalUnitName = Organizational Unit Name commonName = Common Name (eg, your name or your server\'s hostname) emailAddress = Email Address [reqDN.CNfirst] commonName = Common Name [reqDN.missingCN] countryName = CountryName [reqDN.justEmail] emailAddress = CountryName davix-R_0_5_0/deps/libneon/test/props.c000066400000000000000000000536441257152637300201500ustar00rootroot00000000000000/* Tests for property handling Copyright (C) 2002-2008, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_props.h" #include "tests.h" #include "child.h" #include "utils.h" static const ne_propname p_alpha = {"DAV:", "alpha"}, p_beta = {"http://webdav.org/random/namespace", "beta"}, p_delta = {NULL, "delta"}; /* Tests little except that ne_proppatch() doesn't segfault. */ static int patch_simple(void) { ne_session *sess; ne_proppatch_operation ops[] = { { &p_alpha, ne_propset, "fish" }, { &p_beta, ne_propremove, NULL }, { NULL, ne_propset, NULL } }; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 Goferit\r\n" "Connection: close\r\n\r\n")); ONREQ(ne_proppatch(sess, "/fish", ops)); ne_session_destroy(sess); return await_server(); } #define RESP207 "HTTP/1.0 207 Stuff\r\n" "Server: foo\r\n\r\n" static void dummy_results(void *ud, const ne_uri *uri, const ne_prop_result_set *rset) { NE_DEBUG(NE_DBG_HTTP, "dummy_results.\n"); } /* Regression tests for propfind bodies which caused segfaults. */ static int regress(void) { static const char *bodies[] = { RESP207 "\n" "" "" "" "", /* segfaults with neon <= 0.23.5 */ RESP207 "" "/foo/" "" "HTTP/1.1 404 Not Found" "", /* format string handling with neon <= 0.24.4 */ RESP207 "" "/foo/" "" "%s%s%s%s" "", NULL, }; ne_session *sess; int n; for (n = 0; bodies[n] != NULL; n++) { CALL(make_session(&sess, single_serve_string, (void *)bodies[n])); ne_simple_propfind(sess, "/", 0, NULL, dummy_results, NULL); ne_session_destroy(sess); CALL(await_server()); } return OK; } static int patch_regress(void) { static const char *bodies[] = { /* format string handling bugs with neon <= 0.24.4 */ RESP207 "" "/foo/" "HTTP/1.1 500 Bad Voodoo" "%s%s%s%s" "", RESP207 "" "/foo/" "HTTP/1.1 %s%s%s%s", NULL }; ne_session *sess; int n; static const ne_propname pn = { "DAV:", "foobar" }; ne_proppatch_operation pops[] = { { &pn, ne_propset, "fish" }, { NULL, ne_propset, NULL } }; for (n = 0; bodies[n] != NULL; n++) { CALL(make_session(&sess, single_serve_string, (void *)bodies[n])); ne_proppatch(sess, "/", pops); ne_session_destroy(sess); CALL(await_server()); } return OK; } static int pstat_count; /* tos_*: set of 207 callbacks which serialize the data back into a * text stream, which can be easily checked for correctness. */ static void *tos_startresp(void *buf, const ne_uri *uri) { ne_buffer_concat(buf, "start-resp[", uri->path, "];", NULL); pstat_count = 0; return ne_strdup(uri->path); } static void tos_status_descr(ne_buffer *buf, const ne_status *status, const char *description) { if (status) { char s[50]; ne_snprintf(s, sizeof s, "-status={%d %s}", status->code, status->reason_phrase); ne_buffer_zappend(buf, s); } if (description) ne_buffer_concat(buf, "-descr={", description, "}", NULL); } static void tos_endresp(void *buf, void *response, const ne_status *status, const char *description) { char *href = response; ne_buffer_concat(buf, "end-resp[", href, "]", NULL); ne_free(href); tos_status_descr(buf, status, description); ne_buffer_zappend(buf, ";"); } static void *tos_startpstat(void *buf, void *resphref) { char num[20], *href; sprintf(num, "-%d", ++pstat_count); href = ne_concat(resphref, num, NULL); ne_buffer_concat(buf, "start-pstat[", href, "];", NULL); return href; } static void tos_endpstat(void *buf, void *href, const ne_status *status, const char *description) { ne_buffer_concat(buf, "end-pstat[", href, "]", NULL); tos_status_descr(buf, status, description); ne_buffer_zappend(buf, ";"); ne_free(href); } struct propctx { ne_207_parser *p207; ne_buffer *buf; }; #define STATE_myprop (NE_PROPS_STATE_TOP) static int tos_startprop(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { if (parent == NE_207_STATE_PROP && strcmp(nspace, "DAV:") == 0 && (strcmp(name, "propone") == 0 || strcmp(name, "proptwo") == 0)) { /* Handle this! */ struct propctx *ctx = userdata; char *resphref = ne_207_get_current_response(ctx->p207); char *pstathref = ne_207_get_current_propstat(ctx->p207); ne_buffer_concat(ctx->buf, "start-prop[", resphref, ",", pstathref, ",", name, "];", NULL); return STATE_myprop; } else { return NE_XML_DECLINE; } } static int tos_cdata(void *userdata, int state, const char *cdata, size_t len) { struct propctx *ctx = userdata; ne_buffer_zappend(ctx->buf, "cdata-prop["); ne_buffer_append(ctx->buf, cdata, len); ne_buffer_zappend(ctx->buf, "];"); return 0; } static int tos_endprop(void *userdata, int state, const char *nspace, const char *name) { struct propctx *ctx = userdata; ne_buffer_concat(ctx->buf, "end-prop[", name, "];", NULL); return 0; } static int run_207_response(char *resp, const char *expected) { ne_buffer *buf = ne_buffer_create(); ne_session *sess = ne_session_create("http", "localhost", 7777); ne_xml_parser *p = ne_xml_create(); ne_207_parser *p207; ne_request *req = ne_request_create(sess, "PROPFIND", "/foo"); ne_uri base = {0}; struct propctx ctx; ne_fill_server_uri(sess, &base); base.path = ne_strdup("/foo"); p207 = ne_207_create(p, &base, buf); ne_uri_free(&base); ne_add_response_body_reader(req, ne_accept_207, ne_xml_parse_v, p); ne_207_set_response_handlers(p207, tos_startresp, tos_endresp); ne_207_set_propstat_handlers(p207, tos_startpstat, tos_endpstat); ctx.buf = buf; ctx.p207 = p207; ne_xml_push_handler(p, tos_startprop, tos_cdata, tos_endprop, &ctx); CALL(spawn_server(7777, single_serve_string, resp)); ONREQ(ne_request_dispatch(req)); CALL(await_server()); ONV(ne_xml_failed(p), ("parse error in response body: %s", ne_xml_get_error(p))); ONV(strcmp(buf->data, expected), ("comparison failed.\n" "expected string: `%s'\n" "got string: `%s'", expected, buf->data)); ne_buffer_destroy(buf); ne_207_destroy(p207); ne_xml_destroy(p); ne_request_destroy(req); ne_session_destroy(sess); return OK; } /* Macros for easily writing a 207 response body; all expand to * a string literal. */ #define MULTI_207(x) "HTTP/1.0 207 Foo\r\nConnection: close\r\n\r\n" \ "\r\n" \ "" x "" #define RESP_207(href, x) "" href "" x \ "" #define PSTAT_207(x) "" x "" #define STAT_207(s) "HTTP/1.1 " s "" #define DESCR_207(d) "" d "" #define DESCR_REM "The end of the world, as we know it" #define PROPS_207(x) "" x "" #define APROP_207(n, c) "" c "" /* Tests for the 207 interface: send a 207 response body, compare the * re-serialized string returned with that expected. */ static int two_oh_seven(void) { static char *ts[][2] = { { MULTI_207(RESP_207("/foo", "")), "start-resp[/foo];end-resp[/foo];" }, /* test for response status handling */ { MULTI_207(RESP_207("/bar", STAT_207("200 OK"))), "start-resp[/bar];end-resp[/bar]-status={200 OK};" }, /* test that empty description == NULL description argument */ { MULTI_207(RESP_207("/bar", STAT_207("200 OK") DESCR_207(""))), "start-resp[/bar];end-resp[/bar]-status={200 OK};" }, /* test multiple responses */ { MULTI_207(RESP_207("/hello/world", STAT_207("200 OK")) RESP_207("/foo/bar", STAT_207("999 French Fries"))), "start-resp[/hello/world];end-resp[/hello/world]-status={200 OK};" "start-resp[/foo/bar];end-resp[/foo/bar]" "-status={999 French Fries};" }, /* test multiple propstats in mulitple responses */ { MULTI_207(RESP_207("/al/pha", PSTAT_207(STAT_207("321 Une")) PSTAT_207(STAT_207("432 Deux")) PSTAT_207(STAT_207("543 Trois"))) RESP_207("/be/ta", PSTAT_207(STAT_207("787 Quatre")) PSTAT_207(STAT_207("878 Cinq")))), "start-resp[/al/pha];" "start-pstat[/al/pha-1];end-pstat[/al/pha-1]-status={321 Une};" "start-pstat[/al/pha-2];end-pstat[/al/pha-2]-status={432 Deux};" "start-pstat[/al/pha-3];end-pstat[/al/pha-3]-status={543 Trois};" "end-resp[/al/pha];" "start-resp[/be/ta];" "start-pstat[/be/ta-1];end-pstat[/be/ta-1]-status={787 Quatre};" "start-pstat[/be/ta-2];end-pstat[/be/ta-2]-status={878 Cinq};" "end-resp[/be/ta];" }, /* test that incomplete responses are completely ignored. */ { MULTI_207("" RESP_207("/", STAT_207("123 Hoorah")) "" "hello" "" RESP_207("/bar", STAT_207("200 OK"))), "start-resp[/];end-resp[/]-status={123 Hoorah};" "start-resp[/bar];end-resp[/bar]-status={200 OK};" }, /* tests for propstat status */ { MULTI_207(RESP_207("/pstat", PSTAT_207("" STAT_207("666 Doomed")))), "start-resp[/pstat];start-pstat[/pstat-1];" "end-pstat[/pstat-1]-status={666 Doomed};end-resp[/pstat];" }, { MULTI_207(RESP_207("/pstat", PSTAT_207(""))), "start-resp[/pstat];start-pstat[/pstat-1];" "end-pstat[/pstat-1];end-resp[/pstat];" }, /* tests for responsedescription handling */ { MULTI_207(RESP_207("/bar", STAT_207("200 OK") DESCR_207(DESCR_REM))), "start-resp[/bar];end-resp[/bar]-status={200 OK}" "-descr={" DESCR_REM "};" }, { MULTI_207(RESP_207("/bar", PSTAT_207(STAT_207("456 Too Hungry") DESCR_207("Not enough food available")) STAT_207("200 OK") DESCR_207("Not " DESCR_REM))), "start-resp[/bar];" "start-pstat[/bar-1];end-pstat[/bar-1]-status={456 Too Hungry}" "-descr={Not enough food available};" "end-resp[/bar]-status={200 OK}-descr={Not " DESCR_REM "};" }, /* intermingle some random elements and cdata to make sure * they are ignored. */ { MULTI_207("blargl" RESP_207("/bar", "" PSTAT_207("blergl") STAT_207("200 OK") "foop" DESCR_207(DESCR_REM) "carroon") "carapi"), "start-resp[/bar];start-pstat[/bar-1];end-pstat[/bar-1];" "end-resp[/bar]-status={200 OK}-descr={" DESCR_REM "};" }, /* test for properties within a 207. */ { MULTI_207(RESP_207("/alpha", PSTAT_207(PROPS_207( APROP_207("propone", "hello") APROP_207("proptwo", "foobar")) STAT_207("200 OK")))), "start-resp[/alpha];start-pstat[/alpha-1];" "start-prop[/alpha,/alpha-1,propone];cdata-prop[hello];" "end-prop[propone];" "start-prop[/alpha,/alpha-1,proptwo];cdata-prop[foobar];" "end-prop[proptwo];" "end-pstat[/alpha-1]-status={200 OK};end-resp[/alpha];" } }; size_t n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) CALL(run_207_response(ts[n][0], ts[n][1])); return OK; } /* Serialize propfind result callbacks into a string */ static int simple_iterator(void *vbuf, const ne_propname *name, const char *value, const ne_status *st) { char code[20]; ne_buffer *buf = vbuf; ne_buffer_concat(buf, "prop:[{", name->nspace, ",", name->name, "}=", NULL); if (value) ne_buffer_concat(buf, "'", value, "'", NULL); else ne_buffer_zappend(buf, "#novalue#"); sprintf(code, ":{%d ", st->code); if (st->reason_phrase) ne_buffer_concat(buf, code, st->reason_phrase, "}];", NULL); else ne_buffer_concat(buf, code, "#noreason#}];", NULL); return 0; } static void simple_results(void *buf, const ne_uri *uri, const ne_prop_result_set *rset) { ne_buffer_concat(buf, "results(", uri->path, ",", NULL); ne_propset_iterate(rset, simple_iterator, buf); ne_buffer_czappend(buf, ")//"); } /* Test function to compare two long strings and print a digestible * failure message. */ static int diffcmp(const char *expected, const char *actual) { size_t n; if (!strcmp(expected, actual)) return OK; NE_DEBUG(NE_DBG_HTTP, "diffcmp: Expect: [%s]\n" "diffcmp: Actual: [%s]\n", expected, actual); for (n = 0; expected[n] && actual[n]; n++) { if (expected[n] != actual[n]) { t_context("difference at byte %" NE_FMT_SIZE_T ": " "`%.10s...' not `%.10s...'", n, actual+n, expected+n); break; } } return FAIL; } /* PROPFIND creator callback. */ static void *pf_creator(void *userdata, const ne_uri *uri) { ne_buffer *buf = userdata; NE_DEBUG(NE_DBG_HTTP, "pf: Creator at %s\n", uri->path); ne_buffer_concat(buf, "creator[", uri->path, "]//", NULL); return ne_strdup(uri->path); } /* PROPFIND destructor callback. */ static void pf_destructor(void *userdata, void *private) { ne_buffer *buf = userdata; char *cookie = private; NE_DEBUG(NE_DBG_HTTP, "pf: Destructor at %s\n", cookie); ne_buffer_concat(buf, "destructor[", cookie, "]//", NULL); ne_free(cookie); } /* PROPFIND test type. */ enum pftype { PF_SIMPLE, /* using ne_simple_propfind */ PF_NAMED, /* using ne_propfind_named */ PF_ALLPROP /* using ne_propfind_allprop */ }; static int run_propfind(const ne_propname *props, char *resp, int depth, const char *expected, enum pftype type) { ne_session *sess; ne_buffer *buf = ne_buffer_create(); CALL(make_session(&sess, single_serve_string, resp)); if (type == PF_SIMPLE) { ONREQ(ne_simple_propfind(sess, "/propfind", depth, props, simple_results, buf)); } else { ne_propfind_handler *hdl; hdl = ne_propfind_create(sess, "/propfind", depth); ne_propfind_set_private(hdl, pf_creator, pf_destructor, buf); if (type == PF_NAMED) { ONREQ(ne_propfind_named(hdl, props, simple_results, buf)); } else { ONREQ(ne_propfind_allprop(hdl, simple_results, buf)); } ne_propfind_destroy(hdl); } ne_session_destroy(sess); CALL(await_server()); CALL(diffcmp(expected, buf->data)); ne_buffer_destroy(buf); return OK; } /* a PROPFIND response body for the {DAV:}fishbone property, using * given property value and status. */ #define FISHBONE_RESP(value, status) MULTI_207(RESP_207("/foop", \ PSTAT_207(PROPS_207(APROP_207("fishbone", value)) \ STAT_207(status)))) static int propfind(void) { static const struct { char *resp; const char *expected; int depth; enum pftype type; } ts[] = { /* simple single property. */ { FISHBONE_RESP("hello, world", "212 Well OK"), "results(/foop,prop:[{DAV:,fishbone}='hello, world':{212 Well OK}];)//", 0, PF_SIMPLE }, /* property with some nested elements. */ { FISHBONE_RESP("this is a property fish value", "299 Just About OK"), "results(/foop,prop:[{DAV:,fishbone}=" "'this is a property " "fish value':" "{299 Just About OK}];)//", 0, PF_SIMPLE }, /* failed to fetch a property. */ { FISHBONE_RESP("property value is ignored", "404 Il n'ya pas de property"), "results(/foop,prop:[{DAV:,fishbone}=#novalue#:" "{404 Il n'ya pas de property}];)//", 0, PF_SIMPLE }, #if 0 /* propstat missing status should be ignored; if a response contains no * valid propstats, it should also be ignored. */ { MULTI_207(RESP_207("/alpha", PSTAT_207(APROP_207("fishbone", "unseen"))) RESP_207("/beta", PSTAT_207(APROP_207("fishbone", "hello, world") STAT_207("200 OK")))), "results(/beta,prop:[{DAV:,fishbone}='hello, world':{200 OK}];)//", 0, PF_SIMPLE }, #endif /* props on several resources */ { MULTI_207(RESP_207("/alpha", PSTAT_207(PROPS_207(APROP_207("fishbone", "strike one")) STAT_207("234 First is OK"))) RESP_207("/beta", PSTAT_207(PROPS_207(APROP_207("fishbone", "strike two")) STAT_207("256 Second is OK")))), "results(/alpha,prop:[{DAV:,fishbone}='strike one':{234 First is OK}];)//" "results(/beta,prop:[{DAV:,fishbone}='strike two':{256 Second is OK}];)//", 0, PF_SIMPLE}, /* whitespace handling. */ { MULTI_207(RESP_207("\r\nhttp://localhost:7777/alpha ", PSTAT_207(PROPS_207(APROP_207("alpha", "beta")) "\r\nHTTP/1.1 200 OK "))), "results(/alpha,prop:[{DAV:,alpha}='beta':{200 OK}];)//", 0, PF_SIMPLE}, /* attribute handling. */ { MULTI_207(RESP_207("\r\nhttp://localhost:7777/alpha ", PSTAT_207(PROPS_207("" "beta") "\r\nHTTP/1.1 200 OK "))), "results(/alpha,prop:[{DAV:,alpha}='beta':{200 OK}];)//", 0, PF_SIMPLE}, /* "complex" propfinds. */ { FISHBONE_RESP("hello, world", "212 Well OK"), "creator[/foop]//" "results(/foop,prop:[{DAV:,fishbone}='hello, world':{212 Well OK}];)//" "destructor[/foop]//", 0, PF_NAMED } }; const ne_propname pset1[] = { { "DAV:", "fishbone", }, { NULL, NULL } }; size_t n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) { const ne_propname *pset = pset1; CALL(run_propfind(pset, ts[n].resp, ts[n].depth, ts[n].expected, ts[n].type)); } return OK; } static int unbounded_response(const char *header, const char *repeats) { ne_session *sess; struct infinite i = { header, repeats}; int dbg; CALL(make_session(&sess, serve_infinite, &i)); dbg = ne_debug_mask; ONN("unbounded PROPFIND response did not fail", ne_simple_propfind(sess, "/", 0, NULL, dummy_results, NULL) != NE_ERROR); CALL(reap_server()); ne_session_destroy(sess); return OK; } static int unbounded_propstats(void) { return unbounded_response( RESP207 "\n" "" "/", ""); } static int unbounded_props(void) { return unbounded_response( RESP207 "\n" "" "/", "hello, world"); } ne_test tests[] = { T(two_oh_seven), T(patch_simple), T(propfind), T(regress), T(patch_regress), T(unbounded_props), T(unbounded_propstats), T(NULL) }; davix-R_0_5_0/deps/libneon/test/redirect.c000066400000000000000000000113551257152637300205770ustar00rootroot00000000000000/* Tests for 3xx redirect interface (ne_redirect.h) Copyright (C) 2002-2003, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_redirect.h" #include "tests.h" #include "child.h" #include "utils.h" struct redir_args { int code; const char *dest; const char *path; }; static int serve_redir(ne_socket *sock, void *ud) { struct redir_args *args = ud; char buf[BUFSIZ]; CALL(discard_request(sock)); ne_snprintf(buf, BUFSIZ, "HTTP/1.0 %d Get Ye Away\r\n" "Content-Length: 0\r\n" "Location: %s\r\n\n", args->code, args->dest); SEND_STRING(sock, buf); return OK; } /* Run a request to 'path' and retrieve the redirect destination to * *redir. */ static int process_redir(ne_session *sess, const char *path, const ne_uri **redir) { ONN("did not get NE_REDIRECT", any_request(sess, path) != NE_REDIRECT); *redir = ne_redirect_location(sess); return OK; } static int check_redir(struct redir_args *args, const char *expect) { ne_session *sess; const ne_uri *loc; char *unp; CALL(make_session(&sess, serve_redir, args)); ne_redirect_register(sess); CALL(process_redir(sess, args->path, &loc)); ONN("redirect location was NULL", loc == NULL); unp = ne_uri_unparse(loc); ONV(strcmp(unp, expect), ("redirected to `%s' not `%s'", unp, expect)); ne_free(unp); ne_session_destroy(sess); CALL(await_server()); return OK; } #define DEST "http://foo.com/blah/blah/bar" #define PATH "/redir/me" static int simple(void) { struct redir_args args[] = { {301, DEST, PATH}, {302, DEST, PATH}, {303, DEST, PATH}, {307, DEST, PATH}, {0, NULL, NULL} }; int n; for (n = 0; args[n].code; n++) CALL(check_redir(&args[n], DEST)); return OK; } /* check that a non-absoluteURI is qualified properly */ static int non_absolute(void) { struct redir_args args = {302, "/foo/bar/blah", PATH}; return check_redir(&args, "http://localhost:7777/foo/bar/blah"); } static int relative_1(void) { struct redir_args args = {302, "norman", "/foo/bar"}; return check_redir(&args, "http://localhost:7777/foo/norman"); } static int relative_2(void) { struct redir_args args = {302, "wishbone", "/foo/bar/"}; return check_redir(&args, "http://localhost:7777/foo/bar/wishbone"); } #if 0 /* could implement failure on self-referential redirects, but * realistically, the application must implement a max-redirs count * check, so it's kind of redundant. Mozilla takes this approach. */ static int fail_loop(void) { ne_session *sess; CALL(make_session(&sess, serve_redir, "http://localhost:7777/foo/bar")); ne_redirect_register(sess); ONN("followed looping redirect", any_request(sess, "/foo/bar") != NE_ERROR); ne_session_destroy(sess); return OK; } #endif /* ensure that ne_redirect_location returns NULL when no redirect has * been encountered, or redirect hooks aren't registered. */ static int no_redirect(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); const ne_uri *loc; ONN("redirect non-NULL before register", ne_redirect_location(sess)); ne_redirect_register(sess); ONN("initial redirect non-NULL", ne_redirect_location(sess)); CALL(spawn_server(7777, single_serve_string, "HTTP/1.0 200 OK\r\n\r\n\r\n")); ONREQ(any_request(sess, "/noredir")); CALL(await_server()); ONN("redirect non-NULL after non-redir req", ne_redirect_location(sess)); CALL(spawn_server(7777, single_serve_string, "HTTP/1.0 302 Get Ye Away\r\n" "Location: /blah\r\n" "\r\n")); CALL(process_redir(sess, "/foo", &loc)); CALL(await_server()); ne_session_destroy(sess); return OK; } ne_test tests[] = { T(lookup_localhost), T(simple), T(non_absolute), T(relative_1), T(relative_2), T(no_redirect), T(NULL) }; davix-R_0_5_0/deps/libneon/test/request.c000066400000000000000000001756661257152637300205060ustar00rootroot00000000000000/* HTTP request handling tests Copyright (C) 2001-2010, Joe Orton 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 "config.h" #include #include /* for time() */ #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include "ne_request.h" #include "ne_socket.h" #include "tests.h" #include "child.h" #include "utils.h" static char buffer[BUFSIZ]; static ne_session *def_sess; static ne_request *def_req; static int prepare_request(server_fn fn, void *ud) { static char uri[100]; def_sess = ne_session_create("http", "localhost", 7777); sprintf(uri, "/test%d", test_num); def_req = ne_request_create(def_sess, "GET", uri); CALL(spawn_server(7777, fn, ud)); return OK; } static int finish_request(void) { ne_request_destroy(def_req); ne_session_destroy(def_sess); return await_server(); } #define RESP200 "HTTP/1.1 200 OK\r\n" "Server: neon-test-server\r\n" #define TE_CHUNKED "Transfer-Encoding: chunked\r\n" /* takes response body chunks and appends them to a buffer. */ static int collector(void *ud, const char *data, size_t len) { ne_buffer *buf = ud; ne_buffer_append(buf, data, len); return 0; } typedef ne_request *(*construct_request)(ne_session *sess, void *userdata); /* construct a get request, callback for run_request. */ static ne_request *construct_get(ne_session *sess, void *userdata) { ne_request *r = ne_request_create(sess, "GET", "/"); ne_buffer *buf = userdata; ne_add_response_body_reader(r, ne_accept_2xx, collector, buf); return r; } /* run a request created by callback 'cb' in session 'sess'. */ static int run_request(ne_session *sess, int status, construct_request cb, void *userdata) { ne_request *req = cb(sess, userdata); ON(req == NULL); ONREQ(ne_request_dispatch(req)); ONV(ne_get_status(req)->code != status, ("response status-code was %d not %d", ne_get_status(req)->code, status)); ne_request_destroy(req); return OK; } /* Runs a server function 'fn', expecting to get a header 'name' with * value 'value' in the response. If 'value' is NULL, expects that * *no* header of that name is present. */ static int expect_header_value(const char *name, const char *value, server_fn fn, void *userdata) { ne_session *sess; ne_request *req; const char *gotval; CALL(make_session(&sess, fn, userdata)); req = ne_request_create(sess, "FOO", "/bar"); ONREQ(ne_request_dispatch(req)); CALL(await_server()); gotval = ne_get_response_header(req, name); ONV(value && !gotval, ("header '%s: %s' not sent", name, value)); ONV(!value && gotval, ("header '%s: %s' not expected", name, gotval)); ONV(value && gotval && strcmp(gotval, value), ("header '%s' mis-match: got '%s' not '%s'", name, gotval, value)); ne_request_destroy(req); ne_session_destroy(sess); return OK; } /* runs a server function 'fn', expecting response body to be equal to * 'expect' */ static int expect_response(const char *expect, server_fn fn, void *userdata) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_buffer *buf = ne_buffer_create(); ON(sess == NULL || buf == NULL); ON(spawn_server(7777, fn, userdata)); CALL(run_request(sess, 200, construct_get, buf)); ON(await_server()); ONN("response body match", strcmp(buf->data, expect)); ne_session_destroy(sess); ne_buffer_destroy(buf); return OK; } #define EMPTY_RESP RESP200 "Content-Length: 0\r\n\r\n" /* Process a request with given method and response, expecting to get * a zero-length response body. A second request is sent down the * connection (to ensure that the response isn't silently eaten), so * 'resp' must be an HTTP/1.1 response with no 'Connection: close' * header. */ static int expect_no_body(const char *method, const char *resp) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_request *req = ne_request_create(sess, method, "/first"); ssize_t ret; char *r = ne_malloc(strlen(resp) + sizeof(EMPTY_RESP)); strcpy(r, resp); strcat(r, EMPTY_RESP); ON(spawn_server(7777, single_serve_string, r)); ne_free(r); ONN("failed to begin request", ne_begin_request(req)); ret = ne_read_response_block(req, buffer, BUFSIZ); ONV(ret != 0, ("got response block of size %" NE_FMT_SSIZE_T, ret)); ONN("failed to end request", ne_end_request(req)); /* process following request; makes sure that nothing extra has * been eaten by the first request. */ ONV(any_request(sess, "/second"), ("second request on connection failed: %s",ne_get_error(sess))); ON(await_server()); ne_request_destroy(req); ne_session_destroy(sess); return OK; } static int reason_phrase(void) { ne_session *sess; CALL(make_session(&sess, single_serve_string, RESP200 "Connection: close\r\n\r\n")); ONREQ(any_request(sess, "/foo")); CALL(await_server()); ONV(strcmp(ne_get_error(sess), "200 OK"), ("reason phrase mismatch: got `%s' not `200 OK'", ne_get_error(sess))); ne_session_destroy(sess); return OK; } static int single_get_eof(void) { return expect_response("a", single_serve_string, RESP200 "Connection: close\r\n" "\r\n" "a"); } static int single_get_clength(void) { return expect_response("a", single_serve_string, RESP200 "Content-Length: \t\t 1 \t\t\r\n" "\r\n" "a" "bbbbbbbbasdasd"); } static int single_get_chunked(void) { return expect_response("a", single_serve_string, RESP200 TE_CHUNKED "\r\n" "1\r\n" "a\r\n" "0\r\n" "\r\n" "g;lkjalskdjalksjd"); } static int no_body_304(void) { return expect_no_body("GET", "HTTP/1.1 304 Not Mfodified\r\n" "Content-Length: 5\r\n\r\n"); } static int no_body_204(void) { return expect_no_body("GET", "HTTP/1.1 204 Not Modified\r\n" "Content-Length: 5\r\n\r\n"); } static int no_body_HEAD(void) { return expect_no_body("HEAD", "HTTP/1.1 200 OK\r\n" "Content-Length: 5\r\n\r\n"); } static int no_headers(void) { return expect_response("abcde", single_serve_string, "HTTP/1.1 200 OK\r\n\r\n" "abcde"); } #define CHUNK(len, data) #len "\r\n" data "\r\n" #define ABCDE_CHUNKS CHUNK(1, "a") CHUNK(1, "b") \ CHUNK(1, "c") CHUNK(1, "d") \ CHUNK(1, "e") CHUNK(0, "") static int chunks(void) { /* lots of little chunks. */ return expect_response("abcde", single_serve_string, RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS); } static int te_header(void) { return expect_response("abcde", single_serve_string, RESP200 "Transfer-Encoding: CHUNKED\r\n" "\r\n" ABCDE_CHUNKS); } static int te_identity(void) { /* http://bugzilla.gnome.org/show_bug.cgi?id=310636 says privoxy * uses the "identity" transfer-coding. */ return expect_response("abcde", single_serve_string, RESP200 "Transfer-Encoding: identity\r\n" "Content-Length: 5\r\n" "\r\n" "abcde"); } static int chunk_numeric(void) { /* leading zero's */ return expect_response("0123456789abcdef", single_serve_string, RESP200 TE_CHUNKED "\r\n" "000000010\r\n" "0123456789abcdef\r\n" "000000000\r\n" "\r\n"); } static int chunk_extensions(void) { /* chunk-extensions. */ return expect_response("0123456789abcdef", single_serve_string, RESP200 TE_CHUNKED "\r\n" "000000010; foo=bar; norm=fish\r\n" "0123456789abcdef\r\n" "000000000\r\n" "\r\n"); } static int chunk_trailers(void) { /* trailers. */ return expect_response("abcde", single_serve_string, RESP200 TE_CHUNKED "\r\n" "00000005; foo=bar; norm=fish\r\n" "abcde\r\n" "000000000\r\n" "X-Hello: world\r\n" "X-Another: header\r\n" "\r\n"); } static int chunk_oversize(void) { #define BIG (20000) char *body = ne_malloc(BIG + 1); static const char rnd[] = "abcdefghijklm"; int n; ne_buffer *buf = ne_buffer_create(); for (n = 0; n < BIG; n++) { body[n] = rnd[n % (sizeof(rnd) - 1)]; } body[n] = '\0'; #undef BIG ne_buffer_concat(buf, RESP200 TE_CHUNKED "\r\n" "4E20\r\n", body, "\r\n", "0\r\n\r\n", NULL); CALL(expect_response(body, single_serve_string, buf->data)); ne_buffer_destroy(buf); ne_free(body); return OK; } static int te_over_clength(void) { /* T-E dominates over C-L. */ return expect_response("abcde", single_serve_string, RESP200 TE_CHUNKED "Content-Length: 300\r\n" "\r\n" ABCDE_CHUNKS); } /* te_over_clength with the headers the other way round; check for * ordering problems. */ static int te_over_clength2(void) { return expect_response("abcde", single_serve_string, RESP200 "Content-Length: 300\r\n" TE_CHUNKED "\r\n" ABCDE_CHUNKS); } /* obscure case which is possibly a valid request by 2616, but should * be handled correctly in any case. neon <0.22.0 tries to * eat the response body, which is probably incorrect. */ static int no_body_chunks(void) { return expect_no_body("HEAD", "HTTP/1.1 204 Not Modified\r\n" TE_CHUNKED "\r\n"); } static int serve_twice(ne_socket *sock, void *userdata) { const char *resp = userdata; CALL(discard_request(sock)); SEND_STRING(sock, resp); CALL(discard_request(sock)); SEND_STRING(sock, resp); return OK; } /* Test persistent connection handling: serve 'response' twice on a * single TCP connection, expecting to get a response body equal to * 'body' both times. */ static int test_persist_p(const char *response, const char *body, int proxy) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_buffer *buf = ne_buffer_create(); ON(sess == NULL || buf == NULL); ON(spawn_server(7777, serve_twice, (char *)response)); if (proxy) { ne_session_proxy(sess, "localhost", 7777); ne_set_session_flag(sess, NE_SESSFLAG_CONNAUTH, 1); } CALL(run_request(sess, 200, construct_get, buf)); ONV(strcmp(buf->data, body), ("response #1 mismatch: [%s] not [%s]", buf->data, body)); /* Run it again. */ ne_buffer_clear(buf); CALL(run_request(sess, 200, construct_get, buf)); ON(await_server()); ONV(strcmp(buf->data, body), ("response #2 mismatch: [%s] not [%s]", buf->data, body)); ne_session_destroy(sess); ne_buffer_destroy(buf); return OK; } static int test_persist(const char *response, const char *body) { return test_persist_p(response, body, 0); } static int persist_http11(void) { return test_persist(RESP200 "Content-Length: 5\r\n\r\n" "abcde", "abcde"); } static int persist_chunked(void) { return test_persist(RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS, "abcde"); } static int persist_http10(void) { return test_persist("HTTP/1.0 200 OK\r\n" "Connection: keep-alive\r\n" "Content-Length: 5\r\n\r\n" "abcde", "abcde"); } static int persist_proxy_http10(void) { return test_persist_p("HTTP/1.0 200 OK\r\n" "Proxy-Connection: keep-alive\r\n" "Content-Length: 5\r\n\r\n" "abcde", "abcde", 1); } /* Server function for fail_early_eof */ static int serve_eof(ne_socket *sock, void *ud) { const char *resp = ud; /* dummy request/response. */ CALL(discard_request(sock)); CALL(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n")); /* real request/response. */ CALL(discard_request(sock)); CALL(SEND_STRING(sock, resp)); return OK; } /* Utility function: 'resp' is a truncated response; such that an EOF * arrives early during response processing; but NOT as a valid * premature EOF due to a persistent connection timeout. It is an * error if the request is then retried, and the test fails. */ static int fail_early_eof(const char *resp) { ne_session *sess = ne_session_create("http", "localhost", 7777); CALL(spawn_server_repeat(7777, serve_eof, (char *)resp, 3)); ONREQ(any_request(sess, "/foo")); ONN("request retried after early EOF", any_request(sess, "/foobar") == NE_OK); CALL(reap_server()); ne_session_destroy(sess); return OK; } /* This failed with neon <0.22. */ static int fail_eof_continued(void) { return fail_early_eof("HTTP/1.1 100 OK\r\n\r\n"); } static int fail_eof_headers(void) { return fail_early_eof("HTTP/1.1 200 OK\r\nJimbob\r\n"); } static int fail_eof_chunk(void) { return fail_early_eof(RESP200 TE_CHUNKED "\r\n" "1\r\n" "a"); } static int fail_eof_badclen(void) { return fail_early_eof(RESP200 "Content-Length: 10\r\n\r\n" "abcde"); } /* Persistent connection timeout where a FIN is sent to terminate the * connection, which is caught by a 0 return from the read() when the * second request reads the status-line. */ static int ptimeout_eof(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); CALL(spawn_server_repeat(7777, single_serve_string, RESP200 "Content-Length: 0\r\n" "\r\n", 4)); CALL(any_2xx_request(sess, "/first")); CALL(any_2xx_request(sess, "/second")); ONN("server died prematurely?", dead_server()); reap_server(); ne_session_destroy(sess); return OK; } /* Persistent connection timeout where a FIN is sent to terminate the * connection, but the request fails in the write() call which sends * the body. */ static int ptimeout_eof2(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); CALL(spawn_server_repeat(7777, single_serve_string, RESP200 "Content-Length: 0\r\n" "\r\n", 4)); CALL(any_2xx_request(sess, "/first")); minisleep(); CALL(any_2xx_request_body(sess, "/second")); ONN("server died prematurely?", dead_server()); reap_server(); ne_session_destroy(sess); return OK; } /* TODO: add a ptimeout_reset too, if an RST can be reliably generated * mid-connection. */ /* Emulates a persistent connection timeout on the server. This tests * the timeout occuring after between 1 and 10 requests down the * connection. */ static int persist_timeout(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_buffer *buf = ne_buffer_create(); int n; struct many_serve_args args; ON(sess == NULL || buf == NULL); args.str = RESP200 "Content-Length: 5\r\n\r\n" "abcde"; for (args.count = 1; args.count < 10; args.count++) { ON(spawn_server(7777, many_serve_string, &args)); for (n = 0; n < args.count; n++) { ONV(run_request(sess, 200, construct_get, buf), ("%d of %d, request failed: %s", n, args.count, ne_get_error(sess))); ONV(strcmp(buf->data, "abcde"), ("%d of %d, response body mismatch", n, args.count)); /* Ready for next time. */ ne_buffer_clear(buf); } ON(await_server()); } ne_session_destroy(sess); ne_buffer_destroy(buf); return OK; } /* Test that an HTTP/1.0 server is not presumed to support persistent * connections by default. */ static int no_persist_http10(void) { ne_session *sess = ne_session_create("http", "localhost", 7777); CALL(spawn_server_repeat(7777, single_serve_string, "HTTP/1.0 200 OK\r\n" "Content-Length: 5\r\n\r\n" "abcde" "Hello, world - what a nice day!\r\n", 4)); /* if the connection is treated as persistent, the status-line for * the second request will be "Hello, world...", which will * fail. */ ONREQ(any_request(sess, "/foobar")); ONREQ(any_request(sess, "/foobar")); ONN("server died prematurely?", dead_server()); CALL(reap_server()); ne_session_destroy(sess); return OK; } static int ignore_bad_headers(void) { return expect_response("abcde", single_serve_string, RESP200 "Stupid Header\r\n" "ReallyStupidHeader\r\n" "Content-Length: 5\r\n" "\r\n" "abcde"); } static int fold_headers(void) { return expect_response("abcde", single_serve_string, RESP200 "Content-Length: \r\n 5\r\n" "\r\n" "abcde"); } static int fold_many_headers(void) { return expect_response("abcde", single_serve_string, RESP200 "Content-Length: \r\n \r\n \r\n \r\n 5\r\n" "\r\n" "abcde"); } #define NO_BODY "Content-Length: 0\r\n\r\n" static int empty_header(void) { return expect_header_value("ranDom-HEader", "", single_serve_string, RESP200 "RANDom-HeADEr:\r\n" NO_BODY); } static int ignore_header_case(void) { return expect_header_value("ranDom-HEader", "noddy", single_serve_string, RESP200 "RANDom-HeADEr: noddy\r\n" NO_BODY); } static int ignore_header_ws(void) { return expect_header_value("ranDom-HEader", "fishy", single_serve_string, RESP200 "RANDom-HeADEr: fishy\r\n" NO_BODY); } static int ignore_header_ws2(void) { return expect_header_value("ranDom-HEader", "fishy", single_serve_string, RESP200 "RANDom-HeADEr \t : fishy\r\n" NO_BODY); } static int ignore_header_ws3(void) { return expect_header_value("ranDom-HEader", "fishy", single_serve_string, RESP200 "RANDom-HeADEr: fishy \r\n" NO_BODY); } static int ignore_header_tabs(void) { return expect_header_value("ranDom-HEader", "geezer", single_serve_string, RESP200 "RANDom-HeADEr: \t \tgeezer\r\n" NO_BODY); } static int trailing_header(void) { return expect_header_value("gONe", "fishing", single_serve_string, RESP200 TE_CHUNKED "\r\n0\r\n" "Hello: world\r\n" "GONE: fishing\r\n" "\r\n"); } static int continued_header(void) { return expect_header_value("hello", "w o r l d", single_serve_string, RESP200 "Hello: \n\tw\r\n\to r l\r\n\td \r\n" NO_BODY); } /* check headers callbacks are working correctly. */ static int multi_header(void) { return expect_header_value("X-Header", "jim, jab, jar", single_serve_string, RESP200 "X-Header: jim\r\n" "x-header: jab\r\n" "x-Header: jar\r\n" "Content-Length: 0\r\n\r\n"); } /* check headers callbacks are working correctly. */ static int multi_header2(void) { return expect_header_value("X-Header", "jim, jab, jar", single_serve_string, RESP200 "X-Header: jim \r\n" "x-header: jab \r\n" "x-Header: jar \r\n" "Content-Length: 0\r\n\r\n"); } /* RFC 2616 14.10: headers listed in Connection must be stripped on * receiving an HTTP/1.0 message in case there was a pre-1.1 proxy * somewhere. */ static int strip_http10_connhdr(void) { return expect_header_value("X-Widget", NULL, single_serve_string, "HTTP/1.0 200 OK\r\n" "Connection: x-widget\r\n" "x-widget: blah\r\n" "Content-Length: 0\r\n" "\r\n"); } static int strip_http10_connhdr2(void) { return expect_header_value("X-Widget", NULL, single_serve_string, "HTTP/1.0 200 OK\r\n" "Connection: connection, x-fish, x-widget\r\n" "x-widget: blah\r\n" "Content-Length: 0\r\n" "\r\n"); } static int post_send_retry(ne_request *req, void *userdata, const ne_status *status) { return status->code == 400 ? NE_RETRY : NE_OK; } /* Test that the stored response headers are forgotten if the request * is retried. */ static int reset_headers(void) { ne_session *sess; ne_request *req; const char *value; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 400 Hit me again\r\n" "Content-Length: 0\r\n" "X-Foo: bar\r\n" "\r\n" "HTTP/1.1 200 Thank you kindly\r\n" "Content-Length: 0\r\n" "X-Foo: hello fair world\r\n" "\r\n")); ne_hook_post_send(sess, post_send_retry, NULL); req = ne_request_create(sess, "GET", "/foo"); ONREQ(ne_request_dispatch(req)); value = ne_get_response_header(req, "X-Foo"); ONCMP("hello fair world", value, "response header", "X-Foo"); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); return OK; } static int iterate_none(void) { ne_session *sess; ne_request *req; CALL(make_session(&sess, single_serve_string, "HTTP/1.0 200 OK\r\n\r\n")); req = ne_request_create(sess, "GET", "/"); ONREQ(ne_request_dispatch(req)); ONN("iterator was not NULL for no headers", ne_response_header_iterate(req, NULL, NULL, NULL) != NULL); CALL(await_server()); ne_request_destroy(req); ne_session_destroy(sess); return OK; } #define MANY_HEADERS (90) static int iterate_many(void) { ne_request *req; ne_buffer *buf = ne_buffer_create(); ne_session *sess; int n; struct header { char name[10], value[10]; int seen; } hdrs[MANY_HEADERS]; void *cursor = NULL; const char *name, *value; ne_buffer_czappend(buf, "HTTP/1.0 200 OK\r\n"); for (n = 0; n < MANY_HEADERS; n++) { sprintf(hdrs[n].name, "x-%d", n); sprintf(hdrs[n].value, "Y-%d", n); hdrs[n].seen = 0; ne_buffer_concat(buf, hdrs[n].name, ": ", hdrs[n].value, "\r\n", NULL); } ne_buffer_czappend(buf, "\r\n"); CALL(make_session(&sess, single_serve_string, buf->data)); req = ne_request_create(sess, "GET", "/foo"); ONREQ(ne_request_dispatch(req)); while ((cursor = ne_response_header_iterate(req, cursor, &name, &value))) { n = -1; ONV(strncmp(name, "x-", 2) || strncmp(value, "Y-", 2) || strcmp(name + 2, value + 2) || (n = atoi(name + 2)) >= MANY_HEADERS || n < 0, ("bad name/value pair: %s = %s", name, value)); NE_DEBUG(NE_DBG_HTTP, "iterate: got pair (%d): %s = %s\n", n, name, value); ONV(hdrs[n].seen == 1, ("duplicate pair %d", n)); hdrs[n].seen = 1; } for (n = 0; n < MANY_HEADERS; n++) { ONV(hdrs[n].seen == 0, ("unseen pair %d", n)); } ne_buffer_destroy(buf); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); return OK; } struct s1xx_args { int count; int hdrs; }; static int serve_1xx(ne_socket *sock, void *ud) { struct s1xx_args *args = ud; CALL(discard_request(sock)); do { if (args->hdrs) { SEND_STRING(sock, "HTTP/1.1 100 Continue\r\n" "Random: header\r\n" "Another: header\r\n\r\n"); } else { SEND_STRING(sock, "HTTP/1.1 100 Continue\r\n\r\n"); } } while (--args->count > 0); SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n"); return OK; } #define sess def_sess static int skip_interim_1xx(void) { struct s1xx_args args = {0, 0}; ON(prepare_request(serve_1xx, &args)); ONREQ(ne_request_dispatch(def_req)); return finish_request(); } static int skip_many_1xx(void) { struct s1xx_args args = {5, 0}; ON(prepare_request(serve_1xx, &args)); ONREQ(ne_request_dispatch(def_req)); return finish_request(); } static int skip_1xx_hdrs(void) { struct s1xx_args args = {5, 5}; ON(prepare_request(serve_1xx, &args)); ONREQ(ne_request_dispatch(def_req)); return finish_request(); } #undef sess /* server for expect_100_once: serves a 100-continue request, and * fails if the request body is sent twice. */ static int serve_100_once(ne_socket *sock, void *ud) { struct s1xx_args args = {2, 0}; char ch; CALL(serve_1xx(sock, &args)); CALL(discard_body(sock)); ONN("body was served twice", ne_sock_read(sock, &ch, 1) == 1); return OK; } /* regression test; fails with neon <0.22, where the request body was * served *every* time a 1xx response was received, rather than just * once. */ static int expect_100_once(void) { ne_session *sess; ne_request *req; char body[BUFSIZ]; CALL(make_session(&sess, serve_100_once, NULL)); req = ne_request_create(sess, "GET", "/foo"); ne_set_request_flag(req, NE_REQFLAG_EXPECT100, 1); ONN("expect100 flag ignored", ne_get_request_flag(req, NE_REQFLAG_EXPECT100) != 1); memset(body, 'A', sizeof(body)); ne_set_request_body_buffer(req, body, sizeof(body)); ONREQ(ne_request_dispatch(req)); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); return OK; } /* regression test for enabling 100-continue without sending a body. */ static int expect_100_nobody(void) { ne_session *sess; ne_request *req; CALL(make_session(&sess, serve_100_once, NULL)); req = ne_request_create(sess, "GET", "/foo"); ne_set_request_flag(req, NE_REQFLAG_EXPECT100, 1); ONREQ(ne_request_dispatch(req)); ne_request_destroy(req); ne_session_destroy(sess); return await_server(); } struct body { char *body; size_t size; }; static int want_body(ne_socket *sock, void *userdata) { struct body *b = userdata; char *buf = ne_malloc(b->size); clength = 0; CALL(discard_request(sock)); ONN("request has c-l header", clength == 0); ONN("request length", clength != (int)b->size); NE_DEBUG(NE_DBG_HTTP, "reading body of %" NE_FMT_SIZE_T " bytes...\n", b->size); ON(ne_sock_fullread(sock, buf, b->size)); ON(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n")); ON(memcmp(buf, b->body, b->size)); ne_free(buf); return OK; } static ssize_t provide_body(void *userdata, char *buf, size_t buflen) { static const char *pnt; static size_t left; struct body *b = userdata; if (buflen == 0) { pnt = b->body; left = b->size; } else { if (left < buflen) buflen = left; memcpy(buf, pnt, buflen); left -= buflen; } return buflen; } static int send_bodies(void) { unsigned int n, m; struct body bodies[] = { { "abcde", 5 }, { "\0\0\0\0\0\0", 6 }, { NULL, 50000 }, { NULL } }; #define BIG 2 /* make the body with some cruft. */ bodies[BIG].body = ne_malloc(bodies[BIG].size); for (n = 0; n < bodies[BIG].size; n++) { bodies[BIG].body[n] = (char)n%80; } for (m = 0; m < 2; m++) { for (n = 0; bodies[n].body != NULL; n++) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_request *req; ON(sess == NULL); ON(spawn_server(7777, want_body, &(bodies[n]))); req = ne_request_create(sess, "PUT", "/"); ON(req == NULL); if (m == 0) { ne_set_request_body_buffer(req, bodies[n].body, bodies[n].size); } else { ne_set_request_body_provider(req, bodies[n].size, provide_body, &bodies[n]); } ONREQ(ne_request_dispatch(req)); CALL(await_server()); ne_request_destroy(req); ne_session_destroy(sess); } } ne_free(bodies[BIG].body); return OK; } /* Utility function: run a request using the given server fn, and the * request should fail. If 'error' is non-NULL, it must be a substring * of the error string. */ static int fail_request_with_error(int with_body, server_fn fn, void *ud, int forever, const char *error) { ne_session *sess = ne_session_create("http", "localhost", 7777); ne_request *req; int ret; ON(sess == NULL); if (forever) { ON(spawn_server_repeat(7777, fn, ud, 100)); } else { ON(spawn_server(7777, fn, ud)); } req = ne_request_create(sess, "GET", "/"); ON(req == NULL); if (with_body) { static const char *body = "random stuff"; ne_set_request_body_buffer(req, body, strlen(body)); } /* request should fail. */ ret = ne_request_dispatch(req); ONN("request succeeded", ret == NE_OK); if (!forever) { /* reap the server, don't care what it's doing. */ reap_server(); } NE_DEBUG(NE_DBG_HTTP, "Response gave error `%s'\n", ne_get_error(sess)); ONV(error && strstr(ne_get_error(sess), error) == NULL, ("failed with error `%s', no `%s'", ne_get_error(sess), error)); if (!forever) ONV(any_request(sess, "/fail/to/connect") != NE_CONNECT, ("subsequent request re-used connection?")); ne_request_destroy(req); ne_session_destroy(sess); return OK; } /* Run a random GET request which is given 'body' as the response; the * request must fail, and 'error' must be found in the error * string. */ static int invalid_response_gives_error(const char *resp, const char *error) { return fail_request_with_error(0, single_serve_string, (void *)resp, 0, error); } /* Utility function: run a request using the given server fn, and the * request must fail. */ static int fail_request(int with_body, server_fn fn, void *ud, int forever) { return fail_request_with_error(with_body, fn, ud, forever, NULL); } static int unbounded_headers(void) { struct infinite i = { RESP200, "x-foo: bar\r\n" }; return fail_request(0, serve_infinite, &i, 0); } static int blank_response(void) { return fail_request(0, single_serve_string, "\r\n", 0); } static int serve_non_http(ne_socket *sock, void *ud) { SEND_STRING(sock, "Hello Mum.\n"); ne_sock_readline(sock, buffer, BUFSIZ); return OK; } /* Test behaviour when not speaking to an HTTP server. Regression test * for infinite loop. */ static int not_http(void) { return fail_request(0, serve_non_http, NULL, 0); } static int unbounded_folding(void) { struct infinite i = { "HTTP/1.0 200 OK\r\nFoo: bar\r\n", " hello there.\r\n" }; return fail_request(0, serve_infinite, &i, 0); } static int serve_close(ne_socket *sock, void *ud) { /* do nothing; the socket will be closed. */ return 0; } /* Returns non-zero if port is alive. */ static int is_alive(int port) { ne_sock_addr *addr; ne_socket *sock = ne_sock_create(); const ne_inet_addr *ia; int connected = 0; addr = ne_addr_resolve("localhost", 0); for (ia = ne_addr_first(addr); ia && !connected; ia = ne_addr_next(addr)) connected = ne_sock_connect(sock, ia, 7777) == 0; ne_addr_destroy(addr); if (sock == NULL) return 0; else { ne_sock_close(sock); return 1; } } /* This is a regression test for neon 0.17.0 and earlier, which goes * into an infinite loop if a request with a body is sent to a server * which simply closes the connection. */ static int closed_connection(void) { int ret; /* This spawns a server process which will run the 'serve_close' * response function 200 times, then die. This guarantees that the * request eventually fails... */ CALL(fail_request(1, serve_close, NULL, 1)); /* if server died -> infinite loop was detected. */ ret = !is_alive(7777); reap_server(); ONN("server aborted, infinite loop?", ret); return OK; } static int serve_close2(ne_socket *sock, void *userdata) { int *count = userdata; *count += 1; if (*count == 1) return 0; NE_DEBUG(NE_DBG_HTTP, "Re-entered! Buggy client.\n"); CALL(discard_request(sock)); CALL(SEND_STRING(sock, RESP200 "Content-Length: 0\r\n\r\n")); return 0; } /* As closed_connection(); but check that the client doesn't retry * after receiving the EOF on the first request down a new * connection. */ static int close_not_retried(void) { int count = 0; ne_session *sess = ne_session_create("http", "localhost", 7777); CALL(spawn_server_repeat(7777, serve_close2, &count, 3)); ONN("request was retried after EOF", any_request(sess, "/foo") == NE_OK); reap_server(); ne_session_destroy(sess); return OK; } static enum { prog_error, /* error */ prog_transfer, /* doing a transfer */ prog_done /* finished. */ } prog_state = prog_transfer; static ne_off_t prog_last = -1, prog_total; #define FOFF "%" NE_FMT_NE_OFF_T /* callback for send_progress. */ static void s_progress(void *userdata, ne_off_t prog, ne_off_t total) { NE_DEBUG(NE_DBG_HTTP, "progress callback: " FOFF "/" FOFF ".\n", prog, total); switch (prog_state) { case prog_error: case prog_done: return; case prog_transfer: if (total != prog_total) { t_context("total unexpected: " FOFF " not " FOFF "", total, prog_total); prog_state = prog_error; } else if (prog > total) { t_context("first progress was invalid (" FOFF "/" FOFF ")", prog, total); prog_state = prog_error; } else if (prog_last != -1 && prog_last > prog) { t_context("progess went backwards: " FOFF " to " FOFF, prog_last, prog); prog_state = prog_error; } else if (prog_last == prog) { t_context("no progress made! " FOFF " to " FOFF, prog_last, prog); prog_state = prog_error; } else if (prog == total) { prog_state = prog_done; } break; } prog_last = prog; } #undef FOFF static ssize_t provide_progress(void *userdata, char *buf, size_t bufsiz) { int *count = userdata; if (*count >= 0 && buf != NULL) { buf[0] = 'a'; *count -= 1; return 1; } else { return 0; } } static int send_progress(void) { static int count = 200; ON(prepare_request(single_serve_string, RESP200 "Connection: close\r\n\r\n")); prog_total = 200; ne_set_progress(def_sess, s_progress, NULL); ne_set_request_body_provider(def_req, count, provide_progress, &count); #define sess def_sess ONREQ(ne_request_dispatch(def_req)); #undef sess ON(finish_request()); CALL(prog_state == prog_error); return OK; } static int read_timeout(void) { ne_session *sess; ne_request *req; time_t start, finish; int ret; CALL(make_session(&sess, sleepy_server, NULL)); /* timeout after one second. */ ne_set_read_timeout(sess, 1); req = ne_request_create(sess, "GET", "/timeout"); time(&start); ret = ne_request_dispatch(req); time(&finish); reap_server(); ONN("request succeeded, should have timed out", ret == NE_OK); ONV(ret != NE_TIMEOUT, ("request failed non-timeout error: %s", ne_get_error(sess))); ONN("timeout ignored, or very slow machine", finish - start > 3); ne_request_destroy(req); ne_session_destroy(sess); return OK; } /* expect failure code 'code', for request to given hostname and port, * without running a server. */ static int fail_noserver(const char *hostname, unsigned int port, int code) { ne_session *sess = ne_session_create("http", hostname, port); int ret = any_request(sess, "/foo"); ne_session_destroy(sess); ONV(ret == NE_OK, ("request to server at %s:%u succeded?!", hostname, port)); ONV(ret != code, ("request failed with %d not %d", ret, code)); return OK; } static int fail_lookup(void) { return fail_noserver("no.such.domain", 7777, NE_LOOKUP); } /* neon 0.23.0 to 0.23.3: if a nameserver lookup failed, subsequent * requests on the session would crash. */ static int fail_double_lookup(void) { ne_session *sess = ne_session_create("http", "nonesuch.invalid", 80); ONN("request did not give lookup failure", any_request(sess, "/foo") != NE_LOOKUP); ONN("second request did not give lookup failure", any_request(sess, "/bar") != NE_LOOKUP); ne_session_destroy(sess); return OK; } static int fail_connect(void) { return fail_noserver("localhost", 7777, NE_CONNECT); } /* Test that the origin server hostname is NOT resolved for a proxied * request. */ static int proxy_no_resolve(void) { ne_session *sess = ne_session_create("http", "nonesuch2.invalid", 80); int ret; ne_session_proxy(sess, "localhost", 7777); CALL(spawn_server(7777, single_serve_string, RESP200 "Content-Length: 0\r\n\r\n")); ret = any_request(sess, "/foo"); ne_session_destroy(sess); ONN("origin server name resolved when proxy used", ret == NE_LOOKUP); CALL(await_server()); return OK; } /* If the chunk size is entirely invalid, the request should be * aborted. Fails with neon <0.22; invalid chunk sizes would be * silently treated as 'zero'. */ static int fail_chunksize(void) { return fail_request(0, single_serve_string, RESP200 TE_CHUNKED "\r\n" "ZZZZZ\r\n\r\n", 0); } /* in neon <0.22, if an error occcurred whilst reading the response * body, the connection would not be closed (though this test will * succeed in neon <0.22 since it the previous test fails). */ static int abort_respbody(void) { ne_session *sess; CALL(make_session(&sess, single_serve_string, RESP200 TE_CHUNKED "\r\n" "zzz\r\n" RESP200 "Content-Length: 0\r\n\r\n")); /* connection must be aborted on the first request, since it * contains an invalid chunk size. */ ONN("invalid chunk size was accepted?", any_request(sess, "/foo") != NE_ERROR); CALL(await_server()); /* second request should fail since server has gone away. */ ONN("connection was not aborted", any_request(sess, "/foo") == NE_OK); ne_session_destroy(sess); return OK; } static int serve_abort(ne_socket *sock, void *ud) { exit(0); } /* Test that after an aborted request on a peristent connection, a * failure of the *subsequent* request is not treated as a persistent * connection timeout and retried. */ static int retry_after_abort(void) { ne_session *sess; /* Serve two responses down a single persistent connection, the * second of which is invalid and will cause the request to be * aborted. */ CALL(make_session(&sess, single_serve_string, RESP200 "Content-Length: 0\r\n\r\n" RESP200 TE_CHUNKED "\r\n" "zzzzz\r\n")); CALL(any_request(sess, "/first")); ONN("second request should fail", any_request(sess, "/second") == NE_OK); CALL(await_server()); /* spawn a server, abort the server immediately. If the * connection reset is interpreted as a p.conn timeout, a new * connection will be attempted, which will fail with * NE_CONNECT. */ CALL(spawn_server(7777, serve_abort, NULL)); ONN("third request was retried", any_request(sess, "/third") == NE_CONNECT); reap_server(); ne_session_destroy(sess); return OK; } /* Fail to parse the response status line: check the error message is * sane. Failed during 0.23-dev briefly, and possibly with 0.22.0 * too. */ static int fail_statusline(void) { ne_session *sess; int ret; CALL(make_session(&sess, single_serve_string, "Fish.\r\n")); ret = any_request(sess, "/fail"); ONV(ret != NE_ERROR, ("request failed with %d not NE_ERROR", ret)); ONV(strstr(ne_get_error(sess), "Could not parse response status line") == NULL, ("session error was `%s'", ne_get_error(sess))); ne_session_destroy(sess); return OK; } #define LEN (9000) static int fail_long_header(void) { char resp[LEN + 500] = "HTTP/1.1 200 OK\r\n" "Server: fish\r\n"; size_t len = strlen(resp); /* add a long header */ memset(resp + len, 'a', LEN); resp[len + LEN] = '\0'; strcat(resp, "\r\n\r\n"); return invalid_response_gives_error(resp, "Line too long"); } static int fail_on_invalid(void) { static const struct { const char *resp, *error; } ts[] = { /* non-chunked TE. */ { RESP200 "transfer-encoding: punked\r\n" "\r\n" ABCDE_CHUNKS , "Unknown transfer-coding" }, /* chunk without trailing CRLF */ { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcdeFISH", "delimiter was invalid" }, /* chunk with CR then EOF */ { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcde\n", "not read chunk delimiter" }, /* chunk with CR then notLF */ { RESP200 TE_CHUNKED "\r\n" "5\r\n" "abcde\rZZZ", "delimiter was invalid" }, /* chunk size overflow */ { RESP200 TE_CHUNKED "\r\n" "800000000\r\n" "abcde\r\n", "Could not parse chunk size" }, /* EOF at chunk size */ { RESP200 TE_CHUNKED "\r\n", "Could not read chunk size" }, /* negative C-L */ { RESP200 "Content-Length: -1\r\n" "\r\n" "abcde", "Invalid Content-Length" }, /* invalid C-Ls */ { RESP200 "Content-Length: 5, 3\r\n" "\r\n" "abcde", "Invalid Content-Length" }, { RESP200 "Content-Length: 5z\r\n" "\r\n" "abcde", "Invalid Content-Length" }, { RESP200 "Content-Length: z5\r\n" "\r\n" "abcde", "Invalid Content-Length" }, /* stupidly-large C-L */ { RESP200 "Content-Length: 99999999999999999999999999\r\n" "\r\n" "abcde", "Invalid Content-Length" }, { NULL, NULL } }; int n; for (n = 0; ts[n].resp; n++) CALL(invalid_response_gives_error(ts[n].resp, ts[n].error)); return OK; } static int versions(void) { ne_session *sess; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 OK\r\n" "Content-Length: 0\r\n\r\n" "HTTP/1.0 200 OK\r\n" "Content-Length: 0\r\n\r\n")); ONREQ(any_request(sess, "/http11")); ONN("did not detect HTTP/1.1 compliance", ne_version_pre_http11(sess) != 0); ONREQ(any_request(sess, "/http10")); ONN("did not detect lack of HTTP/1.1 compliance", ne_version_pre_http11(sess) == 0); ne_session_destroy(sess); return OK; } struct cr_args { const char *method, *uri; int result; }; static void hk_createreq(ne_request *req, void *userdata, const char *method, const char *requri) { struct cr_args *args = userdata; args->result = 1; /* presume failure */ if (strcmp(args->method, method)) t_context("Hook got method %s not %s", method, args->method); else if (strcmp(args->uri, requri)) t_context("Hook got Req-URI %s not %s", requri, args->uri); else args->result = 0; } static int hook_create_req(void) { ne_session *sess; struct cr_args args; CALL(make_session(&sess, single_serve_string, EMPTY_RESP EMPTY_RESP)); ne_hook_create_request(sess, hk_createreq, &args); args.method = "GET"; args.uri = "/foo"; args.result = -1; ONREQ(any_request(sess, "/foo")); ONN("first hook never called", args.result == -1); if (args.result) return FAIL; args.uri = "http://localhost:7777/bar"; args.result = -1; /* force use of absoluteURI in request-uri */ ne_session_proxy(sess, "localhost", 7777); ONREQ(any_request(sess, "/bar")); ONN("second hook never called", args.result == -1); if (args.result) return FAIL; ne_session_destroy(sess); return OK; } static int serve_check_method(ne_socket *sock, void *ud) { char *method = ud; char buf[20]; size_t methlen = strlen(method); if (ne_sock_read(sock, buf, methlen) != (ssize_t)methlen) return -1; ONN("method corrupted", memcmp(buf, method, methlen)); return single_serve_string(sock, "HTTP/1.1 204 OK\r\n\r\n"); } /* Test that the method string passed to ne_request_create is * strdup'ed. */ static int dup_method(void) { char method[] = "FOO"; ne_session *sess; ne_request *req; CALL(make_session(&sess, serve_check_method, method)); req = ne_request_create(sess, method, "/bar"); strcpy(method, "ZZZ"); ONREQ(ne_request_dispatch(req)); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); return OK; } static int abortive_reader(void *userdata, const char *buf, size_t len) { ne_session *sess = userdata; if (len == 5 && strncmp(buf, "abcde", 5) == 0) { ne_set_error(sess, "Reader callback failed"); } else { ne_set_error(sess, "Reader callback called with length %" NE_FMT_SIZE_T, len); } return NE_ERROR; } static int abort_reader(void) { ne_session *sess; ne_request *req; int ret; CALL(make_session(&sess, single_serve_string, RESP200 "Content-Length: 5\r\n\r\n" "abcde" "HTTP/1.1 200 OK\r\n" "Content-Length: 0\r\n\r\n")); req = ne_request_create(sess, "GET", "/foo"); ne_add_response_body_reader(req, ne_accept_2xx, abortive_reader, sess); ret = ne_request_dispatch(req); ONV(ret != NE_ERROR, ("request did not fail with NE_ERROR: %d", ret)); ONV(strcmp(ne_get_error(sess), "Reader callback failed") != 0, ("unexpected session error string: %s", ne_get_error(sess))); ne_request_destroy(req); /* test that the connection was closed. */ ONN("connection not closed after aborted response", any_2xx_request(sess, "/failmeplease") == OK); ne_session_destroy(sess); CALL(await_server()); return OK; } /* attempt and fail to send request from offset 500 of /dev/null. */ static int send_bad_offset(void) { ne_session *sess; ne_request *req; int ret, fds[2]; CALL(make_session(&sess, single_serve_string, RESP200 "Content-Length: 0\r\n" "\r\n")); /* create a pipe, on which seek is guaranteed to fail. */ ONN("could not create pipe", pipe(fds) != 0); req = ne_request_create(sess, "PUT", "/null"); ne_set_request_body_fd(req, fds[0], 500, 5); ret = ne_request_dispatch(req); close(fds[0]); close(fds[1]); ONN("request dispatched with bad offset!", ret == NE_OK); ONV(ret != NE_ERROR, ("request failed with unexpected error code %d: %s", ret, ne_get_error(sess))); ONV(strstr(ne_get_error(sess), "Could not seek") == NULL, ("bad error message from seek failure: %s", ne_get_error(sess))); reap_server(); ne_request_destroy(req); ne_session_destroy(sess); return OK; } static void thook_create_req(ne_request *req, void *userdata, const char *method, const char *requri) { ne_buffer *buf = userdata; ne_buffer_concat(buf, "(create,", method, ",", requri, ")\n", NULL); } static void hook_pre_send(ne_request *req, void *userdata, ne_buffer *header) { ne_buffer *buf = userdata; ne_buffer_czappend(buf, "(pre-send)\n"); } /* Returns a static string giving a comma-separated representation of * the status structure passed in. */ static char *status_to_string(const ne_status *status) { static char sbuf[128]; ne_snprintf(sbuf, sizeof sbuf, "HTTP/%d.%d,%d,%s", status->major_version, status->minor_version, status->code, status->reason_phrase); return sbuf; } static void hook_post_headers(ne_request *req, void *userdata, const ne_status *status) { ne_buffer *buf = userdata; ne_buffer_concat(buf, "(post-headers,", status_to_string(status), ")\n", NULL); } static int hook_post_send(ne_request *req, void *userdata, const ne_status *status) { ne_buffer *buf = userdata; ne_buffer_concat(buf, "(post-send,", status_to_string(status), ")\n", NULL); return NE_OK; } static void hook_destroy_req(ne_request *req, void *userdata) { ne_buffer *buf = userdata; ne_buffer_czappend(buf, "(destroy-req)\n"); } static void hook_destroy_sess(void *userdata) { ne_buffer *buf = userdata; ne_buffer_czappend(buf, "(destroy-sess)\n"); } static void hook_close_conn(void *userdata) { ne_buffer *buf = userdata; ne_buffer_czappend(buf, "(close-conn)\n"); } static int hooks(void) { ne_buffer *buf = ne_buffer_create(); ne_session *sess; struct many_serve_args args; args.str = RESP200 "Content-Length: 0\r\n" "\r\n"; args.count = 3; CALL(make_session(&sess, many_serve_string, &args)); ne_hook_create_request(sess, thook_create_req, buf); ne_hook_pre_send(sess, hook_pre_send, buf); ne_hook_post_headers(sess, hook_post_headers, buf); ne_hook_post_send(sess, hook_post_send, buf); ne_hook_destroy_request(sess, hook_destroy_req, buf); ne_hook_destroy_session(sess, hook_destroy_sess, buf); ne_hook_close_conn(sess, hook_close_conn, buf); CALL(any_2xx_request(sess, "/first")); ONCMP("(create,GET,/first)\n" "(pre-send)\n" "(post-headers,HTTP/1.1,200,OK)\n" "(post-send,HTTP/1.1,200,OK)\n" "(destroy-req)\n", buf->data, "hook ordering", "first result"); ne_buffer_clear(buf); /* Unhook for mismatched fn/ud pointers: */ ne_unhook_create_request(sess, hk_createreq, buf); ne_unhook_create_request(sess, thook_create_req, sess); /* Unhook real functions. */ ne_unhook_pre_send(sess, hook_pre_send, buf); ne_unhook_destroy_request(sess, hook_destroy_req, buf); ne_unhook_post_headers(sess, hook_post_headers, buf); CALL(any_2xx_request(sess, "/second")); ONCMP("(create,GET,/second)\n" "(post-send,HTTP/1.1,200,OK)\n", buf->data, "hook ordering", "second result"); ne_buffer_clear(buf); /* Double hook create, double hook then double unhook post. */ ne_hook_create_request(sess, thook_create_req, buf); ne_hook_post_send(sess, hook_post_send, buf); ne_unhook_post_send(sess, hook_post_send, buf); ne_unhook_post_send(sess, hook_post_send, buf); CALL(any_2xx_request(sess, "/third")); ONCMP("(create,GET,/third)\n" "(create,GET,/third)\n", buf->data, "hook ordering", "third result"); ne_buffer_clear(buf); ne_session_destroy(sess); CALL(await_server()); ONCMP("(destroy-sess)\n" "(close-conn)\n", buf->data, "hook ordering", "first destroyed session"); ne_buffer_clear(buf); sess = ne_session_create("http", "www.example.com", 80); ne_hook_destroy_session(sess, hook_destroy_sess, buf); ne_unhook_destroy_session(sess, hook_destroy_sess, buf); ne_session_destroy(sess); ONCMP("", buf->data, "hook ordering", "second destroyed session"); ne_buffer_destroy(buf); return OK; } static void hook_self_destroy_req(ne_request *req, void *userdata) { ne_unhook_destroy_request(ne_get_session(req), hook_self_destroy_req, userdata); } /* Test that it's safe to call ne_unhook_destroy_request from a * destroy_request hook. */ static int hook_self_destroy(void) { ne_session *sess = ne_session_create("http", "localhost", 1234); ne_hook_destroy_request(sess, hook_self_destroy_req, NULL); ne_request_destroy(ne_request_create(sess, "GET", "/")); ne_session_destroy(sess); return OK; } static int icy_protocol(void) { ne_session *sess; CALL(make_session(&sess, single_serve_string, "ICY 200 OK\r\n" "Content-Length: 0\r\n\r\n")); ne_set_session_flag(sess, NE_SESSFLAG_ICYPROTO, 1); ONREQ(any_request(sess, "/foo")); ne_session_destroy(sess); return await_server(); } static void status_cb(void *userdata, ne_session_status status, const ne_session_status_info *info) { ne_buffer *buf = userdata; char scratch[512]; switch (status) { case ne_status_lookup: ne_buffer_concat(buf, "lookup(", info->lu.hostname, ")-", NULL); break; case ne_status_connecting: ne_iaddr_print(info->ci.address, scratch, sizeof scratch); ne_buffer_concat(buf, "connecting(", info->lu.hostname, ",", scratch, ")-", NULL); break; case ne_status_disconnected: ne_buffer_czappend(buf, "dis"); /* fallthrough */ case ne_status_connected: ne_buffer_concat(buf, "connected(", info->cd.hostname, ")-", NULL); break; case ne_status_sending: case ne_status_recving: ne_snprintf(scratch, sizeof scratch, "%" NE_FMT_NE_OFF_T ",%" NE_FMT_NE_OFF_T, info->sr.progress, info->sr.total); ne_buffer_concat(buf, status == ne_status_sending ? "send" : "recv", "(", scratch, ")-", NULL); break; default: ne_buffer_czappend(buf, "bork!"); break; } } static int status(void) { ne_session *sess; ne_buffer *buf = ne_buffer_create(); ne_sock_addr *sa = ne_addr_resolve("localhost", 0); char addr[64], expect[1024]; ONN("could not resolve localhost", ne_addr_result(sa)); ne_snprintf(expect, sizeof expect, "lookup(localhost)-" "connecting(localhost,%s)-" "connected(localhost)-" "send(0,5000)-" "send(5000,5000)-" "recv(0,5)-" "recv(5,5)-" "disconnected(localhost)-", ne_iaddr_print(ne_addr_first(sa), addr, sizeof addr)); ne_addr_destroy(sa); CALL(make_session(&sess, single_serve_string, RESP200 "Content-Length: 5\r\n\r\n" "abcde")); ne_set_notifier(sess, status_cb, buf); CALL(any_2xx_request_body(sess, "/status")); ne_session_destroy(sess); CALL(await_server()); ONV(strcmp(expect, buf->data), ("status event sequence mismatch: got [%s] not [%s]", buf->data, expect)); ne_buffer_destroy(buf); return OK; } static int status_chunked(void) { ne_session *sess; ne_buffer *buf = ne_buffer_create(); ne_sock_addr *sa = ne_addr_resolve("localhost", 0); char addr[64], expect[1024]; ONN("could not resolve localhost", ne_addr_result(sa)); /* This sequence is not exactly guaranteed by the API, but it's * what the current implementation should do. */ ne_snprintf(expect, sizeof expect, "lookup(localhost)-" "connecting(localhost,%s)-" "connected(localhost)-" "send(0,5000)-" "send(5000,5000)-" "recv(0,-1)-" "recv(1,-1)-" "recv(2,-1)-" "recv(3,-1)-" "recv(4,-1)-" "recv(5,-1)-" "disconnected(localhost)-", ne_iaddr_print(ne_addr_first(sa), addr, sizeof addr)); ne_addr_destroy(sa); CALL(make_session(&sess, single_serve_string, RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS)); ne_set_notifier(sess, status_cb, buf); CALL(any_2xx_request_body(sess, "/status")); ne_session_destroy(sess); CALL(await_server()); ONV(strcmp(expect, buf->data), ("status event sequence mismatch: got [%s] not [%s]", buf->data, expect)); ne_buffer_destroy(buf); return OK; } static const unsigned char raw_127[4] = "\x7f\0\0\01"; /* 127.0.0.1 */ static int local_addr(void) { ne_session *sess; ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); CALL(make_session(&sess, single_serve_string, RESP200 "Connection: close\r\n\r\n")); ne_set_localaddr(sess, ia); ONREQ(any_request(sess, "/foo")); ne_session_destroy(sess); ne_iaddr_free(ia); return reap_server(); } /* Regression in 0.27.0, ne_set_progress(sess, NULL, NULL) should * register the progress callback. */ static int dereg_progress(void) { ne_session *sess; CALL(make_session(&sess, single_serve_string, RESP200 TE_CHUNKED "\r\n" ABCDE_CHUNKS)); ne_set_progress(sess, NULL, NULL); ONREQ(any_request(sess, "/foo")); ne_session_destroy(sess); return await_server(); } static int addrlist(void) { ne_session *sess; ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); const ne_inet_addr *ial[1]; sess = ne_session_create("http", "www.example.com", 7777); CALL(spawn_server(7777, single_serve_string, EMPTY_RESP)); ial[0] = ia; ne_set_addrlist(sess, ial, 1); CALL(any_2xx_request(sess, "/blah")); ne_session_destroy(sess); ne_iaddr_free(ia); return await_server(); } static int socks_session(ne_session **sess, struct socks_server *srv, const char *hostname, unsigned int port, server_fn server, void *userdata) { srv->server = server; srv->userdata = userdata; CALL(spawn_server(7777, socks_server, srv)); *sess = ne_session_create("http", hostname, port); ne_session_socks_proxy(*sess, srv->version, "localhost", 7777, srv->username, srv->password); return OK; } static int socks_proxy(void) { ne_session *sess; struct socks_server srv = {0}; srv.version = NE_SOCK_SOCKSV5; srv.failure = fail_none; srv.expect_port = 4242; srv.expect_addr = NULL; srv.expect_fqdn = "socks.example.com"; srv.username = "bloggs"; srv.password = "guessme"; CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port, single_serve_string, EMPTY_RESP)); CALL(any_2xx_request(sess, "/blee")); ne_session_destroy(sess); return await_server(); } static int socks_v4_proxy(void) { ne_session *sess; struct socks_server srv = {0}; srv.version = NE_SOCK_SOCKSV4; srv.failure = fail_none; srv.expect_port = 4242; srv.expect_addr = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4); srv.expect_fqdn = "localhost"; srv.username = "bloggs"; srv.password = "guessme"; CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port, single_serve_string, EMPTY_RESP)); CALL(any_2xx_request(sess, "/blee")); ne_iaddr_free(srv.expect_addr); ne_session_destroy(sess); return await_server(); } /* Server function which serves the request body back as the response * body. */ static int serve_mirror(ne_socket *sock, void *userdata) { char response[1024]; CALL(discard_request(sock)); ONV(clength == 0 || (size_t)clength > sizeof buffer, ("C-L out of bounds: %d", clength)); ONV(ne_sock_fullread(sock, buffer, clength), ("read failed: %s", ne_sock_error(sock))); ne_snprintf(response, sizeof response, "HTTP/1.0 200 OK\r\n" "Content-Length: %d\r\n" "\r\n", clength); ONN("send response header failed", server_send(sock, response, strlen(response))); ONN("send response body failed", server_send(sock, buffer, clength)); ONV(ne_sock_read(sock, buffer, 1) != NE_SOCK_CLOSED, ("client sent data after request: %c", buffer[0])); return OK; } /* Test for ne_set_request_body_fd() bug in <= 0.29.3. */ static int send_length(void) { ne_session *sess; ne_request *req; int fd; ne_buffer *buf = ne_buffer_create(); fd = open("foobar.txt", O_RDONLY); ONV(fd < 0, ("open random.txt failed: %s", strerror(errno))); CALL(make_session(&sess, serve_mirror, NULL)); req = ne_request_create(sess, "GET", "/foo"); ne_set_request_body_fd(req, fd, 0, 3); ne_add_response_body_reader(req, ne_accept_2xx, collector, buf); ONREQ(ne_request_dispatch(req)); ONCMP("foo", buf->data, "response body", "match"); ne_request_destroy(req); ne_session_destroy(sess); close(fd); return await_server(); } /* Test for error code for a SOCKS proxy failure, bug in <= 0.29.3. */ static int socks_fail(void) { ne_session *sess; struct socks_server srv = {0}; int ret; srv.version = NE_SOCK_SOCKSV5; srv.failure = fail_init_vers; srv.expect_port = 4242; srv.expect_addr = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4); srv.expect_fqdn = "localhost"; srv.username = "bloggs"; srv.password = "guessme"; CALL(socks_session(&sess, &srv, srv.expect_fqdn, srv.expect_port, single_serve_string, EMPTY_RESP)); ret = any_request(sess, "/blee"); ONV(ret != NE_ERROR, ("request failed with %d not NE_ERROR", ret)); ONV(strstr(ne_get_error(sess), "Could not establish connection from SOCKS proxy") == NULL || strstr(ne_get_error(sess), "Invalid version in proxy response") == NULL, ("unexpected error string: %s", ne_get_error(sess))); ne_iaddr_free(srv.expect_addr); ne_session_destroy(sess); return await_server(); } /* TODO: test that ne_set_notifier(, NULL, NULL) DTRT too. */ ne_test tests[] = { T(lookup_localhost), T(single_get_clength), T(single_get_eof), T(single_get_chunked), T(no_body_204), T(no_body_304), T(no_body_HEAD), T(no_headers), T(chunks), T(te_header), T(te_identity), T(reason_phrase), T(chunk_numeric), T(chunk_extensions), T(chunk_trailers), T(chunk_oversize), T(te_over_clength), T(te_over_clength2), T(no_body_chunks), T(persist_http11), T(persist_chunked), T(persist_http10), T(persist_proxy_http10), T(persist_timeout), T(no_persist_http10), T(ptimeout_eof), T(ptimeout_eof2), T(closed_connection), T(close_not_retried), T(send_progress), T(ignore_bad_headers), T(fold_headers), T(fold_many_headers), T(multi_header), T(multi_header2), T(empty_header), T(trailing_header), T(ignore_header_case), T(ignore_header_ws), T(ignore_header_ws2), T(ignore_header_ws3), T(ignore_header_tabs), T(strip_http10_connhdr), T(strip_http10_connhdr2), T(continued_header), T(reset_headers), T(iterate_none), T(iterate_many), T(skip_interim_1xx), T(skip_many_1xx), T(skip_1xx_hdrs), T(send_bodies), T(expect_100_once), T(expect_100_nobody), T(unbounded_headers), T(unbounded_folding), T(blank_response), T(not_http), T(fail_eof_continued), T(fail_eof_headers), T(fail_eof_chunk), T(fail_eof_badclen), T(fail_long_header), T(fail_on_invalid), T(read_timeout), T(fail_lookup), T(fail_double_lookup), T(fail_connect), T(proxy_no_resolve), T(fail_chunksize), T(abort_respbody), T(retry_after_abort), T(fail_statusline), T(dup_method), T(versions), T(hook_create_req), T(abort_reader), T(send_bad_offset), T(hooks), T(hook_self_destroy), T(icy_protocol), T(status), T(status_chunked), T(local_addr), T(dereg_progress), T(addrlist), T(socks_proxy), T(socks_v4_proxy), T(send_length), T(socks_fail), T(NULL) }; davix-R_0_5_0/deps/libneon/test/resolve.c000066400000000000000000000031251257152637300204510ustar00rootroot00000000000000/* Test program for the neon resolver interface Copyright (C) 2002-2003, Joe Orton 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 "config.h" #include #include "ne_socket.h" int main(int argc, char **argv) { ne_sock_addr *addr; char buf[256]; int ret = 0; if (argc < 2) { printf("Usage: %s hostname\n", argv[0]); return 1; } if (ne_sock_init()) { printf("%s: Failed to initialize socket library.\n", argv[0]); return 1; } addr = ne_addr_resolve(argv[1], 0); if (ne_addr_result(addr)) { printf("Could not resolve `%s': %s\n", argv[1], ne_addr_error(addr, buf, sizeof buf)); ret = 2; } else { const ne_inet_addr *ia; printf("Resolved `%s' OK:", argv[1]); for (ia = ne_addr_first(addr); ia; ia = ne_addr_next(addr)) { printf(" <%s>", ne_iaddr_print(ia, buf, sizeof buf)); } putchar('\n'); } ne_addr_destroy(addr); return ret; } davix-R_0_5_0/deps/libneon/test/run-tests.sh000066400000000000000000000010771257152637300211320ustar00rootroot00000000000000#!/bin/sh # # This script can be used to run the installed neon test suite # against an installed copy of the neon library. # # enable glibc malloc safety checks MALLOC_CHECK_=2 export MALLOC_CHECK_ cd data if test -x ../bin/ssl; then rm -rf ca echo "INIT: generating SSL ceritifcates..." if sh ./makekeys.sh 2> makekeys.out; then :; else echo FAIL: could not generate SSL certificates exit 2 fi fi for t in ../bin/*; do if ${t}; then :; else echo FAIL: ${t} exit 1 fi done echo "PASS: all tests passed" exit 0 davix-R_0_5_0/deps/libneon/test/run.sh000066400000000000000000000006461257152637300177730ustar00rootroot00000000000000#!/bin/sh rm -f debug.log child.log ulimit -c unlimited ulimit -t 120 unset LANG unset LC_MESSAGES # Enable glibc heap consistency checks, and memory randomization. MALLOC_CHECK_=2 MALLOC_PERTURB_=`expr $RANDOM % 255 2>/dev/null` export MALLOC_CHECK_ MALLOC_PERTURB_ export TEST_QUIET=${TEST_QUIET:-1} RETVAL=0 for f in $*; do if ${HARNESS} ./$f ${SRCDIR}; then : else RETVAL=$? fi done exit $RETVAL davix-R_0_5_0/deps/libneon/test/server.key000066400000000000000000000007611257152637300206510ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIBOwIBAAJBAPNFTmxnz4JZA+8+SonD0qWgSBPYWrNlH1FP+psm5EGZGmGJGvSD sk6HkyvstdopKF50UuEaJ263IorAhkmdGG0CAwEAAQJAJBhYdoVAqNqEVu8rKB3C F4kcqLUlYBDVAL+ZM4QlwgWncAKk2C53BwH4PVWIIfyysleyt3bTAtqg/tgMNM06 AQIhAP1HKbuppa+UY4rNP4Xcyj5BrCU4wVz77sg/ygW+mWIhAiEA9eKcUnnaIpig hlWtx9qz++85/JtahA85j6T48v0hBM0CIQCa8ByUg2wq45CdSX+xiOZjfVMslfKb yjZBY9xW9UjpYQIgdy9j5JqKANEIpnTran95VLot2mMXagHTPeySe331PlUCIQD0 rL1AXeIR3Vd4D8dgab/FVbg4i94qBiY0731nyPJRoQ== -----END RSA PRIVATE KEY----- davix-R_0_5_0/deps/libneon/test/session.c000066400000000000000000000116771257152637300204700ustar00rootroot00000000000000/* Tests for session handling Copyright (C) 2002-2006, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_session.h" #include "tests.h" static int fill_uri(void) { ne_uri uri = {0}; ne_session *sess = ne_session_create("http", "localhost", 7777); ne_fill_server_uri(sess, &uri); ONCMP("localhost", uri.host, "fill_uri", "host"); ONN("port mis-match", uri.port != 7777); ONCMP("http", uri.scheme, "fill_uri", "scheme"); ne_session_destroy(sess); ne_uri_free(&uri); return OK; } static int fill_proxy_uri(void) { ne_uri uri = {0}; ne_session *sess = ne_session_create("http", "localhost", 7777); ne_fill_proxy_uri(sess, &uri); ONN("no proxy host should be set", uri.host != NULL); ONN("no proxy port should be set", uri.port != 0); ne_session_proxy(sess, "www.example.com", 345); ne_fill_proxy_uri(sess, &uri); ONCMP("www.example.com", uri.host, "fill_proxy_uri", "host"); ONN("proxy port mis-match", uri.port != 345); ne_session_destroy(sess); ne_uri_free(&uri); return OK; } static int match_hostport(const char *scheme, const char *hostname, int port, const char *hostport) { ne_session *sess = ne_session_create(scheme, hostname, port); const char *hp = ne_get_server_hostport(sess); ONV(strcmp(hp, hostport), ("hostport incorrect for %s: `%s' not `%s'", scheme, hp, hostport)); ne_session_destroy(sess); return OK; } static int hostports(void) { static const struct { const char *scheme, *hostname; int port; const char *hostport; } hps[] = { { "http", "host.name", 80, "host.name" }, { "http", "host.name", 555, "host.name:555" }, { "http", "host.name", 443, "host.name:443" }, { "https", "host.name", 80, "host.name:80" }, { "https", "host.name", 443, "host.name" }, { "https", "host.name", 700, "host.name:700" }, { NULL } }; int n; for (n = 0; hps[n].scheme; n++) { CALL(match_hostport(hps[n].scheme, hps[n].hostname, hps[n].port, hps[n].hostport)); } return OK; } /* Check that ne_set_error is passing through to printf correctly. */ static int errors(void) { ne_session *sess = ne_session_create("http", "foo.com", 80); #define EXPECT "foo, hello world, 100, bar!" ne_set_error(sess, "foo, %s, %d, bar!", "hello world", 100); ONV(strcmp(ne_get_error(sess), EXPECT), ("session error was `%s' not `%s'", ne_get_error(sess), EXPECT)); #undef EXPECT ne_session_destroy(sess); return OK; } #define ID1 "foo" #define ID2 "bar" static int privates(void) { ne_session *sess = ne_session_create("http", "localhost", 80); char *v1 = "hello", *v2 = "world"; ne_set_session_private(sess, ID1, v1); ne_set_session_private(sess, ID2, v2); #define PRIV(msg, id, val) \ ONN(msg, ne_get_session_private(sess, id) != val) PRIV("private #1 wrong", ID1, v1); PRIV("private #2 wrong", ID2, v2); PRIV("unknown id wrong", "no such ID", NULL); ne_session_destroy(sess); return OK; } /* test that ne_session_create doesn't really care what scheme you * give it, and that ne_get_scheme() works. */ static int get_scheme(void) { static const char *schemes[] = { "http", "https", "ftp", "ldap", "foobar", NULL }; int n; for (n = 0; schemes[n]; n++) { ne_session *sess = ne_session_create(schemes[n], "localhost", 80); ONV(strcmp(ne_get_scheme(sess), schemes[n]), ("scheme was `%s' not `%s'!", ne_get_scheme(sess), schemes[n])); ne_session_destroy(sess); } return OK; } static int flags(void) { ne_session *sess = ne_session_create("https", "localhost", 443); ne_set_session_flag(sess, NE_SESSFLAG_PERSIST, 1); ONN("persist flag was not set", ne_get_session_flag(sess, NE_SESSFLAG_PERSIST) != 1); ne_set_session_flag(sess, NE_SESSFLAG_LAST, 1); ONN("unsupported flag was recognized", ne_get_session_flag(sess, NE_SESSFLAG_LAST) != -1); ne_session_destroy(sess); return OK; } ne_test tests[] = { T(fill_uri), T(fill_proxy_uri), T(hostports), T(errors), T(privates), T(get_scheme), T(flags), T(NULL) }; davix-R_0_5_0/deps/libneon/test/skeleton.c000066400000000000000000000023151257152637300206160ustar00rootroot00000000000000/* neon test suite Copyright (C) 2002-2003, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_request.h" #include "ne_socket.h" #include "tests.h" #include "child.h" #include "utils.h" static int foo(void) { /* This is a skeleton test suite file. */ return OK; } ne_test tests[] = { T(foo), /* test functions here */ /* end of test functions. */ T(NULL) }; davix-R_0_5_0/deps/libneon/test/socket.c000066400000000000000000001117301257152637300202640ustar00rootroot00000000000000/* Socket handling tests Copyright (C) 2002-2009, Joe Orton 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. */ /* This module can be compiled with -DSOCKET_SSL enabled, to run all * the tests over an SSL connection. */ #include "config.h" #include #include /* for AF_INET6 */ #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include /* for gethostname() */ #endif #include /* for time() */ #include "ne_socket.h" #include "ne_utils.h" #include "ne_alloc.h" #include "child.h" #include "tests.h" #include "utils.h" #ifdef SOCKET_SSL #include "ne_ssl.h" ne_ssl_context *server_ctx, *client_ctx; #endif static ne_sock_addr *localhost; static char buffer[BUFSIZ]; #if defined(AF_INET6) && defined(USE_GETADDRINFO) #define TEST_IPV6 #endif /* tests for doing init/finish multiple times. */ static int multi_init(void) { int res1 = ne_sock_init(), res2 = ne_sock_init(); ONV(res1 != res2, ("cached init result changed from %d to %d", res1, res2)); ne_sock_exit(); ne_sock_exit(); ne_sock_exit(); res1 = ne_sock_init(); ONV(res1 != res2, ("re-init after exit gave %d not %d", res1, res2)); ne_sock_exit(); res2 = ne_sock_init(); ONV(res1 != res2, ("second time, cached init result changed from %d to %d", res1, res2)); return OK; } /* Create and connect *sock to address addr on given port. */ static int do_connect(ne_socket **sock, ne_sock_addr *addr, unsigned int port) { const ne_inet_addr *ia; *sock = ne_sock_create(); ONN("could not create socket", *sock == NULL); for (ia = ne_addr_first(addr); ia; ia = ne_addr_next(addr)) { if (ne_sock_connect(*sock, ia, port) == 0) return OK; } t_context("could not connect to server: %s", ne_sock_error(*sock)); ne_sock_close(*sock); return FAIL; } #ifdef SOCKET_SSL static int init_ssl(void) { char *server_key; ne_ssl_certificate *cert; /* take srcdir as argv[1]. */ if (test_argc > 1) { server_key = ne_concat(test_argv[1], "/server.key", NULL); } else { server_key = ne_strdup("server.key"); } ONN("sock_init failed", ne_sock_init()); server_ctx = ne_ssl_context_create(1); ONN("SSL_CTX_new failed", server_ctx == NULL); ne_ssl_context_keypair(server_ctx, "server.cert", server_key); client_ctx = ne_ssl_context_create(0); ONN("SSL_CTX_new failed for client", client_ctx == NULL); cert = ne_ssl_cert_read("ca/cert.pem"); ONN("could not load ca/cert.pem", cert == NULL); ne_ssl_context_trustcert(client_ctx, cert); ne_free(server_key); return OK; } #endif static int resolve(void) { char buf[256]; localhost = ne_addr_resolve("localhost", 0); ONV(ne_addr_result(localhost), ("could not resolve `localhost': %s", ne_addr_error(localhost, buf, sizeof buf))); /* and again for child.c */ return lookup_localhost(); } static int serve_close(ne_socket *sock, void *ud) { return 0; } #ifdef SOCKET_SSL struct serve_pair { server_fn fn; void *userdata; }; static int wrap_serve(ne_socket *sock, void *ud) { struct serve_pair *pair = ud; if (ne_sock_accept_ssl(sock, server_ctx)) { NE_DEBUG(NE_DBG_SOCKET, "SSL_accept failed: %s\n", ne_sock_error(sock)); return 1; } NE_DEBUG(NE_DBG_SOCKET, "SSL accept okay.\n"); return pair->fn(sock, pair->userdata); } static int begin(ne_socket **sock, server_fn fn, void *ud) { struct serve_pair pair; pair.fn = fn; pair.userdata = ud; CALL(spawn_server(7777, wrap_serve, &pair)); CALL(do_connect(sock, localhost, 7777)); ONV(ne_sock_connect_ssl(*sock, client_ctx, NULL), ("SSL negotation failed: %s", ne_sock_error(*sock))); return OK; } #else /* non-SSL begin() function. */ static int begin(ne_socket **sock, server_fn fn, void *ud) { CALL(spawn_server(7777, fn, ud)); return do_connect(sock, localhost, 7777); } #endif static int resolve_numeric(void) { ne_sock_addr *addr = ne_addr_resolve("127.0.0.1", 0); ONV(ne_addr_result(addr), ("failed to resolve 127.0.0.1: %s", ne_addr_error(addr, buffer, sizeof buffer))); ONN("ne_addr_first returned NULL", ne_addr_first(addr) == NULL); ONN("ne_iaddr_print didn't return buffer", ne_iaddr_print(ne_addr_first(addr), buffer, sizeof buffer) != buffer); ONV(strcmp(buffer, "127.0.0.1"), ("ntop gave `%s' not 127.0.0.1", buffer)); ne_addr_destroy(addr); return OK; } #if 0 static int resolve_ipv6(void) { char err[256]; ne_sock_addr *addr = ne_addr_resolve("[::1]", 0); ONV(ne_addr_result(addr), ("could not resolve `[::1]': %s", ne_addr_error(addr, err, sizeof err))); ne_addr_destroy(addr); return OK; } #endif static const unsigned char raw_127[4] = "\x7f\0\0\01", /* 127.0.0.1 */ raw6_nuls[16] = /* :: */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; #ifdef TEST_IPV6 static const unsigned char raw6_local[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", raw6_cafe[16] = /* feed::cafe */ "\xfe\xed\0\0\0\0\0\0\0\0\0\0\0\0\xca\xfe", raw6_babe[16] = /* cafe:babe:: */ "\xca\xfe\xba\xbe\0\0\0\0\0\0\0\0\0\0\0\0"; #endif /* Check the given inet addr is 127.0.0.1. */ static int check_is_raw127(const ne_inet_addr *ia) { unsigned char raw[5]; raw[4] = 'Z'; ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv4); ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); ONN("raw address mismatch", memcmp(raw, raw_127, 4) != 0); ONN("ne_iaddr_raw buffer overflow", raw[4] != 'Z'); return OK; } static int addr_make_v4(void) { ne_inet_addr *ia; char pr[50]; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); ne_iaddr_print(ia, pr, sizeof pr); ONV(strcmp(pr, "127.0.0.1"), ("address was %s not 127.0.0.1", pr)); CALL(check_is_raw127(ia)); ne_iaddr_free(ia); return OK; } static int parse_v4(void) { ne_inet_addr *ia; ia = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4); ONN("parse failed", ia == NULL); CALL(check_is_raw127(ia)); ne_iaddr_free(ia); return OK; } static int addr_make_v6(void) { #ifdef TEST_IPV6 struct { const unsigned char *addr; const char *rep; } as[] = { { raw6_cafe, "feed::cafe" }, { raw6_babe, "cafe:babe::" }, { raw6_nuls, "::" }, { NULL, NULL } }; int n; for (n = 0; as[n].rep != NULL; n++) { ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv6, as[n].addr); char pr[128]; unsigned char raw[17]; ONV(ia == NULL, ("could not make address for '%s'", as[n].rep)); ne_iaddr_print(ia, pr, sizeof pr); ONV(strcmp(pr, as[n].rep), ("address %d was '%s' not '%s'", n, pr, as[n].rep)); ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv6); raw[16] = 'Z'; ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); ONN("raw address mismatch", memcmp(raw, as[n].addr, 4) != 0); ONN("ne_iaddr_raw buffer overflow", raw[16] != 'Z'); ne_iaddr_free(ia); ia = ne_iaddr_parse(as[n].rep, ne_iaddr_ipv6); ONV(ia == NULL, ("ne_iaddr_parse failed for %s", as[n].rep)); ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv6); ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); ONN("raw address mismatch", memcmp(raw, as[n].addr, 4) != 0); ONN("ne_iaddr_raw buffer overflow", raw[16] != 'Z'); ne_iaddr_free(ia); } return OK; #else /* should fail when lacking IPv6 support. */ ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv6, raw6_nuls); ONN("ne_iaddr_make did not return NULL", ia != NULL); ONN("ne_iaddr_parse did not return NULL", ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv6)); #endif return OK; } static const unsigned char raw_1234[] = "\x01\x02\x03\x04"; static int addr_compare(void) { ne_inet_addr *ia1, *ia2; int ret; ia1 = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ia2 = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("addr_make returned NULL", !ia1 || !ia2); ret = ne_iaddr_cmp(ia1, ia2); ONV(ret != 0, ("comparison of equal IPv4 addresses was %d", ret)); ne_iaddr_free(ia2); ia2 = ne_iaddr_make(ne_iaddr_ipv4, raw_1234); ret = ne_iaddr_cmp(ia1, ia2); ONN("comparison of unequal IPv4 addresses was zero", ret == 0); #ifdef TEST_IPV6 ne_iaddr_free(ia2); ia2 = ne_iaddr_make(ne_iaddr_ipv6, raw6_cafe); ONN("could not make IPv6 address", !ia2); ret = ne_iaddr_cmp(ia1, ia2); ONN("comparison of IPv4 and IPv6 addresses was zero", ret == 0); ne_iaddr_free(ia1); ia1 = ne_iaddr_make(ne_iaddr_ipv6, raw6_cafe); ret = ne_iaddr_cmp(ia1, ia2); ONN("comparison of equal IPv6 addresses was not zero", ret != 0); ne_iaddr_free(ia1); ia1 = ne_iaddr_make(ne_iaddr_ipv6, raw6_babe); ret = ne_iaddr_cmp(ia1, ia2); ONN("comparison of unequal IPv6 address was zero", ret == 0); #endif ne_iaddr_free(ia1); ne_iaddr_free(ia2); return OK; } static int addr_reverse(void) { ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); char buf[128], *syshost = NULL; #ifdef HAVE_GETHOSTNAME char host[128]; if (gethostname(host, sizeof host) == 0) { syshost = host; } #endif ONN("ne_iaddr_make returned NULL", ia == NULL); ONN("reverse lookup for 127.0.0.1 failed", ne_iaddr_reverse(ia, buf, sizeof buf) != 0); ONV(!(strcmp(buf, "localhost.localdomain") == 0 || strcmp(buf, "localhost") == 0 || (syshost && strcmp(buf, syshost) == 0)), ("reverse lookup for 127.0.0.1 got %s", buf)); ne_iaddr_free(ia); return OK; } static int just_connect(void) { ne_socket *sock; CALL(begin(&sock, serve_close, NULL)); ne_sock_close(sock); return await_server(); } /* Connect to an address crafted using ne_iaddr_make rather than from * the resolver. */ static int addr_connect(void) { ne_socket *sock = ne_sock_create(); ne_inet_addr *ia; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); CALL(spawn_server(7777, serve_close, NULL)); ONN("could not connect", ne_sock_connect(sock, ia, 7777)); ne_sock_close(sock); CALL(await_server()); ne_iaddr_free(ia); return OK; } static int addr_peer(void) { ne_socket *sock = ne_sock_create(); ne_inet_addr *ia, *ia2; unsigned int port = 9999; int ret; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); CALL(spawn_server(7777, serve_close, NULL)); ONN("could not connect", ne_sock_connect(sock, ia, 7777)); ia2 = ne_sock_peer(sock, &port); ret = ne_iaddr_cmp(ia, ia2); ONV(ret != 0, ("comparison of peer with server address was %d", ret)); ONV(port != 7777, ("got peer port %u", port)); ne_sock_close(sock); CALL(await_server()); ne_iaddr_free(ia); ne_iaddr_free(ia2); return OK; } /* Exect a read() to return EOF */ static int expect_close(ne_socket *sock) { ssize_t n = ne_sock_read(sock, buffer, 1); ONV(n > 0, ("read got %" NE_FMT_SSIZE_T " bytes not closure", n)); ONV(n < 0 && n != NE_SOCK_CLOSED, ("read got error not closure: `%s'", ne_sock_error(sock))); return OK; } static int good_close(ne_socket *sock) { NE_DEBUG(NE_DBG_SOCKET, "Socket error was %s\n", ne_sock_error(sock)); ONN("close failed", ne_sock_close(sock)); return OK; } /* Finish a test, closing socket and rejoining child. If eof is non-zero, * expects to read EOF from the socket before closing. */ static int finish(ne_socket *sock, int eof) { if (eof) CALL(expect_close(sock)); CALL(good_close(sock)); return await_server(); } /* Exect a ne_sock_peek() to return EOF */ static int expect_peek_close(ne_socket *sock) { ssize_t n = ne_sock_read(sock, buffer, 1); ONV(n != NE_SOCK_CLOSED, ("peek gave %" NE_FMT_SSIZE_T " not closure", n)); return OK; } /* Test that just does a connect then a close. */ static int read_close(void) { ne_socket *sock; CALL(begin(&sock, serve_close, NULL)); CALL(expect_close(sock)); ONN("close failed", ne_sock_close(sock)); return await_server(); } /* Test that just does a connect then a close (but gets the close via * ne_sock_peek). */ static int peek_close(void) { ne_socket *sock; CALL(begin(&sock, serve_close, NULL)); CALL(expect_peek_close(sock)); ONN("close failed", ne_sock_close(sock)); return await_server(); } /* Don't change this string. */ #define STR "Hello, World." /* do a sock_peek() on sock for 'len' bytes, and expect 'str'. */ static int peek_expect(ne_socket *sock, const char *str, size_t len) { ssize_t ret; memset(buffer, '@', sizeof buffer); ret = ne_sock_peek(sock, buffer, len); ONV((ssize_t)len != ret, ("peek got %" NE_FMT_SSIZE_T " bytes not %" NE_FMT_SIZE_T, ret, len)); ONV(memcmp(str, buffer, len), ("peek mismatch: `%.*s' not `%.*s'", (int)len, buffer, (int)len, str)); ONV(buffer[len] != '@', ("buffer overrun: %" NE_FMT_SSIZE_T "nth byte was '%c' not '@'", len, buffer[len])); return OK; } /* do a sock_read() on sock for 'len' bytes, and expect 'str'. */ static int read_expect(ne_socket *sock, const char *str, size_t len) { ssize_t ret = ne_sock_read(sock, buffer, len); ONV((ssize_t)len != ret, ("read got %" NE_FMT_SSIZE_T " bytes not %" NE_FMT_SIZE_T, ret, len)); ONV(memcmp(str, buffer, len), ("read mismatch: `%.*s' not `%.*s'", (int)len, buffer, (int)len, str)); return OK; } /* do a sock_read() on sock for 'len' bytes, and expect 'str'. */ static int fullread_expect(ne_socket *sock, const char *str, size_t len) { ssize_t ret = ne_sock_fullread(sock, buffer, len); ONV(ret, ("fullread failed (%" NE_FMT_SSIZE_T "): %s", ret, ne_sock_error(sock))); ONV(memcmp(str, buffer, len), ("fullread mismatch: `%.*s' not `%.*s'", (int)len, buffer, (int)len, str)); return OK; } #define FULLREAD(str) CALL(fullread_expect(sock, str, strlen(str))) /* Declare a struct string */ #define DECL(var,str) struct string var = { str, 0 }; var.len = strlen(str) #define DECL_LONG(var,ch,n) struct string var; var.data = memset(ne_malloc(n), ch, n); var.len = n; /* Test a simple read. */ static int single_read(void) { ne_socket *sock; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); CALL(read_expect(sock, STR, strlen(STR))); CALL(expect_close(sock)); CALL(good_close(sock)); return await_server(); } /* Test a simple peek. */ static int single_peek(void) { ne_socket *sock; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); CALL(peek_expect(sock, STR, strlen(STR))); return finish(sock, 0); } /* Test lots of 1-byte reads. */ static int small_reads(void) { ne_socket *sock; char *pnt; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); /* read the string byte-by-byte. */ for (pnt = hello.data; *pnt; pnt++) { CALL(read_expect(sock, pnt, 1)); } return finish(sock, 1); } /* peek or read, expecting to get given string. */ #define READ(str) CALL(read_expect(sock, str, strlen(str))) #define PEEK(str) CALL(peek_expect(sock, str, strlen(str))) /* Stress out the read buffer handling a little. */ static int read_and_peek(void) { ne_socket *sock; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); PEEK("Hello"); PEEK("Hell"); PEEK(STR); READ("He"); PEEK("llo, "); READ("l"); PEEK("lo, World."); READ("lo, Worl"); PEEK("d."); PEEK("d"); READ("d."); return finish(sock, 1); } /* Read more bytes than were written. */ static int larger_read(void) { ne_socket *sock; ssize_t nb; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); nb = ne_sock_read(sock, buffer, hello.len + 10); ONV(nb != (ssize_t)hello.len, ("read gave too many bytes (%" NE_FMT_SSIZE_T ")", nb)); ONN("read gave wrong data", memcmp(buffer, hello.data, hello.len)); return finish(sock, 1); } static int line_expect(ne_socket *sock, const char *line) { ssize_t ret = ne_sock_readline(sock, buffer, BUFSIZ); size_t len = strlen(line); NE_DEBUG(NE_DBG_SOCKET, " -> expected=%s -> actual=%s", line, buffer); ONV(ret == NE_SOCK_CLOSED, ("socket closed, expecting `%s'", line)); ONV(ret < 0, ("socket error `%s', expecting `%s'", ne_sock_error(sock), line)); ONV((size_t)ret != len || strcmp(line, buffer), ("readline mismatch: `%s' not `%s'", buffer, line)); return OK; } #define LINE(x) CALL(line_expect(sock, x)) #define STR2 "Goodbye, cruel world." static int line_simple(void) { ne_socket *sock; DECL(oneline, STR "\n" STR2 "\n"); CALL(begin(&sock, serve_sstring, &oneline)); LINE(STR "\n"); LINE(STR2 "\n"); return finish(sock, 1); } static int line_closure(void) { ne_socket *sock; ssize_t ret; DECL(oneline, STR "\n" "foobar"); CALL(begin(&sock, serve_sstring, &oneline)); LINE(STR "\n"); ret = ne_sock_readline(sock, buffer, BUFSIZ); ONV(ret != NE_SOCK_CLOSED, ("readline got %" NE_FMT_SSIZE_T " not EOF: %s", ret, ne_sock_error(sock))); return finish(sock, 0); } /* check that empty lines are handled correctly. */ static int line_empty(void) { ne_socket *sock; DECL(oneline, "\n\na\n\n"); CALL(begin(&sock, serve_sstring, &oneline)); LINE("\n"); LINE("\n"); LINE("a\n"); LINE("\n"); return finish(sock, 1); } static int line_toolong(void) { ne_socket *sock; ssize_t ret; DECL(oneline, "AAAAAA\n"); CALL(begin(&sock, serve_sstring, &oneline)); ret = ne_sock_readline(sock, buffer, 5); ONV(ret != NE_SOCK_ERROR, ("readline should fail on long line: %" NE_FMT_SSIZE_T, ret)); reap_server(); ne_sock_close(sock); return OK; } #define OVERLEN (9000) static int line_overflow(void) { ne_socket *sock; ssize_t ret; DECL_LONG(line, 'A', OVERLEN); CALL(begin(&sock, serve_sstring, &line)); PEEK("A"); /* fill the read buffer */ ret = ne_sock_readline(sock, buffer, OVERLEN); ONV(ret != NE_SOCK_ERROR, ("readline should fail on overlong line: %" NE_FMT_SSIZE_T, ret)); ne_free(line.data); return finish(sock, 0); } /* readline()s mingled with other operations: buffering tests. */ static int line_mingle(void) { ne_socket *sock; DECL(oneline, "alpha\nbeta\ndelta\ngamma\n"); CALL(begin(&sock, serve_sstring, &oneline)); READ("a"); LINE("lpha\n"); READ("beta"); LINE("\n"); PEEK("d"); PEEK("delt"); LINE("delta\n"); READ("gam"); LINE("ma\n"); return finish(sock, 1); } /* readline which needs multiple read() calls. */ static int line_chunked(void) { ne_socket *sock; DECL(oneline, "this is a line\n"); CALL(begin(&sock, serve_sstring_slowly, &oneline)); LINE("this is a line\n"); return finish(sock, 1); } static int line_long_chunked(void) { ne_socket *sock; ssize_t ret; DECL_LONG(line, 'Z', OVERLEN); CALL(begin(&sock, serve_sstring_slowly, &line)); FULLREAD("ZZZZZZZZ"); /* fill the buffer */ ret = ne_sock_readline(sock, buffer, sizeof buffer); ONV(ret != NE_SOCK_ERROR, ("readline gave %" NE_FMT_SSIZE_T " not failure", ret)); reap_server(); ne_sock_close(sock); ne_free(line.data); return OK; } static time_t to_start, to_finish; static int to_begin(ne_socket **sock) { CALL(begin(sock, sleepy_server, NULL)); ne_sock_read_timeout(*sock, 1); to_start = time(NULL); return OK; } static int to_end(ne_socket *sock) { to_finish = time(NULL); reap_server(); /* hopefully it's hung. */ ONN("timeout ignored, or very slow machine", to_finish - to_start > 3); ONN("close failed", ne_sock_close(sock)); return OK; } #define TO_BEGIN ne_socket *sock; CALL(to_begin(&sock)) #define TO_OP(x) do { int to_ret = (x); \ ONV(to_ret != NE_SOCK_TIMEOUT, ("operation did not timeout: got %d (%s)", to_ret, ne_sock_error(sock))); \ } while (0) #define TO_FINISH return to_end(sock) #ifndef TEST_CONNECT_TIMEOUT #define TEST_CONNECT_TIMEOUT 0 #endif #if TEST_CONNECT_TIMEOUT /* No obvious way to reliably test a connect() timeout. But * www.example.com seems to drop packets on ports other than 80 so * that actually works pretty well. Disabled by default. */ static int connect_timeout(void) { static const unsigned char example_dot_com[] = "\xC0\x00\x22\xA6"; ne_socket *sock = ne_sock_create(); ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv4, example_dot_com); ne_sock_connect_timeout(sock, 1); TO_OP(ne_sock_connect(sock, ia, 8080)); ne_iaddr_free(ia); ne_sock_close(sock); return OK; } #endif static int peek_timeout(void) { TO_BEGIN; TO_OP(ne_sock_peek(sock, buffer, 1)); TO_FINISH; } static int read_timeout(void) { TO_BEGIN; TO_OP(ne_sock_read(sock, buffer, 1)); TO_FINISH; } static int readline_timeout(void) { TO_BEGIN; TO_OP(ne_sock_readline(sock, buffer, 1)); TO_FINISH; } static int fullread_timeout(void) { TO_BEGIN; TO_OP(ne_sock_fullread(sock, buffer, 1)); TO_FINISH; } static int serve_expect(ne_socket *sock, void *ud) { struct string *str = ud; ssize_t ret; while (str->len && (ret = ne_sock_read(sock, buffer, sizeof(buffer))) > 0) { NE_DEBUG(NE_DBG_SOCKET, "Got %" NE_FMT_SSIZE_T " bytes.\n", ret); ONV(memcmp(str->data, buffer, ret), ("unexpected data: [%.*s] not [%.*s]", (int)ret, buffer, (int)ret, str->data)); str->data += ret; str->len -= ret; NE_DEBUG(NE_DBG_SOCKET, "%" NE_FMT_SIZE_T " bytes left.\n", str->len); } NE_DEBUG(NE_DBG_SOCKET, "All data read.\n"); return OK; } #define WRITEL(str) CALL(full_write(sock, str, strlen(str))); \ minisleep() static int small_writes(void) { ne_socket *sock; DECL(str, "This\nIs\nSome\nText.\n"); CALL(begin(&sock, serve_expect, &str)); WRITEL("This\n"); WRITEL("Is\n"); WRITEL("Some\n"); WRITEL("Text.\n"); return finish(sock, 1); } static int large_writes(void) { #define LARGE_SIZE (123456) struct string str; ne_socket *sock; ssize_t n; str.data = ne_malloc(LARGE_SIZE); str.len = LARGE_SIZE; for (n = 0; n < LARGE_SIZE; n++) str.data[n] = 41 + n % 130; CALL(begin(&sock, serve_expect, &str)); CALL(full_write(sock, str.data, str.len)); ne_free(str.data); return finish(sock, 1); } static int full_writev(ne_socket *sock, struct ne_iovec *vec, int count) { int ret = ne_sock_fullwritev(sock, vec, count); NE_DEBUG(NE_DBG_SOCKET, "wrote vector (%d)\n", count); ONV(ret, ("writev failed (%d): %s", ret, ne_sock_error(sock))); return OK; } #undef LARGE_SIZE #define LARGE_SIZE (123456 * 4) static int large_writev(void) { struct string str; ne_socket *sock; ssize_t n; struct ne_iovec vec[4]; str.data = ne_malloc(LARGE_SIZE); str.len = LARGE_SIZE; for (n = 0; n < LARGE_SIZE; n++) str.data[n] = 41 + n % 130; for (n = 0; n < 4; n++) { vec[n].base = str.data + n * LARGE_SIZE / 4; vec[n].len = LARGE_SIZE / 4; } CALL(begin(&sock, serve_expect, &str)); CALL(full_writev(sock, vec, 4)); ne_free(str.data); return finish(sock, 1); } /* echoes back lines. */ static int echo_server(ne_socket *sock, void *ud) { ssize_t ret; while ((ret = ne_sock_readline(sock, buffer, sizeof(buffer))) > 0) { NE_DEBUG(NE_DBG_SOCKET, "Line: %s", buffer); ONN("write failed", ne_sock_fullwrite(sock, buffer, ret)); NE_DEBUG(NE_DBG_SOCKET, "Wrote line.\n"); } ONN("readline failed", ret != NE_SOCK_CLOSED); return 0; } static int echo_expect(ne_socket *sock, const char *line) { CALL(full_write(sock, line, strlen(line))); return line_expect(sock, line); } #define ECHO(line) CALL(echo_expect(sock, line)) static int echo_lines(void) { ne_socket *sock; CALL(begin(&sock, echo_server, NULL)); ECHO("hello,\n"); ECHO("\n"); ECHO("world\n"); return finish(sock, 0); } #ifdef SOCKET_SSL /* harder to simulate closure cases for an SSL connection, since it * may be doing multiple read()s or write()s per ne_sock_* call. */ static int ssl_closure(void) { ne_socket *sock; ssize_t ret; CALL(begin(&sock, serve_close, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); do { ret = ne_sock_fullwrite(sock, "a", 1); } while (ret == 0); ONV(ret != NE_SOCK_RESET && ret != NE_SOCK_CLOSED, ("write got %" NE_FMT_SSIZE_T " not reset or closure: %s", ret, ne_sock_error(sock))); return good_close(sock); } static int serve_truncate(ne_socket *sock, void *userdata) { exit(0); } /* when an EOF is received without a clean shutdown (close_notify message). */ static int ssl_truncate(void) { ne_socket *sock; int ret; CALL(begin(&sock, serve_truncate, NULL)); ret = ne_sock_read(sock, buffer, 1); ONV(ret != NE_SOCK_TRUNC, ("socket got error %d not truncation: `%s'", ret, ne_sock_error(sock))); return finish(sock, 0); } #else /* use W Richard Stevens' SO_LINGER trick to elicit a TCP RST */ static int serve_reset(ne_socket *sock, void *ud) { minisleep(); reset_socket(sock); exit(0); return 0; } static int write_reset(void) { ne_socket *sock; int ret; CALL(begin(&sock, serve_reset, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_fullwrite(sock, "a", 1); if (ret == 0) { ne_sock_close(sock); return SKIP; } if (ret == NE_SOCK_CLOSED) { t_warning("got EOF, failed to elicit TCP RST"); } else { ONV(ret != NE_SOCK_RESET, ("write got %d not reset: %s", ret, ne_sock_error(sock))); } return good_close(sock); } static int read_reset(void) { ne_socket *sock; ssize_t ret; CALL(begin(&sock, serve_reset, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_read(sock, buffer, 1); if (ret == NE_SOCK_CLOSED) { ne_sock_close(sock); return SKIP; } ONV(ret != NE_SOCK_RESET, ("read got %" NE_FMT_SSIZE_T " not reset: %s", ret, ne_sock_error(sock))); return good_close(sock); } #endif static int expect_block_timeout(ne_socket *sock, int timeout, const char *msg) { int ret; NE_DEBUG(NE_DBG_SOCKET, "blocking for %d\n", timeout); ret = ne_sock_block(sock, timeout); ONV(ret != NE_SOCK_TIMEOUT, ( "ne_sock_block got %d not timeout: %s", ret, msg)); return OK; } static int blocking(void) { ne_socket *sock; int ret; CALL(begin(&sock, echo_server, NULL)); CALL(expect_block_timeout(sock, 1, "with non-zero timeout")); WRITEL("Hello, world.\n"); /* poll for data */ do { ret = ne_sock_block(sock, 1); } while (ret == NE_SOCK_TIMEOUT); ONV(ret != 0, ("ne_sock_block never got data: %d", ret)); PEEK("Hello,"); ret = ne_sock_block(sock, 1); ONV(ret != 0, ("ne_sock_block failed after peek: %d", ret)); LINE("Hello, world.\n"); return finish(sock, 0); } static int block_timeout(void) { TO_BEGIN; TO_OP(ne_sock_block(sock, 1)); TO_FINISH; } static int ssl_session_id(void) { ne_socket *sock; unsigned char buf[128]; size_t len1; CALL(begin(&sock, serve_close, NULL)); #ifdef SOCKET_SSL len1 = 0; ONN("retrieve session id length", ne_sock_sessid(sock, NULL, &len1)); if (len1 == 0) { /* recent versions of OpenSSL seem to do this, not sure * why or whether it's bad. */ finish(sock, 1); t_context("zero-length session ID, cannot test further"); return SKIP; } if (len1 < sizeof buf) { buf[len1] = 'Z'; } { size_t len2; len2 = sizeof buf; ONN("could not retrieve session id", ne_sock_sessid(sock, buf, &len2)); ONN("buffer size changed!?", len1 != len2); } ONN("buffer written past expected end", len1 < sizeof buf && buf[len1] != 'Z'); /* Attempt retrieval into too-short buffer: */ len1 = 0; ONN("success for buffer overflow case", ne_sock_sessid(sock, buf, &len1) == 0); #else len1 = sizeof buf; ONN("retrieved session id for non-SSL socket!?", ne_sock_sessid(sock, buf, &len1) == 0); #endif ne_sock_close(sock); return await_server(); } static int serve_ppeer(ne_socket *sock, void *ud) { unsigned int port = 99999; ne_inet_addr *ia = ne_sock_peer(sock, &port); char buf[128], line[256]; if (ia == NULL) ne_snprintf(line, sizeof line, "error: %s", ne_sock_error(sock)); else ne_snprintf(line, sizeof line, "%s@%u\n", ne_iaddr_print(ia, buf, sizeof buf), port); CALL(full_write(sock, line, strlen(line))); ne_iaddr_free(ia); return OK; } static int try_prebind(int addr, int port) { ne_socket *sock = ne_sock_create(); ne_inet_addr *ia; char buf[128], line[256]; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); CALL(spawn_server(7777, serve_ppeer, NULL)); ne_sock_prebind(sock, addr ? ia : NULL, port ? 7778 : 0); ONN("could not connect", ne_sock_connect(sock, ia, 7777)); ne_snprintf(line, sizeof line, "%s@%d\n", ne_iaddr_print(ia, buf, sizeof buf), 7778); if (!port) { /* Don't know what port will be chosen, so... */ ssize_t ret = ne_sock_readline(sock, buffer, BUFSIZ); ONV(ret < 0, ("socket error `%s'", ne_sock_error(sock))); ONV(strncmp(line, buffer, strchr(line, '@') - line) != 0, ("bad address: '%s', expecting '%s'", buffer, line)); } else { LINE(line); } ne_sock_close(sock); CALL(await_server()); ne_iaddr_free(ia); return OK; } static int prebind(void) { CALL(try_prebind(1, 0)); CALL(try_prebind(0, 1)); CALL(try_prebind(1, 1)); return OK; } static int serve_cipher(ne_socket *sock, void *ud) { char *ciph = ne_sock_cipher(sock); char *s = ciph && strlen(ciph) ? ciph : "NULL"; CALL(full_write(sock, s, strlen(s))); if (ciph) ne_free(ciph); return OK; } static int cipher(void) { ne_socket *sock; #ifdef SOCKET_SSL char *ciph; CALL(begin(&sock, serve_cipher, NULL)); ciph = ne_sock_cipher(sock); ONN("NULL/empty cipher", ciph == NULL || strlen(ciph) == 0); FULLREAD(ciph); ne_free(ciph); #else CALL(begin(&sock, serve_cipher, NULL)); ONN("non-NULL cipher for non-SSL socket", ne_sock_cipher(sock) != NULL); FULLREAD("NULL"); #endif return finish(sock, 1); } static int error(void) { ne_socket *sock = ne_sock_create(); ne_sock_set_error(sock, "%s:%s", "fish", "42"); ONCMP("fish:42", ne_sock_error(sock), "socket error", "set"); ne_sock_close(sock); return OK; } static int begin_socks(ne_socket **sock, struct socks_server *srv, server_fn server, void *userdata) { srv->server = server; srv->userdata = userdata; srv->say_hello = 1; CALL(spawn_server(7777, socks_server, srv)); return do_connect(sock, localhost, 7777); } static int socks_proxy(void) { static const struct { enum ne_sock_sversion version; int addr; const char *fqdn; unsigned int port; const char *username, *password; } ts[] = { { NE_SOCK_SOCKSV4, 4, NULL, 55555, NULL, NULL }, { NE_SOCK_SOCKSV4, 4, NULL, 55555, "foobar", NULL }, { NE_SOCK_SOCKSV4A, 0, "www.example.com", 55555, NULL, NULL }, { NE_SOCK_SOCKSV5, 0, "www.example.com", 55555, NULL, NULL }, { NE_SOCK_SOCKSV5, 4, NULL, 55555, NULL, NULL }, #ifdef TEST_IPV6 { NE_SOCK_SOCKSV5, 6, NULL, 55555, NULL, NULL }, #endif { NE_SOCK_SOCKSV5, 0, "www.example.com", 55555, "norman", "foobar" } }; unsigned n; for (n = 0; n < sizeof(ts)/sizeof(ts[n]); n++) { ne_socket *sock; struct socks_server arg = {0}; int ret; arg.version = ts[n].version; arg.expect_port = ts[n].port; if (ts[n].addr == 4) arg.expect_addr = ne_iaddr_make(ne_iaddr_ipv4, raw_127); #ifdef TEST_IPV6 else if (ts[n].addr == 6) arg.expect_addr = ne_iaddr_make(ne_iaddr_ipv4, raw6_cafe); #endif else arg.expect_fqdn = ts[n].fqdn; arg.username = ts[n].username; arg.password = ts[n].password; CALL(begin_socks(&sock, &arg, echo_server, NULL)); ret = ne_sock_proxy(sock, ts[n].version, arg.expect_addr, ts[n].fqdn, ts[n].port, ts[n].username, ts[n].password); ONV(ret, ("proxy connect #%u gave %d", n, ret)); FULLREAD("ok!\n"); ECHO("hello,\n"); ECHO("\n"); ECHO("world\n"); if (ts[n].addr) ne_iaddr_free(arg.expect_addr); CALL(finish(sock, 0)); } return OK; } static int fail_socks(void) { static const struct { enum ne_sock_sversion version; enum socks_failure failure; const char *expect; const char *username, *password; } ts[] = { { NE_SOCK_SOCKSV5, fail_init_vers, "Invalid version in proxy response", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_init_trunc, "Could not read initial response from proxy: Connection closed", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_init_close, "Could not read initial response from proxy: Connection closed", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_no_auth, "No acceptable authentication method", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_bogus_auth, "Unexpected authentication method chosen", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_auth_close, "Could not read login reply: Connection closed", "foo", "bar" }, { NE_SOCK_SOCKSV5, fail_auth_denied, "Authentication failed", "foo", "bar" } }; unsigned n; for (n = 0; n < sizeof(ts)/sizeof(ts[n]); n++) { ne_socket *sock; struct socks_server arg = {0}; int ret; arg.version = ts[n].version; arg.failure = ts[n].failure; arg.expect_port = 5555; arg.expect_addr = ne_iaddr_make(ne_iaddr_ipv4, raw_127); arg.username = ts[n].username; arg.password = ts[n].password; CALL(begin_socks(&sock, &arg, echo_server, NULL)); ret = ne_sock_proxy(sock, ts[n].version, arg.expect_addr, NULL, arg.expect_port, ts[n].username, ts[n].password); ONV(ret == 0, ("proxy connect #%u succeeded, expected failure '%s'", n, ts[n].expect)); if (ret != 0 && strstr(ne_sock_error(sock), ts[n].expect) == NULL) { t_warning("proxy connect #%u got unexpected failure '%s', wanted '%s'", n, ne_sock_error(sock), ts[n].expect); } ne_iaddr_free(arg.expect_addr); CALL(finish(sock, 0)); } return OK; } ne_test tests[] = { T(multi_init), T_LEAKY(resolve), T(resolve_numeric), #ifdef SOCKET_SSL T_LEAKY(init_ssl), #endif T(addr_make_v4), T(parse_v4), T(addr_make_v6), T(addr_compare), T(addr_reverse), T(just_connect), T(addr_connect), T(addr_peer), T(read_close), T(peek_close), T(single_read), T(single_peek), T(small_reads), T(read_and_peek), T(larger_read), T(ssl_session_id), T(cipher), T(line_simple), T(line_closure), T(line_empty), T(line_toolong), T(line_overflow), T(line_mingle), T(line_chunked), T(line_long_chunked), T(small_writes), T(large_writes), T(large_writev), T(echo_lines), T(blocking), T(prebind), T(error), #ifdef SOCKET_SSL T(ssl_closure), T(ssl_truncate), #else T(write_reset), T(read_reset), #endif #if TEST_CONNECT_TIMEOUT T(connect_timeout), #endif T(read_timeout), T(peek_timeout), T(readline_timeout), T(fullread_timeout), T(block_timeout), T(socks_proxy), T(fail_socks), T(NULL) }; davix-R_0_5_0/deps/libneon/test/ssl.c000066400000000000000000001533141257152637300176010ustar00rootroot00000000000000/* neon test suite Copyright (C) 2002-2009, Joe Orton 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 "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_request.h" #include "ne_socket.h" #include "ne_ssl.h" #include "ne_auth.h" #include "tests.h" #include "child.h" #include "utils.h" #ifndef NE_HAVE_SSL /* this file shouldn't be built if SSL is not enabled. */ #error SSL not supported #endif #include "ne_pkcs11.h" #define SERVER_CERT "server.cert" #define CA2_SERVER_CERT "ca2server.pem" #define CA_CERT "ca/cert.pem" #define P12_PASSPHRASE "foobar" #define SERVER_DNAME "Neon QA Dept, Neon Hackers Ltd, " \ "Cambridge, Cambridgeshire, GB" #define CACERT_DNAME "Random Dept, Neosign, Oakland, California, US" static char *srcdir = "."; static char *server_key = NULL; static ne_ssl_certificate *def_ca_cert = NULL, *def_server_cert; static ne_ssl_client_cert *def_cli_cert; static char *nul_cn_fn; static int check_dname(const ne_ssl_dname *dn, const char *expected, const char *which); /* Arguments for running the SSL server */ struct ssl_server_args { char *cert; /* the server cert to present. */ const char *response; /* the response to send. */ int numreqs; /* number of request/responses to handle over the SSL connection. */ /* client cert handling: */ int require_cc; /* require a client cert if non-NULL */ const char *ca_list; /* file of CA certs to verify client cert against */ int fail_silently; /* exit with success if handshake fails */ /* session caching: */ int cache; /* use the session cache if non-zero */ struct ssl_session { unsigned char id[128]; size_t len; } session; int count; /* internal use. */ int use_ssl2; /* force use of SSLv2 only */ const char *key; }; /* default response string if args->response is NULL */ #define DEF_RESP "HTTP/1.0 200 OK\r\nContent-Length: 0\r\n\r\n" /* An SSL server inna bun. */ static int ssl_server(ne_socket *sock, void *userdata) { struct ssl_server_args *args = userdata; int ret; char buf[BUFSIZ]; const char *key; static ne_ssl_context *ctx = NULL; if (ctx == NULL) { ctx = ne_ssl_context_create(args->use_ssl2 ? NE_SSL_CTX_SERVERv2 : NE_SSL_CTX_SERVER); } ONV(ctx == NULL, ("could not create SSL context")); key = args->key ? args->key : server_key; NE_DEBUG(NE_DBG_HTTP, "SSL server init with keypair (%s, %s).\n", args->cert, key); ONV(ne_ssl_context_keypair(ctx, args->cert, key), ("failed to load server keypair: ...")); if (args->require_cc && !args->ca_list) { args->ca_list = CA_CERT; } ne_ssl_context_set_verify(ctx, args->require_cc, args->ca_list, args->ca_list); ret = ne_sock_accept_ssl(sock, ctx); if (ret && args->fail_silently) { return 0; } ONV(ret, ("SSL accept failed: %s", ne_sock_error(sock))); args->count++; /* loop handling requests: */ do { const char *response = args->response ? args->response : DEF_RESP; ret = ne_sock_read(sock, buf, BUFSIZ - 1); if (ret == NE_SOCK_CLOSED) return 0; /* connection closed by parent; give up. */ ONV(ret < 0, ("SSL read failed (%d): %s", ret, ne_sock_error(sock))); buf[ret] = '\0'; NE_DEBUG(NE_DBG_HTTP, "Request over SSL was: [%s]\n", buf); if (strstr(buf, "Proxy-Authorization:") != NULL) { NE_DEBUG(NE_DBG_HTTP, "Got Proxy-Auth header over SSL!\n"); response = "HTTP/1.1 500 Client Leaks Credentials\r\n" "Content-Length: 0\r\n" "\r\n"; } ONV(ne_sock_fullwrite(sock, response, strlen(response)), ("SSL write failed: %s", ne_sock_error(sock))); } while (--args->numreqs > 0); if (args->cache) { unsigned char sessid[128]; size_t len = sizeof sessid; ONN("could not retrieve session ID", ne_sock_sessid(sock, sessid, &len)); #ifdef NE_DEBUGGING { char *b64 = ne_base64(sessid, len); NE_DEBUG(NE_DBG_SSL, "Session id retrieved (%d): [%s]\n", args->count, b64); ne_free(b64); } #endif if (args->count == 1) { /* save the session. */ memcpy(args->session.id, sessid, len); args->session.len = len; } else { /* Compare with stored session. */ ONN("cached session not used", args->session.len != len || memcmp(args->session.id, sessid, len)); } } return 0; } /* serve_ssl wrapper which ignores server failure and always succeeds */ static int fail_serve(ne_socket *sock, void *ud) { struct ssl_server_args args = {0}; args.cert = ud; ssl_server(sock, &args); return OK; } #define DEFSESS (ne_session_create("https", "localhost", 7777)) /* Run a request in the given session. */ static int any_ssl_request(ne_session *sess, server_fn fn, void *server_ud, char *ca_cert, ne_ssl_verify_fn verify_fn, void *verify_ud) { int ret; if (ca_cert) { ne_ssl_certificate *ca = ne_ssl_cert_read(ca_cert); ONV(ca == NULL, ("could not load CA cert `%s'", ca_cert)); ne_ssl_trust_cert(sess, ca); ne_ssl_cert_free(ca); } CALL(spawn_server(7777, fn, server_ud)); if (verify_fn) ne_ssl_set_verify(sess, verify_fn, verify_ud); ret = any_request(sess, "/foo"); CALL(await_server()); ONREQ(ret); return OK; } static int init(void) { /* take srcdir as argv[1]. */ if (test_argc > 1) { srcdir = test_argv[1]; server_key = ne_concat(srcdir, "/server.key", NULL); } else { server_key = "server.key"; } if (ne_sock_init()) { t_context("could not initialize socket/SSL library."); return FAILHARD; } def_ca_cert = ne_ssl_cert_read(CA_CERT); if (def_ca_cert == NULL) { t_context("couldn't load CA cert %s", CA_CERT); return FAILHARD; } def_server_cert = ne_ssl_cert_read(SERVER_CERT); if (def_server_cert == NULL) { t_context("couldn't load server cert %s", SERVER_CERT); return FAILHARD; } /* tests for the encrypted client cert, client.p12 */ def_cli_cert = ne_ssl_clicert_read("client.p12"); if (def_cli_cert == NULL) { t_context("could not load client.p12"); return FAILHARD; } if (!ne_ssl_clicert_encrypted(def_cli_cert)) { ne_ssl_clicert_free(def_cli_cert); def_cli_cert = NULL; t_context("client.p12 is not encrypted!?"); return FAIL; } if (ne_ssl_clicert_decrypt(def_cli_cert, P12_PASSPHRASE)) { ne_ssl_clicert_free(def_cli_cert); def_cli_cert = NULL; t_context("failed to decrypt client.p12"); return FAIL; } nul_cn_fn = ne_concat(srcdir, "/nulcn.pem", NULL); return OK; } /* just check the result codes of loading server certs. */ static int load_server_certs(void) { ne_ssl_certificate *cert; cert = ne_ssl_cert_read("Makefile"); ONN("invalid CA cert file loaded successfully", cert != NULL); cert = ne_ssl_cert_read("nonesuch.pem"); ONN("non-existent 'nonesuch.pem' loaded successfully", cert != NULL); cert = ne_ssl_cert_read("ssigned.pem"); ONN("could not load ssigned.pem", cert == NULL); ne_ssl_cert_free(cert); return OK; } static int trust_default_ca(void) { ne_session *sess = DEFSESS; ne_ssl_trust_default_ca(sess); ne_session_destroy(sess); return OK; } #define CC_NAME "Just A Neon Client Cert" /* Tests for loading client certificates */ static int load_client_cert(void) { ne_ssl_client_cert *cc; const ne_ssl_certificate *cert; const char *name; cc = ne_ssl_clicert_read("client.p12"); ONN("could not load client.p12", cc == NULL); ONN("client.p12 not encrypted!?", !ne_ssl_clicert_encrypted(cc)); name = ne_ssl_clicert_name(cc); if (name == NULL) { t_warning("no friendly name given"); } else { ONV(strcmp(name, CC_NAME), ("friendly name was %s not %s", name, CC_NAME)); } ONN("failed to decrypt", ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE)); ne_ssl_clicert_free(cc); cc = ne_ssl_clicert_read("client.p12"); ONN("decrypted client.p12 with incorrect password!?", ne_ssl_clicert_decrypt(cc, "barfoo") == 0); ne_ssl_clicert_free(cc); /* tests for the unencrypted client cert, client2.p12 */ cc = ne_ssl_clicert_read("unclient.p12"); ONN("could not load unencrypted cert unclient.p12", cc == NULL); ONN("unencrypted cert marked encrypted?", ne_ssl_clicert_encrypted(cc)); cert = ne_ssl_clicert_owner(cc); ONN("client cert had no certificate", cert == NULL); CALL(check_dname(ne_ssl_cert_subject(cert), "Neon Client Cert, Neon Hackers Ltd, " "Cambridge, Cambridgeshire, GB", "client cert subject")); CALL(check_dname(ne_ssl_cert_issuer(cert), CACERT_DNAME, "client cert issuer")); ne_ssl_clicert_free(cc); /* test for ccert without a friendly name, noclient.p12 */ cc = ne_ssl_clicert_read("noclient.p12"); ONN("could not load noclient.p12", cc == NULL); name = ne_ssl_clicert_name(cc); ONV(name != NULL, ("noclient.p12 had friendly name `%s'", name)); ne_ssl_clicert_free(cc); /* test for ccert with a bundled CA. */ cc = ne_ssl_clicert_read("clientca.p12"); ONN("could not load clientca.p12", cc == NULL); ONN("encrypted cert marked unencrypted?", !ne_ssl_clicert_encrypted(cc)); ONN("could not decrypt clientca.p12", ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE)); ne_ssl_clicert_free(cc); /* test for ccert without a private key, nkclient.p12 */ cc = ne_ssl_clicert_read("nkclient.p12"); ONN("did not fail to load clicert without pkey", cc != NULL); /* test for ccert without a cert, ncclient.p12 */ cc = ne_ssl_clicert_read("ncclient.p12"); ONN("did not fail to load clicert without cert", cc != NULL); /* tests for loading bogus files. */ cc = ne_ssl_clicert_read("Makefile"); ONN("loaded Makefile as client cert!?", cc != NULL); /* test for loading nonexistent file. */ cc = ne_ssl_clicert_read("nosuch.pem"); ONN("loaded nonexistent file as client cert!?", cc != NULL); return OK; } /* Test that 'cert', which is signed by CA_CERT, is accepted * unconditionaly. */ static int accept_signed_cert_for_hostname(char *cert, const char *hostname) { ne_session *sess = ne_session_create("https", hostname, 7777); struct ssl_server_args args = {cert, 0}; /* no verify callback needed. */ CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } static int accept_signed_cert(char *cert) { return accept_signed_cert_for_hostname(cert, "localhost"); } static int simple(void) { return accept_signed_cert(SERVER_CERT); } /* Test for SSL operation when server uses SSLv2 */ static int simple_sslv2(void) { #ifdef HAVE_OPENSSL return SKIP; /* this is breaking with current SSL. */ #else ne_session *sess = ne_session_create("https", "localhost", 7777); struct ssl_server_args args = {SERVER_CERT, 0}; args.use_ssl2 = 1; ne_set_session_flag(sess, NE_SESSFLAG_SSLv2, 1); CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; #endif } /* Serves using HTTP/1.0 get-till-EOF semantics. */ static int serve_eof(ne_socket *sock, void *ud) { struct ssl_server_args args = {0}; args.cert = ud; args.response = "HTTP/1.0 200 OK\r\n" "Connection: close\r\n" "\r\n" "This is a response body, like it or not."; return ssl_server(sock, &args); } /* Test read-til-EOF behaviour with SSL. */ static int simple_eof(void) { ne_session *sess = DEFSESS; CALL(any_ssl_request(sess, serve_eof, SERVER_CERT, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } static int intermediary(void) { ne_session *sess = DEFSESS; struct ssl_server_args args = {CA2_SERVER_CERT, 0}; CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } static int empty_truncated_eof(void) { ne_session *sess = DEFSESS; struct ssl_server_args args = {0}; args.cert = SERVER_CERT; args.response = "HTTP/1.0 200 OK\r\n" "\r\n"; CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } /* Server function which just sends a string then EOF. */ static int just_serve_string(ne_socket *sock, void *userdata) { const char *str = userdata; server_send(sock, str, strlen(str)); return 0; } /* test for the SSL negotiation failing. */ static int fail_not_ssl(void) { ne_session *sess = DEFSESS; int ret; CALL(spawn_server(7777, just_serve_string, "Hello, world.\n")); ret = any_request(sess, "/bar"); CALL(await_server()); ONN("request did not fail", ret != NE_ERROR); ne_session_destroy(sess); return OK; } /* Server callback which handles a CONNECT request. */ static int tunnel_server(ne_socket *sock, void *ud) { struct ssl_server_args *args = ud; CALL(discard_request(sock)); SEND_STRING(sock, "HTTP/1.1 200 OK\r\nServer: serve_tunnel\r\n\r\n"); return ssl_server(sock, args); } static int wildcard_match(void) { ne_session *sess; struct ssl_server_args args = {"wildcard.cert", 0}; sess = ne_session_create("https", "anything.example.com", 443); ne_session_proxy(sess, "localhost", 7777); CALL(any_ssl_request(sess, tunnel_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } static int wildcard_match_altname(void) { ne_session *sess; struct ssl_server_args args = {"altname9.cert", 0}; sess = ne_session_create("https", "anything.example.com", 443); ne_session_proxy(sess, "localhost", 7777); CALL(any_ssl_request(sess, tunnel_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } /* Check that hostname comparisons are not cases-sensitive. */ static int caseless_match(void) { return accept_signed_cert("caseless.cert"); } /* Test that the subjectAltName extension has precedence over the * commonName attribute */ static int subject_altname(void) { return accept_signed_cert("altname1.cert"); } /* tests for multiple altNames. */ static int two_subject_altname(void) { return accept_signed_cert("altname2.cert"); } static int two_subject_altname2(void) { return accept_signed_cert("altname3.cert"); } /* Test that a subject altname with *only* an eMail entry is * ignored, and the commonName is used instead. */ static int notdns_altname(void) { return accept_signed_cert("altname4.cert"); } static int ipaddr_altname(void) { return accept_signed_cert_for_hostname("altname5.cert", "127.0.0.1"); } static int uri_altname(void) { return accept_signed_cert_for_hostname("altname7.cert", "localhost"); } /* test that the *most specific* commonName attribute is used. */ static int multi_commonName(void) { return accept_signed_cert("twocn.cert"); } /* regression test for neon <= 0.23.4 where if commonName was the first * RDN in the subject DN, it was ignored. */ static int commonName_first(void) { return accept_signed_cert("cnfirst.cert"); } static int check_dname(const ne_ssl_dname *dn, const char *expected, const char *which) { char *dname; ONV(dn == NULL, ("certificate %s dname was NULL", which)); dname = ne_ssl_readable_dname(dn); NE_DEBUG(NE_DBG_SSL, "Got dname `%s', expecting `%s'\n", dname, expected); ONV(strcmp(dname, expected), ("certificate %s dname was `%s' not `%s'", which, dname, expected)); ne_free(dname); return 0; } /* Check that the readable subject issuer dnames of 'cert' match * 'subject' and 'issuer' (if non-NULL). */ static int check_cert_dnames(const ne_ssl_certificate *cert, const char *subject, const char *issuer) { ONN("no server certificate presented", cert == NULL); CALL(check_dname(ne_ssl_cert_subject(cert), subject, "subject")); return issuer ? check_dname(ne_ssl_cert_issuer(cert), issuer, "issuer") : OK; } /* Verify callback which checks that the certificate presented has the * predetermined subject and issuer DN (as per makekeys.sh). */ static int check_cert(void *userdata, int fs, const ne_ssl_certificate *cert) { int *ret = userdata; if (check_cert_dnames(cert, SERVER_DNAME, CACERT_DNAME) == FAIL) *ret = -1; else *ret = 1; return 0; } /* Check that certificate attributes are passed correctly. */ static int parse_cert(void) { ne_session *sess = DEFSESS; int ret = 0; struct ssl_server_args args = {SERVER_CERT, 0}; /* don't give a CA cert; should force the verify callback to be * used. */ CALL(any_ssl_request(sess, ssl_server, &args, NULL, check_cert, &ret)); ne_session_destroy(sess); ONN("cert verification never called", ret == 0); if (ret == -1) return FAIL; return OK; } #define WRONGCN_DNAME "Bad Hostname Department, Neon Hackers Ltd, " \ "Cambridge, Cambridgeshire, GB" /* Check the certificate chain presented against known dnames. */ static int check_chain(void *userdata, int fs, const ne_ssl_certificate *cert) { int *ret = userdata; if (check_cert_dnames(cert, WRONGCN_DNAME, CACERT_DNAME) == FAIL) { *ret = -1; return 0; } cert = ne_ssl_cert_signedby(cert); if (cert == NULL) { t_context("no CA cert in chain"); *ret = -1; return 0; } if (check_cert_dnames(cert, CACERT_DNAME, CACERT_DNAME) == FAIL) { *ret = -1; return 0; } *ret = 1; return 0; } /* Check that certificate attributes are passed correctly. */ static int parse_chain(void) { ne_session *sess = DEFSESS; int ret = 0; struct ssl_server_args args = {"wrongcn.cert", 0}; args.ca_list = CA_CERT; /* The cert is signed by the CA but has a CN mismatch, so will * force the verification callback to be invoked. */ CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, check_chain, &ret)); ne_session_destroy(sess); ONN("cert verification never called", ret == 0); if (ret == -1) return FAIL; return OK; } static int count_vfy(void *userdata, int fs, const ne_ssl_certificate *c) { int *count = userdata; (*count)++; return 0; } static int no_verify(void) { ne_session *sess = DEFSESS; int count = 0; struct ssl_server_args args = {SERVER_CERT, 0}; CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, count_vfy, &count)); ONN("verify callback called unnecessarily", count != 0); ne_session_destroy(sess); return OK; } static int cache_verify(void) { ne_session *sess = DEFSESS; int ret, count = 0; struct ssl_server_args args = {SERVER_CERT, 0}; /* force verify cert. */ ret = any_ssl_request(sess, ssl_server, &args, NULL, count_vfy, &count); CALL(spawn_server(7777, ssl_server, &args)); ret = any_request(sess, "/foo2"); CALL(await_server()); ONV(count != 1, ("verify callback result not cached: called %d times", count)); ne_session_destroy(sess); return OK; } /* Copy failures into *userdata, and fail verification. */ static int get_failures(void *userdata, int fs, const ne_ssl_certificate *c) { int *out = userdata; *out = fs; return -1; } /* Helper function: run a request using the given self-signed server * certificate, and expect the request to fail with the given * verification failure flags. */ static int fail_ssl_request_with_error2(char *cert, char *key, char *cacert, const char *host, const char *fakehost, const char *msg, int failures, const char *errstr) { ne_session *sess = ne_session_create("https", host, 7777); int gotf = 0, ret; struct ssl_server_args args = {0}; ne_sock_addr *addr; const ne_inet_addr *list[1]; if (fakehost) { addr = ne_addr_resolve(fakehost, 0); ONV(ne_addr_result(addr), ("fake hostname lookup failed for %s", fakehost)); list[0] = ne_addr_first(addr); ne_set_addrlist(sess, list, 1); } args.cert = cert; args.key = key; args.fail_silently = 1; ret = any_ssl_request(sess, ssl_server, &args, cacert, get_failures, &gotf); ONV(gotf == 0, ("no error in verification callback; error string: %s", ne_get_error(sess))); ONV(gotf & ~NE_SSL_FAILMASK, ("verification flags %x outside mask %x", gotf, NE_SSL_FAILMASK)); /* check the failure flags were as expected. */ ONV(failures != gotf, ("verification flags were %d not %d", gotf, failures)); /* and check that the request was failed too. */ ONV(ret == NE_OK, ("%s", msg)); ONV(errstr && strstr(ne_get_error(sess), errstr) == NULL, ("unexpected failure message '%s', wanted '%s'", ne_get_error(sess), errstr)); ne_session_destroy(sess); return OK; } /* Helper function: run a request using the given self-signed server * certificate, and expect the request to fail with the given * verification failure flags. */ static int fail_ssl_request_with_error(char *cert, char *cacert, const char *host, const char *msg, int failures, const char *errstr) { return fail_ssl_request_with_error2(cert, NULL, cacert, host, NULL, msg, failures, errstr); } /* Helper function: run a request using the given self-signed server * certificate, and expect the request to fail with the given * verification failure flags. */ static int fail_ssl_request(char *cert, char *cacert, const char *host, const char *msg, int failures) { return fail_ssl_request_with_error(cert, cacert, host, msg, failures, NULL); } /* Note that the certs used for fail_* are mostly self-signed, so the * cert is passed as CA cert and server cert to fail_ssl_request. */ /* Check that a certificate with the incorrect commonName attribute is * flagged as such. */ static int fail_wrongCN(void) { return fail_ssl_request_with_error("wrongcn.cert", "ca/cert.pem", "localhost", "certificate with incorrect CN was accepted", NE_SSL_IDMISMATCH, "certificate issued for a different hostname"); } #define SRCDIR(s) ne_concat(srcdir, "/" s, NULL) static int fail_nul_cn(void) { char *key = SRCDIR("nulsrv.key"), *ca = SRCDIR("nulca.pem"); CALL(fail_ssl_request_with_error2(nul_cn_fn, key, ca, "www.bank.com", "localhost", "certificate with incorrect CN was accepted", NE_SSL_IDMISMATCH, "certificate issued for a different hostname")); ne_free(key); ne_free(ca); return OK; } static int fail_nul_san(void) { char *cert = SRCDIR("nulsan.pem"), *key = SRCDIR("nulsrv.key"), *ca = SRCDIR("nulca.pem"); CALL(fail_ssl_request_with_error2(cert, key, ca, "www.bank.com", "localhost", "certificate with incorrect CN was accepted", NE_SSL_IDMISMATCH, "certificate issued for a different hostname")); ne_free(cert); ne_free(key); ne_free(ca); return OK; } /* Check that an expired certificate is flagged as such. */ static int fail_expired(void) { char *c = ne_concat(srcdir, "/expired.pem", NULL); CALL(fail_ssl_request_with_error(c, c, "localhost", "expired certificate was accepted", NE_SSL_EXPIRED, "certificate has expired")); ne_free(c); return OK; } static int fail_notvalid(void) { char *c = ne_concat(srcdir, "/notvalid.pem", NULL); CALL(fail_ssl_request_with_error(c, c, "localhost", "not yet valid certificate was accepted", NE_SSL_NOTYETVALID, "certificate is not yet valid")); ne_free(c); return OK; } /* Check that a server cert with a random issuer and self-signed cert * fail with UNTRUSTED. */ static int fail_untrusted_ca(void) { return fail_ssl_request_with_error("server.cert", NULL, "localhost", "untrusted CA.", NE_SSL_UNTRUSTED, "issuer is not trusted"); } static int fail_self_signed(void) { return fail_ssl_request("ssigned.pem", NULL, "localhost", "self-signed cert", NE_SSL_UNTRUSTED); } /* Test for failure when a server cert is presented which has no * commonName (and no alt names either). */ static int fail_missing_CN(void) { ne_session *sess = DEFSESS; ONN("accepted server cert with missing commonName", any_ssl_request(sess, fail_serve, "missingcn.cert", SERVER_CERT, NULL, NULL) == NE_OK); ONV(strstr(ne_get_error(sess), "missing commonName") == NULL, ("unexpected session error `%s'", ne_get_error(sess))); ne_session_destroy(sess); return OK; } /* test for a bad ipAddress altname */ static int fail_bad_ipaltname(void) { return fail_ssl_request("altname6.cert", CA_CERT, "127.0.0.1", "bad IP altname cert", NE_SSL_IDMISMATCH); } /* test for a ipAddress which matched against the hostname as per neon * 0.24 behaviour. */ static int fail_host_ipaltname(void) { return fail_ssl_request("altname5.cert", CA_CERT, "localhost", "bad IP altname cert", NE_SSL_IDMISMATCH); } static int fail_bad_urialtname(void) { return fail_ssl_request("altname8.cert", CA_CERT, "localhost", "bad URI altname cert", NE_SSL_IDMISMATCH); } static int fail_wildcard(void) { return fail_ssl_request("altname9.cert", CA_CERT, "localhost", "subjaltname not honored", NE_SSL_IDMISMATCH); } static int fail_wildcard_ip(void) { return fail_ssl_request("wildip.cert", CA_CERT, "127.0.0.1", "wildcard IP", NE_SSL_IDMISMATCH); } static int fail_ca_expired(void) { return fail_ssl_request_with_error("ca1server.cert", "ca1/cert.pem", "localhost", "issuer ca expired", NE_SSL_BADCHAIN, "bad certificate chain"); } static int fail_ca_notyetvalid(void) { return fail_ssl_request("ca3server.cert", "ca3/cert.pem", "localhost", "issuer ca not yet valid", NE_SSL_BADCHAIN); } /* Test that the SSL session is cached across connections. */ static int session_cache(void) { struct ssl_server_args args = {0}; ne_session *sess = ne_session_create("https", "localhost", 7777); args.cert = SERVER_CERT; args.cache = 1; ne_ssl_trust_cert(sess, def_ca_cert); /* have spawned server listen for several connections. */ CALL(spawn_server_repeat(7777, ssl_server, &args, 4)); ONREQ(any_request(sess, "/req1")); ONREQ(any_request(sess, "/req2")); ne_session_destroy(sess); /* server should still be waiting for connections: if not, * something went wrong. */ ONN("error from child", dead_server()); /* now get rid of it. */ reap_server(); return OK; } /* Callback for client_cert_provider; takes a c. cert as userdata and * registers it. */ static void ccert_provider(void *userdata, ne_session *sess, const ne_ssl_dname *const *dns, int dncount) { const ne_ssl_client_cert *cc = userdata; ne_ssl_set_clicert(sess, cc); } /* Test that the on-demand client cert provider callback is used. */ static int client_cert_provided(void) { ne_session *sess = DEFSESS; ne_ssl_client_cert *cc; struct ssl_server_args args = {SERVER_CERT, NULL}; args.require_cc = 1; cc = ne_ssl_clicert_read("client.p12"); ONN("could not load client.p12", cc == NULL); ONN("could not decrypt client.p12", ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE)); ne_ssl_provide_clicert(sess, ccert_provider, cc); CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); ne_ssl_clicert_free(cc); return OK; } #define DN_COUNT 5 static void cc_check_dnames(void *userdata, ne_session *sess, const ne_ssl_dname *const *dns, int dncount) { int n, *ret = userdata; static const char *expected[DN_COUNT] = { CACERT_DNAME, "First Random CA, CAs Ltd., Lincoln, Lincolnshire, GB", "Second Random CA, CAs Ltd., Falmouth, Cornwall, GB", "Third Random CA, CAs Ltd., Ipswich, Suffolk, GB", "Fourth Random CA, CAs Ltd., Norwich, Norfolk, GB" }; ne_ssl_set_clicert(sess, def_cli_cert); if (dncount != DN_COUNT) { t_context("dname count was %d not %d", dncount, DN_COUNT); *ret = -1; return; } for (n = 0; n < DN_COUNT; n++) { char which[5]; sprintf(which, "%d", n); if (check_dname(dns[n], expected[n], which) == FAIL) { *ret = -1; return; } } *ret = 1; } /* Test for the list of acceptable dnames sent to the client. */ static int cc_provided_dnames(void) { int check = 0; ne_session *sess = DEFSESS; struct ssl_server_args args = {SERVER_CERT, NULL}; args.require_cc = 1; args.ca_list = "calist.pem"; PRECOND(def_cli_cert); ne_ssl_provide_clicert(sess, cc_check_dnames, &check); CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); ONN("provider function not called", check == 0); return (check == -1) ? FAIL : OK; } /* Tests use of a client certificate. */ static int client_cert_pkcs12(void) { ne_session *sess = DEFSESS; struct ssl_server_args args = {SERVER_CERT, NULL}; args.require_cc = 1; PRECOND(def_cli_cert); ne_ssl_set_clicert(sess, def_cli_cert); CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } /* Test use of a PKCS#12 cert with an embedded CA cert - fails with <= * 0.28.3 in GnuTLS build. */ static int client_cert_ca(void) { ne_session *sess = DEFSESS; struct ssl_server_args args = {SERVER_CERT, NULL}; ne_ssl_client_cert *cc; args.require_cc = 1; cc = ne_ssl_clicert_read("clientca.p12"); ONN("could not load clientca.p12", cc == NULL); ONN("encrypted cert marked unencrypted?", !ne_ssl_clicert_encrypted(cc)); ONN("could not decrypt clientca.p12", ne_ssl_clicert_decrypt(cc, P12_PASSPHRASE)); ne_ssl_set_clicert(sess, cc); CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_ssl_clicert_free(cc); ne_session_destroy(sess); return OK; } /* Tests use of an unencrypted client certificate. */ static int ccert_unencrypted(void) { ne_session *sess = DEFSESS; ne_ssl_client_cert *ccert; struct ssl_server_args args = {SERVER_CERT, NULL}; args.require_cc = 1; ccert = ne_ssl_clicert_read("unclient.p12"); ONN("could not load unclient.p12", ccert == NULL); ONN("unclient.p12 was encrypted", ne_ssl_clicert_encrypted(ccert)); ne_ssl_set_clicert(sess, ccert); CALL(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_ssl_clicert_free(ccert); ne_session_destroy(sess); return OK; } #define NOCERT_MESSAGE "client certificate was requested" /* Tests for useful error message if a handshake fails where a client * cert was requested. */ static int no_client_cert(void) { ne_session *sess = DEFSESS; struct ssl_server_args args = {SERVER_CERT, NULL}; int ret; args.require_cc = 1; args.fail_silently = 1; ne_ssl_trust_cert(sess, def_ca_cert); CALL(spawn_server(7777, ssl_server, &args)); ret = any_request(sess, "/failme"); ONV(ret != NE_ERROR, ("unexpected result %d: %s", ret, ne_get_error(sess))); ONV(strstr(ne_get_error(sess), NOCERT_MESSAGE) == NULL, ("error message was '%s', missing '%s'", ne_get_error(sess), NOCERT_MESSAGE)); reap_server(); ne_session_destroy(sess); return OK; } /* non-zero if a server auth header was received */ static int got_server_auth; /* Utility function which accepts the 'tunnel' header. */ static void tunnel_header(char *value) { got_server_auth = 1; } /* Server which acts as a proxy accepting a CONNECT request. */ static int serve_tunnel(ne_socket *sock, void *ud) { struct ssl_server_args *args = ud; /* check for a server auth function */ want_header = "Authorization"; got_header = tunnel_header; got_server_auth = 0; /* give the plaintext tunnel reply, acting as the proxy */ CALL(discard_request(sock)); if (got_server_auth) { SEND_STRING(sock, "HTTP/1.1 500 Leaked Server Auth Creds\r\n" "Content-Length: 0\r\n" "Server: serve_tunnel\r\n\r\n"); return 0; } else { SEND_STRING(sock, "HTTP/1.1 200 OK\r\nServer: serve_tunnel\r\n\r\n"); return ssl_server(sock, args); } } /* neon versions <= 0.21.2 segfault here because ne_sock_close would * be called twice on the socket after the server cert verification * fails. */ static int fail_tunnel(void) { ne_session *sess = ne_session_create("https", "example.com", 443); struct ssl_server_args args = {SERVER_CERT, NULL}; ne_session_proxy(sess, "localhost", 7777); ONN("server cert verification didn't fail", any_ssl_request(sess, serve_tunnel, &args, CA_CERT, NULL, NULL) != NE_ERROR); ne_session_destroy(sess); return OK; } static int proxy_tunnel(void) { ne_session *sess = ne_session_create("https", "localhost", 443); struct ssl_server_args args = {SERVER_CERT, NULL}; ne_session_proxy(sess, "localhost", 7777); /* CA cert is trusted, so no verify callback should be needed. */ CALL(any_ssl_request(sess, serve_tunnel, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } #define RESP_0LENGTH "HTTP/1.1 200 OK\r\n" "Content-Length: 0\r\n" "\r\n" /* a tricky test which requires spawning a second server process in * time for a new connection after a 407. */ static int apt_post_send(ne_request *req, void *ud, const ne_status *st) { int *code = ud; if (st->code == *code) { struct ssl_server_args args = {SERVER_CERT, NULL}; if (*code == 407) args.numreqs = 2; args.response = RESP_0LENGTH; NE_DEBUG(NE_DBG_HTTP, "Got challenge, awaiting server...\n"); CALL(await_server()); NE_DEBUG(NE_DBG_HTTP, "Spawning proper tunnel server...\n"); /* serve *two* 200 OK responses. */ CALL(spawn_server(7777, serve_tunnel, &args)); NE_DEBUG(NE_DBG_HTTP, "Spawned.\n"); } return OK; } static int apt_creds(void *userdata, const char *realm, int attempt, char *username, char *password) { strcpy(username, "foo"); strcpy(password, "bar"); return attempt; } /* Test for using SSL over a CONNECT tunnel via a proxy server which * requires authentication. Broke briefly between 0.23.x and * 0.24.0. */ static int auth_proxy_tunnel(void) { ne_session *sess = ne_session_create("https", "localhost", 443); int ret, code = 407; ne_session_proxy(sess, "localhost", 7777); ne_hook_post_send(sess, apt_post_send, &code); ne_set_proxy_auth(sess, apt_creds, NULL); ne_ssl_trust_cert(sess, def_ca_cert); CALL(spawn_server(7777, single_serve_string, "HTTP/1.0 407 I WANT MORE BISCUITS\r\n" "Proxy-Authenticate: Basic realm=\"bigbluesea\"\r\n" "Connection: close\r\n" "\r\n")); /* run two requests over the tunnel. */ ret = any_2xx_request(sess, "/foobar"); if (!ret) ret = any_2xx_request(sess, "/foobar2"); CALL(await_server()); CALL(ret); ne_session_destroy(sess); return 0; } /* Regression test to check that server credentials aren't sent to the * proxy in a CONNECT request. */ static int auth_tunnel_creds(void) { ne_session *sess = ne_session_create("https", "localhost", 443); int ret, code = 401; struct ssl_server_args args = {SERVER_CERT, 0}; ne_session_proxy(sess, "localhost", 7777); ne_hook_post_send(sess, apt_post_send, &code); ne_set_server_auth(sess, apt_creds, NULL); ne_ssl_trust_cert(sess, def_ca_cert); args.response = "HTTP/1.1 401 I want a Shrubbery\r\n" "WWW-Authenticate: Basic realm=\"bigredocean\"\r\n" "Server: Python\r\n" "Content-Length: 0\r\n" "\r\n"; CALL(spawn_server(7777, serve_tunnel, &args)); ret = any_2xx_request(sess, "/foobar"); CALL(await_server()); CALL(ret); ne_session_destroy(sess); return OK; } static int auth_tunnel_fail(void) { ne_session *sess = ne_session_create("https", "localhost", 443); int ret; CALL(spawn_server(7777, single_serve_string, "HTTP/1.1 407 Nyaaaaah\r\n" "Proxy-Authenticate: GaBoogle\r\n" "Connection: close\r\n" "\r\n")); ne_session_proxy(sess, "localhost", 7777); ne_set_proxy_auth(sess, apt_creds, NULL); ret = any_request(sess, "/bar"); ONV(ret != NE_PROXYAUTH, ("bad error code for tunnel failure: %d", ret)); ONV(strstr(ne_get_error(sess), "GaBoogle") == NULL, ("bad error string for tunnel failure: %s", ne_get_error(sess))); ne_session_destroy(sess); return await_server(); } /* compare against known digest of notvalid.pem. Via: * $ openssl x509 -fingerprint -sha1 -noout -in notvalid.pem */ #define THE_DIGEST "cf:5c:95:93:76:c6:3c:01:8b:62:" \ "b1:6f:f7:7f:42:32:ac:e6:69:1b" static int cert_fingerprint(void) { char *fn = ne_concat(srcdir, "/notvalid.pem", NULL); ne_ssl_certificate *cert = ne_ssl_cert_read(fn); char digest[60]; ne_free(fn); ONN("could not load notvalid.pem", cert == NULL); ONN("failed to digest", ne_ssl_cert_digest(cert, digest)); ne_ssl_cert_free(cert); ONV(strcmp(digest, THE_DIGEST), ("digest was %s not %s", digest, THE_DIGEST)); return OK; } /* verify that identity of certificate in filename 'fname' is 'identity' */ static int check_identity(const char *fname, const char *identity) { ne_ssl_certificate *cert = ne_ssl_cert_read(fname); const char *id; ONV(cert == NULL, ("could not read cert `%s'", fname)); id = ne_ssl_cert_identity(cert); if (identity) { ONV(id == NULL, ("certificate `%s' had no identity", fname)); ONV(strcmp(id, identity), ("certificate `%s' had identity `%s' not `%s'", fname, id, identity)); } else { ONV(id != NULL, ("certificate `%s' had identity `%s' (expected none)", fname, id)); } ne_ssl_cert_free(cert); return OK; } /* check certificate identities. */ static int cert_identities(void) { static const struct { const char *fname, *identity; } certs[] = { { "ssigned.pem", "localhost" }, { "twocn.cert", "localhost" }, { "altname1.cert", "localhost" }, { "altname2.cert", "nohost.example.com" }, { "altname4.cert", "localhost" }, { "ca4.pem", "fourth.example.com" }, { "altname8.cert", "http://nohost.example.com/" }, { NULL, NULL } }; int n; for (n = 0; certs[n].fname != NULL; n++) CALL(check_identity(certs[n].fname, certs[n].identity)); return OK; } static int nulcn_identity(void) { ne_ssl_certificate *cert = ne_ssl_cert_read(nul_cn_fn); const char *id, *expected = "www.bank.com\\x00.badguy.com"; ONN("could not read nulcn.pem", cert == NULL); id = ne_ssl_cert_identity(cert); ONV(id != NULL && strcmp(id, expected) != 0, ("certificate `nulcn.pem' had identity `%s' not `%s'", id, expected)); ne_ssl_cert_free(cert); return OK; } static int check_validity(const char *fname, const char *from, const char *until) { char actfrom[NE_SSL_VDATELEN], actuntil[NE_SSL_VDATELEN]; ne_ssl_certificate *cert; cert = ne_ssl_cert_read(fname); ONV(cert == NULL, ("could not load cert `%s'", fname)); /* cover all calling combos for nice coverage analysis */ ne_ssl_cert_validity(cert, NULL, NULL); ne_ssl_cert_validity(cert, actfrom, NULL); ne_ssl_cert_validity(cert, NULL, actuntil); ne_ssl_cert_validity(cert, actfrom, actuntil); ONV(strcmp(actfrom, from), ("%s: start time was `%s' not `%s'", fname, actfrom, from)); ONV(strcmp(actuntil, until), ("%s: end time was `%s' not `%s'", fname, actuntil, until)); ne_ssl_cert_free(cert); return OK; } /* ceritificate validity times. */ static int cert_validity(void) { char *cert = ne_concat(srcdir, "/expired.pem", NULL); CALL(check_validity(cert, "Mon, 21 Jan 2002 20:39:04 GMT", "Thu, 31 Jan 2002 20:39:04 GMT")); ne_free(cert); cert = ne_concat(srcdir, "/notvalid.pem", NULL); CALL(check_validity(cert, "Wed, 27 Dec 2023 20:40:29 GMT", "Thu, 28 Dec 2023 20:40:29 GMT")); ne_free(cert); return OK; } /* dname comparisons. */ static int dname_compare(void) { ne_ssl_certificate *ssigned; const ne_ssl_dname *dn1, *dn2; dn1 = ne_ssl_cert_subject(def_server_cert); dn2 = ne_ssl_cert_subject(def_server_cert); ONN("identical subject names not equal", ne_ssl_dname_cmp(dn1, dn2) != 0); dn2 = ne_ssl_cert_issuer(def_server_cert); ONN("issuer and subject names equal for signed cert", ne_ssl_dname_cmp(dn1, dn2) == 0); dn1 = ne_ssl_cert_subject(def_ca_cert); ONN("issuer of signed cert not equal to subject of CA cert", ne_ssl_dname_cmp(dn1, dn2) != 0); ssigned = ne_ssl_cert_read("ssigned.pem"); ONN("could not load ssigned.pem", ssigned == NULL); dn1 = ne_ssl_cert_subject(ssigned); dn2 = ne_ssl_cert_issuer(ssigned); ONN("issuer and subject names not equal for self-signed cert", ne_ssl_dname_cmp(dn1, dn2)); ne_ssl_cert_free(ssigned); return OK; } /* The dname with the UTF-8 encoding of the Unicode string: * "Hllo World". */ #define I18N_DNAME "H\xc3\xa8llo World, Neon Hackers Ltd, Cambridge, Cambridgeshire, GB" /* N.B. t61subj.cert encodes an ISO-8859-1 string in a T61String * field, which is strictly wrong but the common usage. */ /* tests for ne_ssl_readable_dname */ static int dname_readable(void) { struct { const char *cert; const char *subjdn, *issuerdn; } ts[] = { { "justmail.cert", "blah@example.com", NULL }, { "t61subj.cert", I18N_DNAME, NULL }, { "bmpsubj.cert", I18N_DNAME, NULL }, { "utf8subj.cert", I18N_DNAME, NULL }, { "twoou.cert", "First OU Dept, Second OU Dept, Neon Hackers Ltd, " "Cambridge, Cambridgeshire, GB" } }; size_t n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) { ne_ssl_certificate *cert = ne_ssl_cert_read(ts[n].cert); ONV(cert == NULL, ("could not load cert %s", ts[n].cert)); CALL(check_cert_dnames(cert, ts[n].subjdn, ts[n].issuerdn)); ne_ssl_cert_free(cert); } return OK; } /* test cert comparisons */ static int cert_compare(void) { ne_ssl_certificate *c1, *c2; c1 = ne_ssl_cert_read("server.cert"); c2 = ne_ssl_cert_read("server.cert"); ONN("identical certs don't compare equal", ne_ssl_cert_cmp(c1, c2) != 0); ONN("identical certs don't compare equal", ne_ssl_cert_cmp(c2, c1) != 0); ne_ssl_cert_free(c2); c2 = ne_ssl_cert_read("ssigned.pem"); ONN("different certs don't compare different", ne_ssl_cert_cmp(c1, c2) == 0); ONN("different certs don't compare different", ne_ssl_cert_cmp(c2, c1) == 0); ne_ssl_cert_free(c2); ne_ssl_cert_free(c1); return OK; } /* Extract raw base64 string from a PEM file */ static int flatten_pem(const char *fname, char **out) { FILE *fp = fopen(fname, "r"); char buf[80]; size_t outlen = 0; int ignore = 1; ONV(fp == NULL, ("could not open %s", fname)); *out = NULL; while (fgets(buf, sizeof buf, fp) != NULL) { size_t len = strlen(buf) - 1; if (len < 1) continue; /* look for the wrapper lines. */ if (strncmp(buf, "-----", 5) == 0) { ignore = !ignore; continue; } /* ignore until the first wrapper line */ if (ignore) continue; *out = realloc(*out, outlen + len + 1); memcpy(*out + outlen, buf, len); outlen += len; } (*out)[outlen] = '\0'; fclose(fp); return OK; } /* check export cert data 'actual' against expected data 'expected */ static int check_exported_data(const char *actual, const char *expected) { ONN("could not export cert", actual == NULL); ONN("export data contained newline", strchr(actual, '\r') || strchr(actual, '\n')); ONV(strcmp(actual, expected), ("exported cert differed from expected:\n" "actual: %s\nexpected: %s", actual, expected)); return OK; } /* Test import and export of certificates. The export format is PEM * without the line feeds and wrapping; compare against . */ static int import_export(void) { char *expected, *actual; ne_ssl_certificate *cert, *imp; CALL(flatten_pem("server.cert", &expected)); cert = ne_ssl_cert_read("server.cert"); ONN("could not load server.cert", cert == NULL); /* export the cert to and compare it with the PEM file */ actual = ne_ssl_cert_export(cert); CALL(check_exported_data(actual, expected)); /* import the exported cert data, check it looks the same */ imp = ne_ssl_cert_import(actual); ONN("failed to import exported cert", imp == NULL); ONN("imported cert was different to original", ne_ssl_cert_cmp(imp, cert)); /* re-export the imported cert and check that looks the same */ ne_free(actual); actual = ne_ssl_cert_export(imp); CALL(check_exported_data(actual, expected)); ne_ssl_cert_free(imp); /* try importing from bogus data */ imp = ne_ssl_cert_import("!!"); ONN("imported bogus cert from bogus base64", imp != NULL); imp = ne_ssl_cert_import("aaaa"); ONN("imported bogus cert from valid base64", imp != NULL); ne_ssl_cert_free(cert); ne_free(actual); ne_free(expected); return OK; } /* Test write/read */ static int read_write(void) { ne_ssl_certificate *c1, *c2; c1 = ne_ssl_cert_read("server.cert"); ONN("could not load server.cert", c1 == NULL); ONN("could not write output.pem", ne_ssl_cert_write(c1, "output.pem")); ONN("wrote to nonexistent directory", ne_ssl_cert_write(c1, "nonesuch/output.pem") == 0); c2 = ne_ssl_cert_read("output.pem"); ONN("could not read output.pem", c2 == NULL); ONN("read of output.pem differs from original", ne_ssl_cert_cmp(c2, c1)); ne_ssl_cert_free(c1); ne_ssl_cert_free(c2); return OK; } /* A verification callback which caches the passed cert. */ static int verify_cache(void *userdata, int fs, const ne_ssl_certificate *cert) { char **cache = userdata; if (*cache == NULL) { *cache = ne_ssl_cert_export(cert); return 0; } else { return -1; } } /* Test a common use of the SSL API; cache the server cert across * sessions. */ static int cache_cert(void) { ne_session *sess = DEFSESS; char *cache = NULL; ne_ssl_certificate *cert; struct ssl_server_args args = {0}; args.cert = "ssigned.pem"; args.cache = 1; ONREQ(any_ssl_request(sess, ssl_server, &args, CA_CERT, verify_cache, &cache)); ne_session_destroy(sess); ONN("no cert was cached", cache == NULL); /* make a real cert */ cert = ne_ssl_cert_import(cache); ONN("could not import cached cert", cert == NULL); ne_free(cache); /* create a new session */ sess = DEFSESS; /* trust the cert */ ne_ssl_trust_cert(sess, cert); ne_ssl_cert_free(cert); /* now, the request should succeed without manual verification */ ONREQ(any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL)); ne_session_destroy(sess); return OK; } static int nonssl_trust(void) { ne_session *sess = ne_session_create("http", "www.example.com", 80); ne_ssl_trust_cert(sess, def_ca_cert); ne_session_destroy(sess); return OK; } /* PIN password provider callback. */ static int pkcs11_pin(void *userdata, int attempt, const char *slot_descr, const char *token_label, unsigned int flags, char *pin) { char *sekrit = userdata; NE_DEBUG(NE_DBG_SSL, "pkcs11: slot = [%s], token = [%s]\n", slot_descr, token_label); if (attempt == 0) { strcpy(pin, sekrit); return 0; } else { return -1; } } static int nss_pkcs11_test(const char *dbname) { ne_session *sess = DEFSESS; struct ssl_server_args args = {SERVER_CERT, NULL}; ne_ssl_pkcs11_provider *prov; int ret; args.require_cc = 1; if (access(dbname, R_OK|X_OK)) { t_warning("NSS required for PKCS#11 testing"); return SKIP; } ret = ne_ssl_pkcs11_nss_provider_init(&prov, "softokn3", dbname, NULL, NULL, NULL); if (ret) { if (ret == NE_PK11_NOTIMPL) t_context("pakchois library required for PKCS#11 support"); else t_context("could not load NSS softokn3 PKCS#11 provider"); return SKIP; } ne_ssl_pkcs11_provider_pin(prov, pkcs11_pin, "foobar"); ne_ssl_set_pkcs11_provider(sess, prov); ret = any_ssl_request(sess, ssl_server, &args, CA_CERT, NULL, NULL); ne_session_destroy(sess); ne_ssl_pkcs11_provider_destroy(prov); return ret; } static int pkcs11(void) { return nss_pkcs11_test("nssdb"); } static int pkcs11_dsa(void) { return nss_pkcs11_test("nssdb-dsa"); } /* TODO: code paths still to test in cert verification: * - server cert changes between connections: Mozilla gives * a "bad MAC decode" error for this; can do better? * - server presents no certificate (using ADH ciphers)... can * only really happen if they mess with the SSL_CTX and enable * ADH cipher manually; but good to check the failure case is * safe. * From the SSL book: * - an early FIN should be returned as a possible truncation attack, * NOT just an NE_SOCK_CLOSED. * - unexpected close_notify is an error but not an attack. * - never attempt session resumption after any aborted connection. */ ne_test tests[] = { T_LEAKY(init), T(load_server_certs), T(trust_default_ca), T(cert_fingerprint), T(cert_identities), T(cert_validity), T(cert_compare), T(dname_compare), T(dname_readable), T(import_export), T(read_write), T(load_client_cert), T(simple), T(simple_sslv2), T(simple_eof), T(empty_truncated_eof), T(fail_not_ssl), T(cache_cert), T(intermediary), T(client_cert_pkcs12), T(ccert_unencrypted), T(client_cert_provided), T(cc_provided_dnames), T(no_client_cert), T(client_cert_ca), T(parse_cert), T(parse_chain), T(no_verify), T(cache_verify), T(wildcard_match), T(wildcard_match_altname), T(caseless_match), T(subject_altname), T(two_subject_altname), T(two_subject_altname2), T(notdns_altname), T(ipaddr_altname), T(uri_altname), T(multi_commonName), T(commonName_first), T(fail_wrongCN), T(fail_expired), T(fail_notvalid), T(fail_untrusted_ca), T(fail_self_signed), T(fail_missing_CN), T(fail_host_ipaltname), T(fail_bad_ipaltname), T(fail_bad_urialtname), T(fail_wildcard), T(fail_wildcard_ip), T(fail_ca_notyetvalid), T(fail_ca_expired), T(nulcn_identity), T(fail_nul_cn), T(fail_nul_san), T(session_cache), T(fail_tunnel), T(proxy_tunnel), T(auth_proxy_tunnel), T(auth_tunnel_creds), T(auth_tunnel_fail), T(nonssl_trust), T(pkcs11), T_XFAIL(pkcs11_dsa), /* unclear why this fails currently. */ T(NULL) }; davix-R_0_5_0/deps/libneon/test/string-tests.c000066400000000000000000000417071257152637300214500ustar00rootroot00000000000000/* String handling tests Copyright (C) 2001-2007, 2009, Joe Orton 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 "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_ERRNO_H #include /* for the ENOENT definitions in str_errors */ #endif #include "ne_string.h" #include "ne_utils.h" #include "tests.h" #undef ONCMP #define ONCMP(a,b) ONV(strcmp(a, b), \ ("result was [%s] not [%s]", a, b)) static int simple(void) { ne_buffer *s = ne_buffer_create(); ON(s == NULL); ne_buffer_zappend(s, "abcde"); ONCMP(s->data, "abcde"); ON(ne_buffer_size(s) != 5); ne_buffer_destroy(s); return OK; } static int buf_concat(void) { ne_buffer *s = ne_buffer_create(); ON(s == NULL); ne_buffer_concat(s, "a", "b", "c", "d", "e", "f", "g", NULL); ONCMP(s->data, "abcdefg"); ON(ne_buffer_size(s) != 7); ne_buffer_destroy(s); return OK; } static int buf_concat2(void) { #define RES "alphabetagammadeltaepsilonetatheta" ne_buffer *s = ne_buffer_create(); ON(s == NULL); ne_buffer_concat(s, "alpha", "beta", "gamma", "delta", "epsilon", "eta", "theta", NULL); ONCMP(s->data, RES); ON(ne_buffer_size(s) != strlen(RES)); ne_buffer_destroy(s); return OK; } static int buf_concat3(void) { ne_buffer *s = ne_buffer_create(); ON(s == NULL); ne_buffer_zappend(s, "foobar"); ne_buffer_concat(s, "norman", NULL); ONCMP(s->data, "foobarnorman"); ON(ne_buffer_size(s) != 12); ne_buffer_destroy(s); return OK; } static int append(void) { ne_buffer *s = ne_buffer_create(); ON(s == NULL); ne_buffer_append(s, "a", 1); ne_buffer_append(s, "b", 1); ne_buffer_append(s, "c", 1); ONCMP(s->data, "abc"); ON(ne_buffer_size(s) != 3); ne_buffer_zappend(s, "hello"); ONCMP(s->data, "abchello"); ne_buffer_czappend(s, "world"); ONCMP(s->data, "abchelloworld"); ON(ne_buffer_size(s) != 13); ne_buffer_destroy(s); return OK; } static int grow(void) { ne_buffer *s = ne_buffer_ncreate(2); ON(s == NULL); ne_buffer_append(s, "a", 1); ne_buffer_grow(s, 4); ONCMP(s->data, "a"); ne_buffer_destroy(s); return OK; } static int alter(void) { ne_buffer *s = ne_buffer_create(); char *d; ON(s == NULL); ne_buffer_zappend(s, "abcdefg"); d = s->data; ON(d == NULL); d[2] = '\0'; ne_buffer_altered(s); ONCMP(s->data, "ab"); ON(ne_buffer_size(s) != 2); ne_buffer_zappend(s, "hijkl"); ONCMP(s->data, "abhijkl"); ne_buffer_destroy(s); return OK; } /* Macros for testing ne_token. */ #define TEST(res) do { \ char *tok = ne_token(&pnt, ','); \ ONN(res ": return", tok == NULL); \ ONN(res ": compare", strcmp(tok, (res))); \ ONN(res ": modify", pnt == NULL); \ } while (0) #define LASTTEST(res) do { \ char *tok = ne_token(&pnt, ','); \ ONN(res ": last return", tok == NULL); \ ONN(res ": last compare", strcmp(tok, (res))); \ ONN(res ": last modify", pnt != NULL); \ } while (0) #define QTEST(res) do { \ char *tok = ne_qtoken(&pnt, ',', QUOTES); \ ONN(res ": return", tok == NULL); \ ONN(res ": compare", strcmp(tok, (res))); \ ONN(res ": modify", pnt == NULL); \ } while (0) #define QLASTTEST(res) do { \ char *tok = ne_qtoken(&pnt, ',', QUOTES); \ ONN(res ": last return", tok == NULL); \ ONN(res ": last compare", strcmp(tok, (res))); \ ONN(res ": last modify", pnt != NULL); \ } while (0) static int token1(void) { char *str = ne_strdup("a,b,c,d"), *pnt = str; TEST("a"); TEST("b"); TEST("c"); LASTTEST("d"); ne_free(str); return OK; } static int token2(void) { char *str = ne_strdup("norman,fishing, elsewhere"), *pnt = str; TEST("norman"); TEST("fishing"); LASTTEST(" elsewhere"); ne_free(str); return OK; } static int nulls(void) { char *str = ne_strdup("alpha,,gamma"), *pnt = str; TEST("alpha"); TEST(""); LASTTEST("gamma"); ne_free(str); pnt = str = ne_strdup(",,,wooo"); TEST(""); TEST(""); TEST(""); LASTTEST("wooo"); ne_free(str); pnt = str = ne_strdup("wooo,,,"); TEST("wooo"); TEST(""); TEST(""); LASTTEST(""); ne_free(str); return OK; } static int empty(void) { char *str = ne_strdup(""), *pnt = str; LASTTEST(""); ne_free(str); return OK; } #undef QUOTES #define QUOTES "'" static int quoted(void) { char *str = ne_strdup("alpha,'beta, a fish called HELLO!?',sandwiches"); char *pnt = str; QTEST("alpha"); QTEST("'beta, a fish called HELLO!?'"); QLASTTEST("sandwiches"); ne_free(str); return OK; } static int badquotes(void) { char *str = ne_strdup("alpha,'blah"), *pnt = str; QTEST("alpha"); ON(ne_qtoken(&pnt, ',', QUOTES) != NULL); ne_free(str); return OK; } /* for testing ne_shave. */ #undef TEST #define TEST(str, ws, res) do { \ char *s = ne_strdup((str)); \ char *r = ne_shave(s, (ws)); \ ONN("[" str "]", strcmp(r, (res))); \ ne_free(s); \ } while (0) static int shave(void) { TEST(" b ", " ", "b"); TEST("b", " ", "b"); TEST(" b ", " ", "b"); TEST("--bbb-----", "-", "bbb"); TEST("hello, world ", " ", "hello, world"); TEST("<<><<<><<<<<><<", "<>", "this is foo"); TEST("09809812342347I once saw an helicopter0012312312398", "0123456789", "I once saw an helicopter"); return OK; } /* Regression test for ne_shave call which should produce an empty * string. */ static int shave_regress(void) { TEST("\"\"", "\"", ""); return OK; } /* Test the ne_token/ne_shave combination. */ #undef TEST #undef LASTTEST #define TEST(res) do { \ char *tok = ne_token(&pnt, ','); \ ONN(res ": return", tok == NULL); \ tok = ne_shave(tok, " "); \ ONN(res ": shave", tok == NULL); \ ONN(res ": compare", strcmp(tok, (res))); \ ONN(res ": modify", pnt == NULL); \ } while (0) #define LASTTEST(res) do { \ char *tok = ne_token(&pnt, ','); \ ONN(res ": last return", tok == NULL); \ tok = ne_shave(tok, " "); \ ONN(res ": last shave", tok == NULL); \ ONN(res ": last compare", strcmp(tok, (res))); \ ONN(res ": last modify", pnt != NULL); \ } while (0) /* traditional use of ne_token/ne_shave. */ static int combo(void) { char *str = ne_strdup(" fred , mary, jim , alice, david"), *pnt = str; TEST("fred"); TEST("mary"); TEST("jim"); TEST("alice"); LASTTEST("david"); ne_free(str); return 0; } static int concat(void) { #define CAT(res, args) do { char *str = ne_concat args; \ ONCMP(str, res); \ ne_free(str); } while (0) CAT("alphabeta", ("alpha", "beta", NULL)); CAT("alpha", ("alpha", "", "", NULL)); CAT("", ("", NULL)); CAT("", ("", "", "", NULL)); CAT("alpha", ("", "a", "lph", "", "a", NULL)); return OK; } static int str_errors(void) { char expect[200], actual[200]; strncpy(expect, strerror(ENOENT), sizeof(expect)); ONN("ne_strerror did not return passed-in buffer", ne_strerror(ENOENT, actual, sizeof(actual)) != actual); ONV(strcmp(expect, actual), ("error from ENOENT was `%s' not `%s'", actual, expect)); /* Test truncated error string is still NUL-terminated. */ ne_strerror(ENOENT, actual, 6); NE_DEBUG(NE_DBG_HTTP, "error: %s\n", actual); ONN("truncated string had wrong length", strlen(actual) != 5); ne_strerror(-1, actual, 6); ONN("truncated string for bad error had wrong length", strlen(actual) != 5); return OK; } static int strnzcpy(void) { char buf[5]; ne_strnzcpy(buf, "abcdefghi", sizeof buf); ONV(strcmp(buf, "abcd"), ("result was `%s' not `abcd'", buf)); ne_strnzcpy(buf, "ab", sizeof buf); ONV(strcmp(buf, "ab"), ("result was `%s' not `ab'", buf)); return OK; } #define FOX_STRING "The quick brown fox jumped over the lazy dog" #define PUNC_STRING "<>,.;'#:@~[]{}!\"$%^&*()_+-=" static int cleaner(void) { static const char *strings[] = { "alpha", "alpha", "pretty\033[41mcolours", "pretty [41mcolours", "beta\n", "beta ", "del\rt\na", "del t a", FOX_STRING, FOX_STRING, "0123456789", "0123456789", PUNC_STRING, PUNC_STRING, "\01blah blee\05bloo", " blah blee bloo", NULL, }; unsigned int n; for (n = 0; strings[n]; n+=2) { char *act = ne_strclean(ne_strdup(strings[n])); ONV(strcmp(act, strings[n+1]), ("cleansed to `%s' not `%s'", act, strings[n+1])); ne_free(act); } return OK; } /* Check that raw data 'raw', of length 'len', has base64 encoding * of 'expected'. */ static int b64_check(const unsigned char *raw, size_t len, const char *expected) { char *encoded = ne_base64(raw, len); unsigned char *decoded; size_t dlen; ONV(strcmp(encoded, expected), ("base64(\"%s\") gave \"%s\" not \"%s\"", raw, encoded, expected)); dlen = ne_unbase64(encoded, &decoded); ONV(dlen != len, ("decoded `%s' length was %" NE_FMT_SIZE_T " not %" NE_FMT_SIZE_T, expected, dlen, len)); ONV(memcmp(raw, decoded, dlen), ("decoded `%s' as `%.*s' not `%.*s'", expected, (int)dlen, decoded, (int)dlen, raw)); ne_free(decoded); ne_free(encoded); return OK; } /* ALLBITS: base64 encoding of "\0..\377" */ #define ALLBITS \ "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss" \ "LS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ" \ "WltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWG" \ "h4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz" \ "tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g" \ "4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" static int base64(void) { unsigned char bits[256]; size_t n; #define B64B(x, l, y) CALL(b64_check((unsigned char *)x, l, y)) #define B64(x, y) B64B(x, strlen(x), y) /* invent these with * $ printf "string" | uuencode -m blah */ B64("a", "YQ=="); B64("bb", "YmI="); B64("ccc", "Y2Nj"); B64("Hello, world", "SGVsbG8sIHdvcmxk"); B64("Aladdin:open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); B64("I once saw a dog called norman.\n", "SSBvbmNlIHNhdyBhIGRvZyBjYWxsZWQgbm9ybWFuLgo="); B64("The quick brown fox jumped over the lazy dog", "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c="); /* binary data.. * $ printf "string" | wc -c # get the length * $ printf "string" | uuencode -m blah # get the base64 */ B64B("\0\0\0\0\0\n", 6, "AAAAAAAK"); B64B("I once wished \0 upon a \0 fish.", 30, "SSBvbmNlIHdpc2hlZCAAIHVwb24gYSAAIGZpc2gu"); B64B("\201\202\203\204", 4, "gYKDhA=="); for (n = 0; n < sizeof bits; n++) bits[n] = (unsigned char)n; CALL(b64_check(bits, sizeof bits, ALLBITS)); #undef B64 #undef B64B return OK; } static int unbase64(void) { static const char *ts[] = { "", "a", "ab", "abc", "}bcd", "a}cd", "ab}d", "abc}", " ", "^bcd", "a^cd", "ab^d", "abc^", "====", "=bcd", "a=cd", "ab=d", "a==d", "a=c=", NULL }; size_t n; for (n = 0; ts[n]; n++) { unsigned char *tmp; ONV(ne_unbase64(ts[n], &tmp) != 0, ("invalid string `%s' was decoded", ts[n])); } return OK; } static int printing(void) { struct { const char *in, *out; size_t pass, ret; } ts[] = { { "alpha", "alpha", 10, 5 }, { "alpha", "alph", 5, 4 }, { "foobar", "", 1, 0 }, { NULL, NULL, 0, 0} }; size_t n; for (n = 0; ts[n].in; n++) { char buf[512]; size_t ret; memset(buf, 'A', sizeof buf); ret = ne_snprintf(buf, ts[n].pass, "%s", ts[n].in); ONCMP(buf, ts[n].out); ONV(ret != ts[n].ret, ("got return value %" NE_FMT_SIZE_T " not %" NE_FMT_SIZE_T, ret, ts[n].ret)); /* byte past the NUL must still be 'A' */ ONN("buffer over-ran!", buf[ret + 1] != 'A'); } return OK; } static int casecmp(void) { static const struct { const char *left, *right; int expect; } ts[] = { { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", 0 }, { "foo", "bar", 1 }, { "!#:[@\377", "!#:[@\377", 0 }, { "bar", "foo", -1 }, { "foop", "foo", 1 }, { "foo", "foop", -1 }, { NULL, NULL, 0 } }; size_t n; for (n = 0; ts[n].left; n++) { int actual; actual = ne_strcasecmp(ts[n].left, ts[n].right); ONV(ts[n].expect == 0 && actual != 0, ("strcasecmp(%s, %s) gave %d, expected 0", ts[n].left, ts[n].right, actual)); ONV(ts[n].expect > 0 && actual <= 0, ("strcasecmp(%s, %s) gave %d, expected > 0", ts[n].left, ts[n].right, actual)); ONV(ts[n].expect < 0 && actual >= 0, ("strcasecmp(%s, %s) gave %d, expected < 0", ts[n].left, ts[n].right, actual)); } ONN("comparison of identical pointers did not give zero", ne_strcasecmp(ts[0].left, ts[0].left) != 0); return OK; } static int casencmp(void) { static const struct { const char *left, *right; size_t n; int expect; } ts[] = { { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 30, 0 }, { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10, 0 }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", 0, 0 }, { "foo", "bar", 3, 1 }, { "bar", "foo", 4, -1 }, { "bar", "foo", 3, -1 }, { "foop", "foo", 4, 1 }, { "foo", "foop", 4, -1 }, { "bee", "bar", 0, 0}, { NULL, NULL, 0, 0 } }; size_t n; for (n = 0; ts[n].left; n++) { int actual; actual = ne_strncasecmp(ts[n].left, ts[n].right, ts[n].n); ONV(ts[n].expect == 0 && actual != 0, ("strncasecmp(%s, %s, %" NE_FMT_SIZE_T ") gave %d, expected 0", ts[n].left, ts[n].right, ts[n].n, actual)); ONV(ts[n].expect > 0 && actual <= 0, ("strncasecmp(%s, %s, %" NE_FMT_SIZE_T ") gave %d, expected > 0", ts[n].left, ts[n].right, ts[n].n, actual)); ONV(ts[n].expect < 0 && actual >= 0, ("strncasecmp(%s, %s, %" NE_FMT_SIZE_T ") gave %d, expected < 0", ts[n].left, ts[n].right, ts[n].n, actual)); } ONN("comparison of identical pointers did not give zero", ne_strncasecmp(ts[0].left, ts[0].left, 5) != 0); return OK; } static int buf_print(void) { ne_buffer *buf = ne_buffer_create(); ne_buffer_czappend(buf, "foo-"); ne_buffer_snprintf(buf, 20, "bar-%s-asda", "norman"); ne_buffer_czappend(buf, "-bloo"); ONN("snprintf return value", ne_buffer_snprintf(buf, 2, "---") != 1); ONCMP(buf->data, "foo-bar-norman-asda-bloo-"); ne_buffer_destroy(buf); return OK; } static int qappend(void) { static const struct { const char *in; size_t inlen; const char *out; } ts[] = { { "", 0, "" }, { "a", 1, "a" }, { "b", 2, "b\\x00" }, { "alpha\0alpha", 11, "alpha\\x00alpha" }, { "a\tb", 3, "a\\x09b" }, { NULL } }; unsigned n; for (n = 0; ts[n].in; n++) { ne_buffer *buf = ne_buffer_create(); char *s; const unsigned char *in = (const unsigned char *)ts[n].in; ne_buffer_qappend(buf, in, ts[n].inlen); ONCMP(buf->data, ts[n].out); ONV(strlen(buf->data) + 1 != buf->used, ("bad buffer length for '%s': %" NE_FMT_SIZE_T, ts[n].out, buf->used)); s = ne_strnqdup(in, ts[n].inlen); ONCMP(s, ts[n].out); ne_free(s); ne_buffer_destroy(buf); } return OK; } ne_test tests[] = { T(simple), T(buf_concat), T(buf_concat2), T(buf_concat3), T(append), T(grow), T(alter), T(token1), T(token2), T(nulls), T(empty), T(quoted), T(badquotes), T(shave), T(shave_regress), T(combo), T(concat), T(str_errors), T(strnzcpy), T(cleaner), T(base64), T(unbase64), T(printing), T(casecmp), T(casencmp), T(buf_print), T(qappend), T(NULL) }; davix-R_0_5_0/deps/libneon/test/stubs.c000066400000000000000000000114211257152637300201300ustar00rootroot00000000000000/* neon test suite Copyright (C) 2002-2005, Joe Orton 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. */ /** These tests show that the stub functions produce appropriate * results to provide ABI-compatibility when a particular feature is * not supported by the library. **/ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_request.h" #include "ne_socket.h" #include "ne_compress.h" #include "tests.h" #include "child.h" #include "utils.h" #if defined(NE_HAVE_ZLIB) && defined(NE_HAVE_SSL) #define NO_TESTS 1 #endif #define EOL "\r\n" #ifndef NE_HAVE_ZLIB static int sd_result = OK; static int sd_reader(void *ud, const char *block, size_t len) { const char *expect = ud; if (strncmp(expect, block, len) != 0) { sd_result = FAIL; t_context("decompress reader got bad data"); } return 0; } static int stub_decompress(void) { ne_session *sess; ne_decompress *dc; ne_request *req; int ret; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 OK" EOL "Connection: close" EOL EOL "abcde")); req = ne_request_create(sess, "GET", "/foo"); dc = ne_decompress_reader(req, ne_accept_2xx, sd_reader, "abcde"); ret = ne_request_dispatch(req); CALL(await_server()); ONREQ(ret); ne_decompress_destroy(dc); ne_request_destroy(req); ne_session_destroy(sess); /* This is a skeleton test suite file. */ return sd_result; } #endif #ifndef NE_HAVE_SSL static int stub_ssl(void) { ne_session *sess = ne_session_create("https", "localhost", 7777); ne_ssl_certificate *cert; ne_ssl_client_cert *cc; /* these should all fail when SSL is not supported. */ cert = ne_ssl_cert_read("Makefile"); if (cert) { char *dn, digest[60], date[NE_SSL_VDATELEN]; const ne_ssl_certificate *issuer; /* This branch should never be executed, but lets pretend it * will to prevent the compiler optimising this code away if * it's placed after the cert != NULL test. And all that * needs to be tested is that these functions link OK. */ dn = ne_ssl_readable_dname(ne_ssl_cert_subject(cert)); ONN("this code shouldn't run", dn != NULL); dn = ne_ssl_readable_dname(ne_ssl_cert_issuer(cert)); ONN("this code shouldn't run", dn != NULL); issuer = ne_ssl_cert_signedby(cert); ONN("this code shouldn't run", issuer != NULL); ONN("this code shouldn't run", ne_ssl_cert_digest(cert, digest)); ne_ssl_cert_validity(cert, date, date); ONN("this code shouldn't run", ne_ssl_dname_cmp(ne_ssl_cert_subject(cert), ne_ssl_cert_issuer(cert))); ONN("this code shouldn't run", ne_ssl_cert_identity(issuer) != NULL); ONN("this code shouldn't run", ne_ssl_cert_export(cert) != NULL); } ONN("this code shouldn't run", ne_ssl_cert_import("foo") != NULL); ONN("this code shouldn't run", ne_ssl_cert_read("Makefile") != NULL); ONN("this code shouldn't succeed", ne_ssl_cert_cmp(NULL, NULL) == 0); ONN("certificate load succeeded", cert != NULL); ne_ssl_cert_free(cert); cc = ne_ssl_clicert_read("Makefile"); if (cc) { const char *name; /* dead branch as above. */ cert = (void *)ne_ssl_clicert_owner(cc); ONN("this code shouldn't run", cert != NULL); name = ne_ssl_clicert_name(cc); ONN("this code shouldn't run", name != NULL); ONN("this code shouldn't run", ne_ssl_clicert_decrypt(cc, "fubar")); ne_ssl_set_clicert(sess, cc); } ONN("client certificate load succeeded", cc != NULL); ne_ssl_clicert_free(cc); ne_ssl_trust_default_ca(sess); ne_session_destroy(sess); return OK; } #endif #ifdef NO_TESTS static int null_test(void) { return OK; } #endif ne_test tests[] = { #ifndef NE_HAVE_ZLIB T(stub_decompress), #endif #ifndef NE_HAVE_SSL T(stub_ssl), #endif /* to prevent failure when SSL and zlib are supported. */ #ifdef NO_TESTS T(null_test), #endif T(NULL) }; davix-R_0_5_0/deps/libneon/test/uri-tests.c000066400000000000000000000444151257152637300207400ustar00rootroot00000000000000/* URI handling tests Copyright (C) 2001-2006, Joe Orton 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 "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "ne_uri.h" #include "ne_alloc.h" #include "tests.h" static int simple(void) { ne_uri p = {0}; ON(ne_uri_parse("http://www.webdav.org/foo", &p)); ON(strcmp(p.host, "www.webdav.org")); ON(strcmp(p.path, "/foo")); ON(strcmp(p.scheme, "http")); ON(p.port); ON(p.userinfo != NULL); ne_uri_free(&p); return 0; } static int simple_ssl(void) { ne_uri p = {0}; ON(ne_uri_parse("https://webdav.org/", &p)); ON(strcmp(p.scheme, "https")); ON(p.port); ne_uri_free(&p); return OK; } static int no_path(void) { ne_uri p = {0}; ON(ne_uri_parse("https://webdav.org", &p)); ON(strcmp(p.path, "/")); ne_uri_free(&p); return OK; } static int escapes(void) { const struct { const char *plain, *escaped; } paths[] = { { "/foo%", "/foo%25" }, { "/foo bar", "/foo%20bar" }, { "/foo_bar", "/foo_bar" }, { "/foobar", "/foobar" }, { "/a\xb9\xb2\xb3\xbc\xbd/", "/a%b9%b2%b3%bc%bd/" }, { NULL, NULL} }; size_t n; for (n = 0; paths[n].plain; n++) { char *esc = ne_path_escape(paths[n].plain), *un; ONCMP(paths[n].escaped, esc, paths[n].plain, "escape"); un = ne_path_unescape(esc); ONCMP(paths[n].plain, un, paths[n].plain, "unescape"); ne_free(un); ne_free(esc); } ONN("unescape accepted invalid URI", ne_path_unescape("/foo%zzbar") != NULL); ONN("unescape accepted invalid URI", ne_path_unescape("/foo%1zbar") != NULL); return OK; } static int parents(void) { static const struct { const char *path, *parent; } ps[] = { { "/a/b/c", "/a/b/" }, { "/a/b/c/", "/a/b/" }, { "/alpha/beta", "/alpha/" }, { "/foo", "/" }, { "norman", NULL }, { "/", NULL }, { "", NULL }, { NULL, NULL } }; int n; for (n = 0; ps[n].path != NULL; n++) { char *p = ne_path_parent(ps[n].path); if (ps[n].parent == NULL) { ONV(p != NULL, ("parent of `%s' was `%s' not NULL", ps[n].path, p)); } else { ONV(p == NULL, ("parent of `%s' was NULL", ps[n].path)); ONV(strcmp(p, ps[n].parent), ("parent of `%s' was `%s' not `%s'", ps[n].path, p, ps[n].parent)); ne_free(p); } } return OK; } static int compares(void) { const char *alpha = "/alpha"; ON(ne_path_compare("/a", "/a/") != 0); ON(ne_path_compare("/a/", "/a") != 0); ON(ne_path_compare("/ab", "/a/") == 0); ON(ne_path_compare("/a/", "/ab") == 0); ON(ne_path_compare("/a/", "/a/") != 0); ON(ne_path_compare("/alpha/", "/beta/") == 0); ON(ne_path_compare("/alpha", "/b") == 0); ON(ne_path_compare("/alpha/", "/alphash") == 0); ON(ne_path_compare("/fish/", "/food") == 0); ON(ne_path_compare(alpha, alpha) != 0); ON(ne_path_compare("/a/b/c/d", "/a/b/c/") == 0); return OK; } static int cmp(void) { static const struct { const char *left, *right; } eq[] = { { "http://example.com/alpha", "http://example.com/alpha" }, { "//example.com/alpha", "//example.com/alpha" }, { "http://example.com/alpha#foo", "http://example.com/alpha#foo" }, { "http://example.com/alpha?bar", "http://example.com/alpha?bar" }, { "http://jim@example.com/alpha", "http://jim@example.com/alpha" }, { "HTTP://example.com/alpha", "http://example.com/alpha" }, { "http://example.com/", "http://example.com" }, { "http://Example.Com/", "http://example.com" }, { NULL, NULL} }, diff[] = { { "http://example.com/alpha", "http://example.com/beta" }, { "http://example.com/alpha", "https://example.com/alpha" }, { "http://example.com/alpha", "http://www.example.com/alpha" }, { "http://example.com:443/alpha", "http://example.com:8080/alpha" }, { "http://example.com/alpha", "http://jim@example.com/alpha" }, { "http://bob@example.com/alpha", "http://jim@example.com/alpha" }, { "http://example.com/alpha", "http://example.com/alpha?fish" }, { "http://example.com/alpha?fish", "http://example.com/alpha?food" }, { "http://example.com/alpha", "http://example.com/alpha#foo" }, { "http://example.com/alpha#bar", "http://example.com/alpha#foo" }, { "http://example.com/alpha", "//example.com/alpha" }, { "http://example.com/alpha", "///alpha" }, { NULL, NULL} }; size_t n; for (n = 0; eq[n].left; n++) { ne_uri alpha, beta; int r1, r2; ONV(ne_uri_parse(eq[n].left, &alpha), ("could not parse left URI '%s'", eq[n].left)); ONV(ne_uri_parse(eq[n].right, &beta), ("could not parse right URI '%s'", eq[n].right)); r1 = ne_uri_cmp(&alpha, &beta); r2 = ne_uri_cmp(&beta, &alpha); ONV(r1 != 0, ("cmp('%s', '%s') = %d not zero", eq[n].left, eq[n].right, r1)); ONV(r2 != 0, ("cmp('%s', '%s') = %d not zero", eq[n].right, eq[n].left, r2)); ne_uri_free(&alpha); ne_uri_free(&beta); } for (n = 0; diff[n].left; n++) { ne_uri alpha, beta; int r1, r2; ONV(ne_uri_parse(diff[n].left, &alpha), ("could not parse left URI '%s'", diff[n].left)); ONV(ne_uri_parse(diff[n].right, &beta), ("could not parse right URI '%s'", diff[n].right)); r1 = ne_uri_cmp(&alpha, &beta); r2 = ne_uri_cmp(&beta, &alpha); ONV(r1 == 0, ("'%s' and '%s' did not compare as different", diff[n].left, diff[n].right)); ONV(r1 + r2 != 0, ("'%s' and '%s' did not compare reflexively (%d vs %d)", diff[n].left, diff[n].right, r1, r2)); ne_uri_free(&alpha); ne_uri_free(&beta); } return OK; } static int children(void) { ON(ne_path_childof("/a", "/a/b") == 0); ON(ne_path_childof("/a/", "/a/b") == 0); ON(ne_path_childof("/aa/b/c", "/a/b/c/d/e") != 0); ON(ne_path_childof("////", "/a") != 0); return OK; } static int slash(void) { ON(ne_path_has_trailing_slash("/a/") == 0); ON(ne_path_has_trailing_slash("/a") != 0); { /* check the uri == "" case. */ char *foo = "/"; ON(ne_path_has_trailing_slash(&foo[1])); } return OK; } static int default_port(void) { ONN("default http: port incorrect", ne_uri_defaultport("http") != 80); ONN("default https: port incorrect", ne_uri_defaultport("https") != 443); ONN("unspecified scheme: port incorrect", ne_uri_defaultport("ldap") != 0); return OK; } static int parse(void) { static const struct test_uri { const char *uri, *scheme, *host; unsigned int port; const char *path, *userinfo, *query, *fragment; } uritests[] = { { "http://webdav.org/norman", "http", "webdav.org", 0, "/norman", NULL, NULL, NULL }, { "http://webdav.org:/norman", "http", "webdav.org", 0, "/norman", NULL, NULL, NULL }, { "https://webdav.org/foo", "https", "webdav.org", 0, "/foo", NULL, NULL, NULL }, { "http://webdav.org:8080/bar", "http", "webdav.org", 8080, "/bar", NULL, NULL, NULL }, { "http://a/b", "http", "a", 0, "/b", NULL, NULL, NULL }, { "http://webdav.org/bar:fish", "http", "webdav.org", 0, "/bar:fish", NULL, NULL, NULL }, { "http://webdav.org", "http", "webdav.org", 0, "/", NULL, NULL, NULL }, { "http://webdav.org/fish@food", "http", "webdav.org", 0, "/fish@food", NULL, NULL, NULL }, /* query/fragments */ { "http://foo/bar?alpha", "http", "foo", 0, "/bar", NULL, "alpha", NULL }, { "http://foo/bar?alpha#beta", "http", "foo", 0, "/bar", NULL, "alpha", "beta" }, { "http://foo/bar#alpha?beta", "http", "foo", 0, "/bar", NULL, NULL, "alpha?beta" }, { "http://foo/bar#beta", "http", "foo", 0, "/bar", NULL, NULL, "beta" }, { "http://foo/bar?#beta", "http", "foo", 0, "/bar", NULL, "", "beta" }, { "http://foo/bar?alpha?beta", "http", "foo", 0, "/bar", NULL, "alpha?beta", NULL }, /* Examples from RFC39861.1.2: */ { "ftp://ftp.is.co.za/rfc/rfc1808.txt", "ftp", "ftp.is.co.za", 0, "/rfc/rfc1808.txt", NULL, NULL, NULL }, { "http://www.ietf.org/rfc/rfc2396.txt", "http", "www.ietf.org", 0, "/rfc/rfc2396.txt", NULL, NULL, NULL }, { "ldap://[2001:db8::7]/c=GB?objectClass?one", "ldap", "[2001:db8::7]", 0, "/c=GB", NULL, "objectClass?one", NULL }, { "mailto:John.Doe@example.com", "mailto", NULL, 0, "John.Doe@example.com", NULL, NULL, NULL }, { "news:comp.infosystems.www.servers.unix", "news", NULL, 0, "comp.infosystems.www.servers.unix", NULL, NULL, NULL }, { "tel:+1-816-555-1212", "tel", NULL, 0, "+1-816-555-1212", NULL, NULL, NULL }, { "telnet://192.0.2.16:80/", "telnet", "192.0.2.16", 80, "/", NULL, NULL, NULL }, { "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", "urn", NULL, 0, "oasis:names:specification:docbook:dtd:xml:4.1.2", NULL}, /* userinfo */ { "ftp://jim:bob@jim.com", "ftp", "jim.com", 0, "/", "jim:bob", NULL, NULL }, { "ldap://fred:bloggs@fish.com/foobar", "ldap", "fish.com", 0, "/foobar", "fred:bloggs", NULL, NULL }, /* IPv6 literals: */ { "http://[::1]/foo", "http", "[::1]", 0, "/foo", NULL, NULL, NULL }, { "http://[a:a:a:a::0]/foo", "http", "[a:a:a:a::0]", 0, "/foo", NULL, NULL, NULL }, { "http://[::1]:8080/bar", "http", "[::1]", 8080, "/bar", NULL, NULL, NULL }, { "ftp://[feed::cafe]:555", "ftp", "[feed::cafe]", 555, "/", NULL, NULL, NULL }, { "DAV:", "DAV", NULL, 0, "", NULL, NULL, NULL }, /* Some odd cases: heir-part and relative-ref will both match * with a zero-length expansion of "authority" (since * * reg-name can be zero-length); so a triple-slash URI-ref * will be matched as "//" followed by a zero-length authority * followed by a path of "/". */ { "foo:///", "foo", "", 0, "/", NULL, NULL, NULL }, { "///", NULL, "", 0, "/", NULL, NULL, NULL }, /* port grammar is "*DIGIT" so may be empty: */ { "ftp://[feed::cafe]:", "ftp", "[feed::cafe]", 0, "/", NULL, NULL, NULL }, { "ftp://[feed::cafe]:/", "ftp", "[feed::cafe]", 0, "/", NULL, NULL, NULL }, { "http://foo:/", "http", "foo", 0, "/", NULL, NULL, NULL }, /* URI-references: */ { "//foo.com/bar", NULL, "foo.com", 0, "/bar", NULL, NULL, NULL }, { "//foo.com", NULL, "foo.com", 0, "/", NULL, NULL, NULL }, { "//[::1]/foo", NULL, "[::1]", 0, "/foo", NULL, NULL, NULL }, { "/bar", NULL, NULL, 0, "/bar", NULL, NULL, NULL }, /* path-absolute */ { "foo/bar", NULL, NULL, 0, "foo/bar", NULL, NULL, NULL }, /* path-noscheme */ { "", NULL, NULL, 0, "", NULL, NULL, NULL }, /* path-empty */ /* CVE-2007-0157: buffer under-read in 0.26.[012]. */ { "http://webdav.org\xFF", "http", "webdav.org\xFF", 0, "/", NULL, NULL, NULL }, { NULL } }; int n; for (n = 0; uritests[n].uri != NULL; n++) { ne_uri res; const struct test_uri *e = &uritests[n]; ONV(ne_uri_parse(e->uri, &res) != 0, ("'%s': parse failed", e->uri)); ONV(res.port != e->port, ("'%s': parsed port was %d not %d", e->uri, res.port, e->port)); ONCMP(e->scheme, res.scheme, e->uri, "scheme"); ONCMP(e->host, res.host, e->uri, "host"); ONV(strcmp(res.path, e->path), ("'%s': parsed path was '%s' not '%s'", e->uri, res.path, e->path)); ONCMP(e->userinfo, res.userinfo, e->uri, "userinfo"); ONCMP(e->query, res.query, e->uri, "query"); ONCMP(e->fragment, res.fragment, e->uri, "fragment"); ne_uri_free(&res); } return OK; } static int failparse(void) { static const char *uris[] = { "http://[::1/", "http://[::1]f:80/", "http://[::1]]:80/", "http://foo/bar asda", "http://fish/[foo]/bar", NULL }; int n; for (n = 0; uris[n] != NULL; n++) { ne_uri p; ONV(ne_uri_parse(uris[n], &p) == 0, ("`%s' did not fail to parse", uris[n])); ne_uri_free(&p); } return 0; } static int unparse(void) { const char *uris[] = { "http://foo.com/bar", "https://bar.com/foo/wishbone", "http://www.random.com:8000/", "http://[::1]:8080/", "ftp://ftp.foo.bar/abc/def", "ftp://joe@bar.com/abc/def", "http://a/b?c#d", "http://a/b?c", "http://a/b#d", "mailto:foo@bar.com", "//foo.com/bar", "//foo.com:8080/bar", NULL }; int n; for (n = 0; uris[n] != NULL; n++) { ne_uri parsed; char *unp; ONV(ne_uri_parse(uris[n], &parsed), ("failed to parse %s", uris[n])); if (parsed.port == 0 && parsed.scheme) parsed.port = ne_uri_defaultport(parsed.scheme); unp = ne_uri_unparse(&parsed); ONV(strcmp(unp, uris[n]), ("unparse got %s from %s", unp, uris[n])); ne_uri_free(&parsed); ne_free(unp); } return OK; } #define BASE "http://a/b/c/d;p?q" static int resolve(void) { static const struct { const char *base, *relative, *expected; } ts[] = { /* Examples from RFC39865.4: */ { BASE, "g:h", "g:h" }, { BASE, "g", "http://a/b/c/g" }, { BASE, "./g", "http://a/b/c/g" }, { BASE, "g/", "http://a/b/c/g/" }, { BASE, "/g", "http://a/g" }, { BASE, "//g", "http://g/" }, /* NOTE: modified to mandate non-empty path */ { BASE, "?y", "http://a/b/c/d;p?y" }, { BASE, "g?y", "http://a/b/c/g?y" }, { BASE, "#s", "http://a/b/c/d;p?q#s" }, { BASE, "g#s", "http://a/b/c/g#s" }, { BASE, "g?y#s", "http://a/b/c/g?y#s" }, { BASE, ";x", "http://a/b/c/;x" }, { BASE, "g;x", "http://a/b/c/g;x" }, { BASE, "g;x?y#s", "http://a/b/c/g;x?y#s" }, { BASE, "", "http://a/b/c/d;p?q" }, { BASE, ".", "http://a/b/c/" }, { BASE, "./", "http://a/b/c/" }, { BASE, "..", "http://a/b/" }, { BASE, "../", "http://a/b/" }, { BASE, "../g", "http://a/b/g" }, { BASE, "../..", "http://a/" }, { BASE, "../../", "http://a/" }, { BASE, "../../g", "http://a/g" }, { BASE, "../../../g", "http://a/g" }, { BASE, "../../../../g", "http://a/g" }, { BASE, "/./g", "http://a/g" }, { BASE, "/../g", "http://a/g" }, { BASE, "g.", "http://a/b/c/g." }, { BASE, ".g", "http://a/b/c/.g" }, { BASE, "g..", "http://a/b/c/g.." }, { BASE, "..g", "http://a/b/c/..g" }, { BASE, "./../g", "http://a/b/g" }, { BASE, "./g/.", "http://a/b/c/g/" }, { BASE, "g/./h", "http://a/b/c/g/h" }, { BASE, "g/../h", "http://a/b/c/h" }, { BASE, "g;x=1/./y", "http://a/b/c/g;x=1/y" }, { BASE, "g;x=1/../y", "http://a/b/c/y" }, { BASE, "g?y/./x", "http://a/b/c/g?y/./x" }, { BASE, "g?y/../x", "http://a/b/c/g?y/../x" }, { BASE, "g#s/./x", "http://a/b/c/g#s/./x" }, { BASE, "g#s/../x", "http://a/b/c/g#s/../x" }, { BASE, "http:g", "http:g" }, /* Additional examples: */ { BASE, ".", "http://a/b/c/" }, { "http://foo.com/alpha/beta", "../gamma", "http://foo.com/gamma" }, { "http://foo.com/alpha//beta", "../gamma", "http://foo.com/alpha/gamma" }, { "http://foo.com", "../gamma", "http://foo.com/gamma" }, { "", "zzz:.", "zzz:" }, { "", "zzz:./foo", "zzz:foo" }, { "", "zzz:../foo", "zzz:foo" }, { "", "zzz:/./foo", "zzz:/foo" }, { "", "zzz:/.", "zzz:/" }, { "", "zzz:/../", "zzz:/" }, { "", "zzz:.", "zzz:" }, { "", "zzz:..", "zzz:" }, { "", "zzz://foo@bar/", "zzz://foo@bar/" }, { "", "zzz://foo/?bar", "zzz://foo/?bar" }, { "zzz://foo/?bar", "//baz/?jam", "zzz://baz/?jam" }, { "zzz://foo/baz?biz", "", "zzz://foo/baz?biz" }, { "zzz://foo/baz", "", "zzz://foo/baz" }, { "//foo/baz", "", "//foo/baz" }, { NULL, NULL, NULL } }; size_t n; for (n = 0; ts[n].base; n++) { ne_uri base, relative, resolved; char *actual; ONV(ne_uri_parse(ts[n].base, &base), ("could not parse base URI '%s'", ts[n].base)); ONV(ne_uri_parse(ts[n].relative, &relative), ("could not parse input URI '%s'", ts[n].relative)); ONN("bad pointer was returned", ne_uri_resolve(&base, &relative, &resolved) != &resolved); ONN("NULL path after resolve", resolved.path == NULL); actual = ne_uri_unparse(&resolved); ONCMP(ts[n].expected, actual, ts[n].relative, "output mismatch"); ne_uri_free(&relative); ne_uri_free(&resolved); ne_uri_free(&base); ne_free(actual); } return OK; } static int copy(void) { static const char *ts[] = { "http://jim@foo.com:8080/bar?baz#bee", "", NULL, }; size_t n; for (n = 0; ts[n]; n++) { ne_uri parsed, parsed2; char *actual; ONV(ne_uri_parse(ts[n], &parsed), ("could not parse URI '%s'", ts[n])); ONN("ne_uri_copy returned wrong pointer", ne_uri_copy(&parsed2, &parsed) != &parsed2); actual = ne_uri_unparse(&parsed2); ONCMP(ts[n], actual, "copied URI", "unparsed URI"); ne_uri_free(&parsed2); ne_uri_free(&parsed); ne_free(actual); } return OK; } ne_test tests[] = { T(simple), T(simple_ssl), T(no_path), T(escapes), T(parents), T(compares), T(cmp), T(children), T(slash), T(default_port), T(parse), T(failparse), T(unparse), T(resolve), T(copy), T(NULL) }; davix-R_0_5_0/deps/libneon/test/util-socks.c000066400000000000000000000214641257152637300210750ustar00rootroot00000000000000/* SOCKS server utils. Copyright (C) 2008, 2009, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include /* for time() */ #include "ne_socket.h" #include "ne_utils.h" #include "ne_alloc.h" #include "child.h" #include "tests.h" #include "utils.h" #define V5_METH_NONE 0x00 #define V5_METH_AUTH 0x02 #define V5_ADDR_IPV4 0x01 #define V5_ADDR_FQDN 0x03 #define V5_ADDR_IPV6 0x04 static int read_socks_string(ne_socket *sock, const char *ctx, unsigned char *buf, unsigned int *olen) { unsigned char len; ssize_t ret; ret = ne_sock_read(sock, (char *)&len, 1); ONV(ret != 1, ("%s length read failed: %s", ctx, ne_sock_error(sock))); ONV(len == 0, ("%s gave zero-length string", ctx)); ret = ne_sock_fullread(sock, (char *)buf, len); ONV(ret != 0, ("%s string read failed, got %" NE_FMT_SSIZE_T " bytes (%s)", ctx, ret, ne_sock_error(sock))); *olen = len; return OK; } static int read_socks_byte(ne_socket *sock, const char *ctx, unsigned char *buf) { ONV(ne_sock_read(sock, (char *)buf, 1) != 1, ("%s byte read failed: %s", ctx, ne_sock_error(sock))); return OK; } static int expect_socks_byte(ne_socket *sock, const char *ctx, unsigned char c) { unsigned char b; CALL(read_socks_byte(sock, ctx, &b)); ONV(b != c, ("%s got byte %hx not %hx", ctx, b, c)); return OK; } static int read_socks_0string(ne_socket *sock, const char *ctx, unsigned char *buf, unsigned *len) { unsigned char *end = buf + *len, *p = buf; while (p < end) { CALL(read_socks_byte(sock, ctx, p)); if (*p == '\0') break; p++; } *len = p - buf; return OK; } int socks_server(ne_socket *sock, void *userdata) { struct socks_server *srv = userdata; unsigned char buf[1024]; unsigned int len, port, version; unsigned char atype; ssize_t ret; version = srv->version == NE_SOCK_SOCKSV5 ? 5 : 4; ne_sock_read_timeout(sock, 5); CALL(expect_socks_byte(sock, "client version", version)); if (version != 5) { unsigned char raw[16]; CALL(expect_socks_byte(sock, "v4 command", 0x01)); ret = ne_sock_fullread(sock, (char *)buf, 6); ONV(ret != 0, ("v4 address read failed with %" NE_FMT_SSIZE_T " (%s)", ret, ne_sock_error(sock))); ONN("bad v4A bogus address", srv->version == NE_SOCK_SOCKSV4A && srv->expect_addr == NULL && memcmp(buf + 2, "\0\0\0", 3) != 0 && buf[6] != 0); ONN("v4 server with no expected address! fail", srv->version == NE_SOCK_SOCKSV4 && srv->expect_addr == NULL); if (srv->expect_addr) { ONN("v4 address mismatch", memcmp(ne_iaddr_raw(srv->expect_addr, raw), buf + 2, 4) != 0); } port = (buf[0] << 8) | buf[1]; ONV(port != srv->expect_port, ("got bad v4 port %u, expected %u", port, srv->expect_port)); len = sizeof buf; CALL(read_socks_0string(sock, "v4 username read", buf, &len)); ONV(srv->username == NULL && len, ("unexpected v4 username %s", buf)); ONV(srv->username && !len, ("no v4 username given, expected %s", srv->username)); ONV(srv->username && len && strcmp(srv->username, (char *)buf), ("bad v4 username, expected %s got %s", srv->username, buf)); if (srv->expect_addr == NULL) { len = sizeof buf; CALL(read_socks_0string(sock, "v4A hostname read", buf, &len)); ONV(strcmp(srv->expect_fqdn, (char *)buf) != 0, ("bad v4A hostname: %s not %s", buf, srv->expect_fqdn)); } { static const char msg[] = "\x00\x5A" "\x00\x00" "\x00\x00\x00\x00" "ok!\n"; if (srv->say_hello) CALL(full_write(sock, msg, 12)); else CALL(full_write(sock, msg, 8)); } return srv->server(sock, srv->userdata); } CALL(read_socks_string(sock, "client method list", buf, &len)); if (srv->failure == fail_init_vers) { CALL(full_write(sock, "\x01\x02", 2)); return OK; } else if (srv->failure == fail_init_close) { return OK; } else if (srv->failure == fail_init_trunc) { CALL(full_write(sock, "\x05", 1)); return OK; } else if (srv->failure == fail_no_auth) { CALL(full_write(sock, "\x05\xff", 2)); return OK; } else if (srv->failure == fail_bogus_auth) { CALL(full_write(sock, "\x05\xfe", 2)); return OK; } ONN("client did not advertise no-auth method", memchr(buf, V5_METH_NONE, len) == NULL); if (srv->username) { int match = 0; ONN("client did not advertise authn method", memchr(buf, V5_METH_AUTH, len) == NULL); CALL(full_write(sock, "\x05\x02", 2)); CALL(expect_socks_byte(sock, "client auth version", 0x01)); CALL(read_socks_string(sock, "client username", buf, &len)); match = len == strlen(srv->username) && memcmp(buf, srv->username, len) == 0; CALL(read_socks_string(sock, "client password", buf, &len)); match = match && len == strlen(srv->password) && memcmp(buf, srv->password, len) == 0; if (srv->failure == fail_auth_close) { return OK; } if (match && srv->failure != fail_auth_denied) { CALL(full_write(sock, "\x01\x00", 2)); } else { CALL(full_write(sock, "\x01\x01", 2)); } if (srv->failure == fail_auth_denied) { return OK; } } else { CALL(full_write(sock, "\x05\x00", 2)); } CALL(expect_socks_byte(sock, "command version", version)); CALL(expect_socks_byte(sock, "command number", 0x01)); CALL(read_socks_byte(sock, "reserved byte", buf)); CALL(read_socks_byte(sock, "address type", &atype)); ONN("bad address type byte", (atype != V5_ADDR_IPV4 && atype != V5_ADDR_IPV6 && atype != V5_ADDR_FQDN)); if (atype == V5_ADDR_FQDN) { ONN("unexpected FQDN from client", srv->expect_fqdn == NULL); CALL(read_socks_string(sock, "read FQDN", buf, &len)); ONV(len != strlen(srv->expect_fqdn) || memcmp(srv->expect_fqdn, buf, len) != 0, ("FQDN mismatch: %.*s not %s", len, buf, srv->expect_fqdn)); } else { unsigned char raw[16]; ONN("unexpected IP literal from client", srv->expect_addr == NULL); ONV((atype == V5_ADDR_IPV4 && ne_iaddr_typeof(srv->expect_addr) != ne_iaddr_ipv4) || (atype == V5_ADDR_IPV6 && ne_iaddr_typeof(srv->expect_addr) != ne_iaddr_ipv6), ("address type mismatch: %hx not %d", atype, ne_iaddr_typeof(srv->expect_addr))); len = atype == V5_ADDR_IPV4 ? 4 : 16; ret = ne_sock_fullread(sock, (char *)buf, len); ONV(ret != 0, ("address read failed with %" NE_FMT_SSIZE_T " (%s)", ret, ne_sock_error(sock))); ne_iaddr_raw(srv->expect_addr, raw); ONN("address mismatch", memcmp(raw, buf, len) != 0); } CALL(read_socks_byte(sock, "port high byte", buf)); CALL(read_socks_byte(sock, "port low byte", buf + 1)); port = (buf[0] << 8) | buf[1]; ONV(port != srv->expect_port, ("got bad port %u, expected %u", port, srv->expect_port)); { static const char msg[] = "\x05\x00\x00" "\x01" "\x00\x00\x00\x00" "\x00\x00" "ok!\n"; if (srv->say_hello) CALL(full_write(sock, msg, 14)); else CALL(full_write(sock, msg, 10)); } return srv->server(sock, srv->userdata); } davix-R_0_5_0/deps/libneon/test/util-tests.c000066400000000000000000000207271257152637300211160ustar00rootroot00000000000000/* utils tests Copyright (C) 2001-2006, Joe Orton 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 "config.h" #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include "ne_utils.h" #include "ne_md5.h" #include "ne_alloc.h" #include "ne_dates.h" #include "ne_string.h" #include "tests.h" static const struct { const char *status; int major, minor, code; const char *rp; } accept_sl[] = { /* These are really valid. */ { "HTTP/1.1 200 OK", 1, 1, 200, "OK" }, { "HTTP/1.1000 200 OK", 1, 1000, 200, "OK" }, { "HTTP/1000.1000 200 OK", 1000, 1000, 200, "OK" }, { "HTTP/00001.1 200 OK", 1, 1, 200, "OK" }, { "HTTP/1.00001 200 OK", 1, 1, 200, "OK" }, { "HTTP/99.99 999 99999", 99, 99, 999, "99999" }, { "HTTP/1.1 100 ", 1, 1, 100, "" }, /* these aren't really valid but we should be able to parse them. */ { "HTTP/1.1 100", 1, 1, 100, "" }, { "HTTP/1.1 200 OK", 1, 1, 200, "OK" }, { "HTTP/1.1 200 \t OK", 1, 1, 200, "OK" }, { " HTTP/1.1 200 OK", 1, 1, 200, "OK" }, { "Norman is a dog HTTP/1.1 200 OK", 1, 1, 200, "OK" }, { NULL } }; static const char *bad_sl[] = { "", "HTTP/1.1 1000 OK", "HTTP/1.1 1000", "HTTP/-1.1 100 OK", "HTTP/1.1 -100 OK", "HTTP/ 200 OK", "HTTP/", "HTTP/1.1A 100 OK", "HTTP/1.", "HTTP/1.1 1", "Fish/1.1 100 OK", "HTTP/1.1 10", "HTTP", "H\0TP/1.1 100 OK", NULL }; static int status_lines(void) { ne_status s; int n; for (n = 0; accept_sl[n].status != NULL; n++) { ONV(ne_parse_statusline(accept_sl[n].status, &s), ("valid #%d: parse", n)); ONV(accept_sl[n].major != s.major_version, ("valid #%d: major", n)); ONV(accept_sl[n].minor != s.minor_version, ("valid #%d: minor", n)); ONV(accept_sl[n].code != s.code, ("valid #%d: code", n)); ONV(strcmp(accept_sl[n].rp, s.reason_phrase), ("valid #%d: reason phrase", n)); ne_free(s.reason_phrase); } for (n = 0; bad_sl[n] != NULL; n++) { ONV(ne_parse_statusline(bad_sl[n], &s) == 0, ("invalid #%d", n)); } return OK; } /* Write MD5 of 'len' bytes of 'str' to 'digest' */ static unsigned char *digest_md5(const char *data, size_t len, unsigned int digest[4]) { struct ne_md5_ctx *ctx; #define CHUNK 100 ctx = ne_md5_create_ctx(); /* exercise the buffering interface */ while (len > CHUNK) { ne_md5_process_bytes(data, CHUNK, ctx); len -= CHUNK; data += CHUNK; } ne_md5_process_bytes(data, len, ctx); ne_md5_finish_ctx(ctx, digest); ne_md5_destroy_ctx(ctx); return (unsigned char *)digest; } static int md5(void) { unsigned int buf[4], buf2[4] = {0}; char ascii[33] = {0}; char zzzs[500]; ne_md5_to_ascii(digest_md5("", 0, buf), ascii); ONN("MD5(null)", strcmp(ascii, "d41d8cd98f00b204e9800998ecf8427e")); ne_md5_to_ascii(digest_md5("foobar", 7, buf), ascii); ONN("MD5(foobar)", strcmp(ascii, "b4258860eea29e875e2ee4019763b2bb")); /* $ perl -e 'printf "z"x500' | md5sum * 8b9323bd72250ea7f1b2b3fb5046391a - */ memset(zzzs, 'z', sizeof zzzs); ne_md5_to_ascii(digest_md5(zzzs, sizeof zzzs, buf), ascii); ONN("MD5(\"z\"x512)", strcmp(ascii, "8b9323bd72250ea7f1b2b3fb5046391a")); ne_ascii_to_md5(ascii, (unsigned char *)buf2); ON(memcmp(buf, buf2, 16)); return OK; } static int md5_alignment(void) { char *bb = ne_malloc(66); struct ne_md5_ctx *ctx; /* regression test for a bug in md5.c in <0.15.0 on SPARC, where * the process_bytes function would SIGBUS if the buffer argument * isn't 32-bit aligned. Won't trigger on x86 though. */ ctx = ne_md5_create_ctx(); ne_md5_process_bytes(bb + 1, 65, ctx); ne_md5_destroy_ctx(ctx); ne_free(bb); return OK; } static const struct { const char *str; time_t time; enum { d_rfc1123, d_iso8601, d_rfc1036 } type; } good_dates[] = { { "Fri, 08 Jun 2001 22:59:46 GMT", 992041186, d_rfc1123 }, { "Friday, 08-Jun-01 22:59:46 GMT", 992041186, d_rfc1036 }, { "Wednesday, 06-Jun-01 22:59:46 GMT", 991868386, d_rfc1036 }, /* some different types of ISO8601 dates. */ { "2001-06-08T22:59:46Z", 992041186, d_iso8601 }, { "2001-06-08T22:59:46.9Z", 992041186, d_iso8601 }, { "2001-06-08T26:00:46+03:01", 992041186, d_iso8601 }, { "2001-06-08T20:58:46-02:01", 992041186, d_iso8601 }, { NULL } }; static int parse_dates(void) { int n; for (n = 0; good_dates[n].str != NULL; n++) { time_t res; const char *str = good_dates[n].str; switch (good_dates[n].type) { case d_rfc1036: res = ne_rfc1036_parse(str); break; case d_iso8601: res = ne_iso8601_parse(str); break; case d_rfc1123: res = ne_rfc1123_parse(str); break; default: res = -1; break; } ONV(res == -1, ("date %d parse", n)); #define FT "%" NE_FMT_TIME_T ONV(res != good_dates[n].time, ( "date %d incorrect (" FT " not " FT ")", n, res, good_dates[n].time)); } return OK; } /* trigger segfaults in ne_rfc1036_parse() in <=0.24.5. */ static int regress_dates(void) { static const char *dates[] = { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" }; size_t n; for (n = 0; n < sizeof(dates)/sizeof(dates[0]); n++) { ne_rfc1036_parse(dates[n]); ne_iso8601_parse(dates[n]); ne_rfc1123_parse(dates[n]); } return OK; } #define GOOD(n,m,msg) ONV(ne_version_match(n,m), \ ("match of " msg " failed (%d.%d)", n, m)) #define BAD(n,m,msg) ONV(ne_version_match(n,m) == 0, \ ("match of " msg " succeeded (%d.%d)", n, m)) static int versioning(void) { GOOD(NE_VERSION_MAJOR, NE_VERSION_MINOR, "current version"); BAD(NE_VERSION_MAJOR + 1, 0, "later major"); BAD(NE_VERSION_MAJOR, NE_VERSION_MINOR + 1, "later minor"); #if NE_VERSION_MAJOR > 0 BAD(NE_VERSION_MAJOR - 1, 0, "earlier major"); #if NE_VERSION_MINOR > 0 GOOD(NE_VERSION_MAJOR, NE_VERSION_MINOR - 1, "earlier minor"); #endif /* NE_VERSION_MINOR > 0 */ #else /* where NE_VERSION_MAJOR == 0 */ BAD(0, NE_VERSION_MINOR - 1, "earlier minor for 0.x"); #endif return OK; } #undef GOOD #undef BAD /* basic ne_version_string() sanity tests */ static int version_string(void) { char buf[1024]; ne_snprintf(buf, sizeof buf, "%s", ne_version_string()); NE_DEBUG(NE_DBG_HTTP, "Version string: %s\n", buf); ONN("version string too long", strlen(buf) > 200); ONN("version string contained newline", strchr(buf, '\n') != NULL); return OK; } static int support(void) { #ifdef NE_HAVE_SSL ONN("SSL support not advertised", !ne_has_support(NE_FEATURE_SSL)); #else ONN("SSL support advertised", ne_has_support(NE_FEATURE_SSL)); #endif #ifdef NE_HAVE_ZLIB ONN("zlib support not advertised", !ne_has_support(NE_FEATURE_ZLIB)); #else ONN("zlib support advertised", ne_has_support(NE_FEATURE_ZLIB)); #endif #ifdef NE_HAVE_IPV6 ONN("IPv6 support not advertised", !ne_has_support(NE_FEATURE_IPV6)); #else ONN("IPv6 support advertised", ne_has_support(NE_FEATURE_IPV6)); #endif #ifdef NE_HAVE_LFS ONN("LFS support not advertised", !ne_has_support(NE_FEATURE_LFS)); #else ONN("LFS support advertised", ne_has_support(NE_FEATURE_LFS)); #endif #ifdef NE_HAVE_TS_SSL ONN("Thread-safe SSL support not advertised", !ne_has_support(NE_FEATURE_TS_SSL)); #else ONN("Thread-safe SSL support advertised", ne_has_support(NE_FEATURE_TS_SSL)); #endif #ifdef NE_HAVE_I18N ONN("i18n support not advertised", !ne_has_support(NE_FEATURE_I18N)); #else ONN("i18n SSL support advertised", ne_has_support(NE_FEATURE_I18N)); #endif return OK; } ne_test tests[] = { T(status_lines), T(md5), T(md5_alignment), T(parse_dates), T(regress_dates), T(versioning), T(version_string), T(support), T(NULL) }; davix-R_0_5_0/deps/libneon/test/utils.c000066400000000000000000000110361257152637300201320ustar00rootroot00000000000000/* Utility functions for HTTP client tests Copyright (C) 2001-2008, Joe Orton 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 "config.h" #ifdef HAVE_UNISTD_H #include /* for sleep() */ #endif #ifdef HAVE_STDLIB_H #include #endif #include "ne_session.h" #include "child.h" #include "tests.h" #include "utils.h" int make_session(ne_session **sess, server_fn fn, void *ud) { *sess = ne_session_create("http", "localhost", 7777); return spawn_server(7777, fn, ud); } static int serve_response(ne_socket *s, const char *response) { CALL(discard_request(s)); CALL(discard_body(s)); ONN("failed to send response", SEND_STRING(s, response)); return OK; } int single_serve_string(ne_socket *s, void *userdata) { const char *str = userdata; return serve_response(s, str); } int double_serve_sstring(ne_socket *s, void *userdata) { struct double_serve_args *args = userdata; struct string *str; CALL(discard_request(s)); CALL(discard_body(s)); str = &args->first; NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", (int)str->len, str->data); ONN("write failed", ne_sock_fullwrite(s, str->data, str->len)); CALL(discard_request(s)); CALL(discard_body(s)); str = &args->second; NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", (int)str->len, str->data); ONN("write failed", ne_sock_fullwrite(s, str->data, str->len)); return OK; } int sleepy_server(ne_socket *sock, void *userdata) { sleep(10); return 0; } int many_serve_string(ne_socket *s, void *userdata) { int n; struct many_serve_args *args = userdata; for (n = 0; n < args->count; n++) { NE_DEBUG(NE_DBG_HTTP, "Serving response %d\n", n); CALL(serve_response(s, args->str)); } return OK; } int any_request(ne_session *sess, const char *uri) { ne_request *req = ne_request_create(sess, "GET", uri); int ret = ne_request_dispatch(req); ne_request_destroy(req); return ret; } int any_2xx_request(ne_session *sess, const char *uri) { ne_request *req = ne_request_create(sess, "GET", uri); int ret = ne_request_dispatch(req); int klass = ne_get_status(req)->klass; ne_request_destroy(req); ONV(ret != NE_OK || klass != 2, ("request failed: %s", ne_get_error(sess))); return ret; } int any_2xx_request_body(ne_session *sess, const char *uri) { ne_request *req = ne_request_create(sess, "GET", uri); #define BSIZE 5000 char *body = memset(ne_malloc(BSIZE), 'A', BSIZE); int ret; ne_set_request_body_buffer(req, body, BSIZE); ret = ne_request_dispatch(req); ne_free(body); ONV(ret != NE_OK || ne_get_status(req)->klass != 2, ("request failed: %s", ne_get_error(sess))); ne_request_destroy(req); return ret; } int serve_sstring(ne_socket *sock, void *ud) { struct string *str = ud; NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", (int)str->len, str->data); ONN("write failed", ne_sock_fullwrite(sock, str->data, str->len)); return 0; } int serve_sstring_slowly(ne_socket *sock, void *ud) { struct string *str = ud; size_t n; NE_DEBUG(NE_DBG_SOCKET, "Slowly serving string: [[[%.*s]]]\n", (int)str->len, str->data); for (n = 0; n < str->len; n++) { ONN("write failed", ne_sock_fullwrite(sock, &str->data[n], 1)); minisleep(); } return 0; } int serve_infinite(ne_socket *sock, void *ud) { struct infinite *i = ud; CALL(discard_request(sock)); SEND_STRING(sock, i->header); while (server_send(sock, i->repeat, strlen(i->repeat)) == 0) /* nullop */; return OK; } int full_write(ne_socket *sock, const char *data, size_t len) { int ret = ne_sock_fullwrite(sock, data, len); NE_DEBUG(NE_DBG_SOCKET, "wrote: [%.*s]\n", (int)len, data); ONV(ret, ("write failed (%d): %s", ret, ne_sock_error(sock))); return OK; } davix-R_0_5_0/deps/libneon/test/utils.h000066400000000000000000000063531257152637300201450ustar00rootroot00000000000000/* neon-specific test utils Copyright (C) 2001-2008, Joe Orton 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 UTILS_H #define UTILS_H 1 #include "ne_request.h" #include "child.h" #define ONREQ(x) do { int _ret = (x); if (_ret) { t_context("line %d: HTTP error:\n%s", __LINE__, ne_get_error(sess)); return FAIL; } } while (0); int single_serve_string(ne_socket *s, void *userdata); struct many_serve_args { int count; const char *str; }; /* Serves args->str response args->count times down a single * connection. */ int many_serve_string(ne_socket *s, void *userdata); /* Run a request using URI on the session. */ int any_request(ne_session *sess, const char *uri); /* Run a request using URI on the session; fail on a non-2xx response. */ int any_2xx_request(ne_session *sess, const char *uri); /* As above but with a request body. */ int any_2xx_request_body(ne_session *sess, const char *uri); /* makes *session, spawns server which will run 'fn(userdata, * socket)'. sets error context if returns non-zero, i.e use like: * CALL(make_session(...)); */ int make_session(ne_session **sess, server_fn fn, void *userdata); /* Server which sleeps for 10 seconds then closes the socket. */ int sleepy_server(ne_socket *sock, void *userdata); struct string { char *data; size_t len; }; struct double_serve_args { struct string first, second; }; /* Serve a struct string. */ int serve_sstring(ne_socket *sock, void *ud); /* Discards an HTTP request, serves response ->first, discards another * HTTP request, then serves response ->second. */ int double_serve_sstring(ne_socket *s, void *userdata); /* Serve a struct string slowly. */ int serve_sstring_slowly(ne_socket *sock, void *ud); struct infinite { const char *header, *repeat; }; /* Pass a "struct infinite *" as userdata, this function sends * ->header and then loops sending ->repeat forever. */ int serve_infinite(ne_socket *sock, void *ud); /* SOCKS server stuff. */ struct socks_server { enum ne_sock_sversion version; enum socks_failure { fail_none = 0, fail_init_vers, fail_init_close, fail_init_trunc, fail_no_auth, fail_bogus_auth, fail_auth_close, fail_auth_denied } failure; unsigned int expect_port; ne_inet_addr *expect_addr; const char *expect_fqdn; const char *username; const char *password; int say_hello; server_fn server; void *userdata; }; int socks_server(ne_socket *sock, void *userdata); int full_write(ne_socket *sock, const char *data, size_t len); #endif /* UTILS_H */ davix-R_0_5_0/deps/libneon/test/xml.c000066400000000000000000000454621257152637300176040ustar00rootroot00000000000000/* neon test suite Copyright (C) 2002-2007, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_xml.h" #include "tests.h" #include "child.h" #include "utils.h" #define ABORT (-42) /* magic code for abort handlers */ #define EVAL_DEFAULT "eval-xmlns-default" #define EVAL_SPECIFIC "eval-xmlns-specific-" struct context { ne_buffer *buf; ne_xml_parser *parser; }; /* A set of SAX handlers which serialize SAX events back into a * pseudo-XML-like string. */ static int startelm(void *userdata, int state, const char *nspace, const char *name, const char **atts) { struct context *ctx = userdata; ne_buffer *buf = ctx->buf; int n; if (strcmp(name, "decline") == 0) return NE_XML_DECLINE; if (strcmp(name, EVAL_DEFAULT) == 0) { const char *val = ne_xml_resolve_nspace(ctx->parser, NULL, 0); ne_buffer_concat(ctx->buf, EVAL_DEFAULT "=[", val, "]", NULL); return NE_XML_DECLINE; } else if (strncmp(name, EVAL_SPECIFIC, strlen(EVAL_SPECIFIC)) == 0) { const char *which = name + strlen(EVAL_SPECIFIC); const char *r = ne_xml_resolve_nspace(ctx->parser, which, strlen(which)); ne_buffer_concat(ctx->buf, name, "=[", r, "]", NULL); return NE_XML_DECLINE; } ne_buffer_concat(buf, "<", "{", nspace, "}", name, NULL); for (n = 0; atts && atts[n] != NULL; n+=2) { ne_buffer_concat(buf, " ", atts[n], "='", atts[n+1], "'", NULL); } ne_buffer_zappend(buf, ">"); return state + 1; } static int chardata(void *userdata, int state, const char *cdata, size_t len) { struct context *ctx = userdata; ne_buffer_append(ctx->buf, cdata, len); return strncmp(cdata, "!ABORT!", len) == 0 ? ABORT : NE_XML_DECLINE; } static int endelm(void *userdata, int state, const char *nspace, const char *name) { struct context *ctx = userdata; ne_buffer_concat(ctx->buf, "", NULL); return 0; } /* A set of SAX handlers which do as above, but change some element * names; used to check nested SAX handling is working properly. */ static int startelm_xform(void *userdata, int state, const char *nspace, const char *name, const char **atts) { if (strcmp(nspace, "two") == 0) return startelm(userdata, state, nspace, "xform", atts); else return NE_XML_DECLINE; } static int endelm_xform(void *userdata, int state, const char *nspace, const char *name) { if (strcmp(nspace, "two") == 0) return endelm(userdata, state, nspace, "xform"); else return NE_XML_DECLINE; } /* A set of SAX handlers which verify that state handling is working * correctly. */ static int startelm_state(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { struct context *ctx = userdata; int n; if (strcmp(nspace, "state") != 0) return NE_XML_DECLINE; for (n = 0; atts[n]; n += 2) { if (strcmp(atts[n], "parent") == 0) { int expected = atoi(atts[n+1]); if (expected != parent) { char err[50]; sprintf(err, "parent state of %s was %d not %d", name, parent, expected); ne_buffer_zappend(ctx->buf, err); } } } return atoi(name+1); } static int endelm_state(void *userdata, int state, const char *nspace, const char *name) { int expected = atoi(name + 1); struct context *ctx = userdata; if (state != expected) ne_buffer_concat(ctx->buf, "wrong state in endelm of ", name, NULL); return 0; } /* A set of SAX handlers which verify that abort handling is working * correctly. */ static int startelm_abort(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { struct context *ctx = userdata; if (strcmp(name, "abort-start") == 0) { ne_buffer_zappend(ctx->buf, "ABORT"); return ABORT; } else return startelm(ctx, parent, nspace, name, atts); } static int endelm_abort(void *userdata, int state, const char *nspace, const char *name) { struct context *ctx = userdata; if (strcmp(name, "abort-end") == 0) { ne_buffer_zappend(ctx->buf, "ABORT"); return ABORT; } else return 0; } /* Test mode for parse_match: */ enum match_type { match_valid = 0, /* test that the parse succeeds */ match_invalid, /* test that the parse fails */ match_nohands, /* test with no handlers registered */ match_encoding, /* test whether the encoding is equal to the result string */ match_chunked /* parse the document one byte at a time */ }; static int parse_match(const char *doc, const char *result, enum match_type t) { const char *origdoc = doc; ne_xml_parser *p = ne_xml_create(); ne_buffer *buf = ne_buffer_create(); int ret; struct context ctx; ctx.buf = buf; ctx.parser = p; if (t == match_invalid) ne_xml_push_handler(p, startelm_abort, chardata, endelm_abort, &ctx); if (t != match_encoding && t != match_nohands) { ne_xml_push_handler(p, startelm_state, NULL, endelm_state, &ctx); ne_xml_push_handler(p, startelm, chardata, endelm, &ctx); ne_xml_push_handler(p, startelm_xform, chardata, endelm_xform, &ctx); } if (t == match_chunked) { do { ret = ne_xml_parse(p, doc++, 1); } while (ret == 0 && *doc); } else { ret = ne_xml_parse(p, doc, strlen(doc)); } if (ret == 0) { ne_xml_parse(p, "", 0); } ONV(ret != ne_xml_failed(p), ("'%s': ne_xml_failed gave %d not %d", origdoc, ne_xml_failed(p), ret)); if (t == match_invalid) ONV(ret != ABORT, ("for '%s': parse got %d not abort failure: %s", origdoc, ret, buf->data)); else ONV(ret, ("for '%s': parse failed: %s", origdoc, ne_xml_get_error(p))); if (t == match_encoding) { const char *enc = ne_xml_doc_encoding(p); ONV(strcmp(enc, result), ("for '%s': encoding was `%s' not `%s'", origdoc, enc, result)); } else if (t == match_valid || t == match_chunked) { ONV(strcmp(result, buf->data), ("for '%s': result mismatch: %s not %s", origdoc, buf->data, result)); } ne_xml_destroy(p); ne_buffer_destroy(buf); return OK; } static int matches(void) { #define PFX "\r\n" #define E(ns, n) "<{" ns "}" n ">" static const struct { const char *in, *out; enum match_type invalid; } ms[] = { /*** Simplest tests ***/ { PFX "", "<{}hello>"}, { PFX "", "<{}hello foo='bar'>"}, /*** Tests for character data handling. ***/ { PFX " world", "<{}hello> world"}, /* test for cdata between elements. */ { PFX "\r\n world", "<{}hello>\n<{}wide> world"}, /* UTF-8 XML Byte Order Mark */ { "\xEF\xBB\xBF" PFX "", "<{}hello>" }, /* UTF-8 XML Byte Order Mark */ { "\xEF\xBB\xBF" PFX "", "<{}hello>", match_chunked }, /* UTF-8 XML Byte Order Mark sans prolog */ { "\xEF\xBB\xBF" "", "<{}hello>" }, /*** Tests for namespace handling. ***/ #define NSA "xmlns:foo='bar'" { PFX "", "<{bar}widget " NSA ">" "" }, /* inherited namespace expansion. */ { PFX "", "<{}widget " NSA ">" E("bar", "norman") ""}, { PFX "" "", "<{}widget " NSA " xmlns:abc='def' xmlns:g='z'>" E("bar", "norman") ""}, /* empty namespace default takes precedence. */ { PFX "" "", "<{foo}widget xmlns='foo'><{}smidgen xmlns=''>" E("", "norman") "" }, /* inherited empty namespace default */ { PFX "", "<{foo}bar xmlns='foo'><{}grok xmlns=''>" E("", "fish") "" }, /* regression test for neon <= 0.23.5 with libxml2, where the * "dereference entities" flag was not set by default. */ { PFX "", "<{}widget foo='no&body'>" }, { PFX "", "<{}widget foo='no body'>" }, /* tests for declined branches */ { PFX "fish" "yesgoodbye", "<{}hello><{}world>yesgoodbye" }, { PFX "fishbar", "<{}hello>" E("", "fish") "" }, /* tests for nested SAX handlers */ { PFX "", "<{two}hello xmlns='two'>" E("two", "xform") ""}, /* test for nspace resolution. */ { PFX "<" EVAL_DEFAULT "/>", "<{fish}hello xmlns='fish'>" EVAL_DEFAULT "=[fish]" "" }, { PFX "<" EVAL_DEFAULT "/>", "<{}hello>" EVAL_DEFAULT "=[]" }, { PFX "<" EVAL_SPECIFIC "foo/>", "<{}hello xmlns:foo='bar'>" EVAL_SPECIFIC "foo=[bar]" }, /* tests for state handling */ { PFX "", "" }, { PFX "", "" }, { PFX "blah", "" }, /* tests for abort handling */ { PFX "", "<{}hello><{}merry>ABORT", match_invalid }, { PFX "fish", "<{}hello><{}merry><{}abort-end>ABORT", match_invalid }, { PFX "!ABORT!", "<{}hello>!ABORT!", match_invalid }, { PFX "!ABORT!", "<{}hello>!ABORT!", match_invalid }, { PFX "!ABORT!", "<{}hello>!ABORT!", match_invalid }, /* tests for encodings */ { "", "ISO-8859-1", match_encoding }, { "", "UTF-8", match_encoding }, /* test that parse is valid even with no handlers registered. */ { PFX "world", "", match_nohands }, /* regression test for prefix matching bug fixed in 0.18.0 */ #define THENS "xmlns:d='foo' xmlns:dd='bar'" { PFX "", "<{foo}hello " THENS ">" }, /**** end of list ****/ { NULL, NULL } }; int n; for (n = 0; ms[n].in != NULL; n++) { CALL(parse_match(ms[n].in, ms[n].out, ms[n].invalid)); } return OK; } static int mapping(void) { static const struct ne_xml_idmap map[] = { { "fee", "bar", 1 }, { "foo", "bar", 2 }, { "bar", "foo", 3 }, { "", "bob", 4 }, { "balloon", "buffoon", 5}, { NULL, NULL, 0} }; int n; for (n = 0; map[n].id; n++) { int id = ne_xml_mapid(map, NE_XML_MAPLEN(map) - 1, map[n].nspace, map[n].name); ONV(id != map[n].id, ("mapped to id %d not %d", id, map[n].id)); } n = ne_xml_mapid(map, NE_XML_MAPLEN(map) - 1, "no-such", "element"); ONV(n != 0, ("unknown element got id %d not zero", n)); return OK; } /* Test for some parse failures */ static int fail_parse(void) { static const char *docs[] = { "foo", PFX "", /* malformed namespace declarations */ PFX "", PFX "", PFX "", PFX "", PFX "", PFX "", /* element names which are not valid QNames. */ PFX "", PFX "<:fee/>", PFX "<0fish/>", PFX "", PFX "", PFX "", PFX "", #if 0 /* currently disabled to allow SVN to work */ PFX "", PFX "", PFX "", PFX "", #endif /* These are tests of XML parser itself really... */ /* 2-byte encoding of '.': */ PFX "" "\x2F\xC0\xAE\x2E\x2F" "", /* 3-byte encoding of '.': */ PFX "" "\x2F\xE0\x80\xAE\x2E\x2F" "", /* 4-byte encoding of '.': */ PFX "" "\x2F\xF0\x80\x80\xAE\x2E\x2F" "", /* 5-byte encoding of '.': */ PFX "" "\x2F\xF8\x80\x80\x80\xAE\x2E\x2F" "", /* 6-byte encoding of '.': */ PFX "" "\x2F\xFC\x80\x80\x80\x80\xAE\x2E\x2F" "", /* two-byte encoding of '<' must not be parsed as a '<': */ PFX "\xC0\xBC" "foo>", /* Invalid UTF-8 XML Byte Order Marks */ "\xEF\xBB" PFX "", "\xEF" PFX "", "\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ]>\ &laugh30;\ ", NULL }; int n; for (n = 0; docs[n]; n++) { ne_xml_parser *p = ne_xml_create(); const char *err; ne_xml_parse(p, docs[n], strlen(docs[n])); ne_xml_parse(p, "", 0); ONV(ne_xml_failed(p) <= 0, ("`%s' did not get positive parse error", docs[n])); err = ne_xml_get_error(p); NE_DEBUG(NE_DBG_HTTP, "Parse error for '%s': %s\n", docs[n], err); ONV(strstr(err, "parse error") == NULL && strstr(err, "Invalid Byte Order Mark") == NULL, ("bad error %s", err)); ne_xml_destroy(p); } return OK; } static int check_attrib(ne_xml_parser *p, const char **atts, const char *nspace, const char *name, const char *value) { const char *act = ne_xml_get_attr(p, atts, nspace, name); char err[50]; int ret = 0; if (value == NULL) { if (act != NULL) { sprintf(err, "attribute %s was set to %s", name, act); ret = NE_XML_ABORT; } } else { if (act == NULL) { sprintf(err, "attribute %s not found", name); ret = NE_XML_ABORT; } else if (strcmp(act, value) != 0) { sprintf(err, "attribute %s was %s not %s", name, act, value); ret = NE_XML_ABORT; } } if (ret == NE_XML_ABORT) ne_xml_set_error(p, err); return ret; } static int startelm_attrib(void *userdata, int state, const char *nspace, const char *name, const char **atts) { ne_xml_parser *p = userdata; if (strcmp(name, "hello") == 0) { CALL(check_attrib(p, atts, NULL, "first", "second")); CALL(check_attrib(p, atts, NULL, "third", "")); CALL(check_attrib(p, atts, "garth", "bar", "asda")); CALL(check_attrib(p, atts, "giraffe", "bar", NULL)); CALL(check_attrib(p, atts, "hot", "dog", NULL)); CALL(check_attrib(p, atts, NULL, "nonesuch", NULL)); } else if (strcmp(name, "goodbye") == 0) { if (atts[0] != NULL) { ne_xml_set_error(p, "non-empty attrib array"); return 1; } } return 1; } static int attributes(void) { ne_xml_parser *p = ne_xml_create(); static const char doc[] = PFX ""; ne_xml_push_handler(p, startelm_attrib, NULL, NULL, p); ne_xml_parse_v(p, doc, strlen(doc)); ONV(ne_xml_failed(p), ("parse error: %s", ne_xml_get_error(p))); ne_xml_destroy(p); return OK; } /* Test for the get/set error interface */ static int errors(void) { ne_xml_parser *p = ne_xml_create(); const char *err; ONV(strcmp(ne_xml_get_error(p), "Unknown error") != 0, ("initial error string unspecified")); ne_xml_set_error(p, "Fish food"); err = ne_xml_get_error(p); ONV(strcmp(err, "Fish food"), ("wrong error %s!", err)); ne_xml_destroy(p); return 0; } ne_test tests[] = { T(matches), T(mapping), T(fail_parse), T(attributes), T(errors), T(NULL) }; davix-R_0_5_0/deps/libneon/test/xmlreq.c000066400000000000000000000114101257152637300202760ustar00rootroot00000000000000/* Test cases for the ne_xmlreq.h interface. Copyright (C) 2005-2006, Joe Orton 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 "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "ne_xmlreq.h" #include "tests.h" #include "utils.h" /* Dummy start_element callback; takes int * userdata and toggles the * pointed-to int iff the root element has name "hello". Accepts all * elements. */ static int startelm(void *userdata, int state, const char *nspace, const char *name, const char **atts) { int *flag = userdata; if (state == NE_XML_STATEROOT && strcmp(name, "hello") == 0) { *flag = !*flag; } return ++state; } static int success(void) { ne_session *sess; ne_request *req; ne_xml_parser *parser; int flag = 0; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 OK\r\n" "Content-Type: text/xml\r\n" "Connection: close\r\n" "\r\n" "\n" "")); req = ne_request_create(sess, "PARSE", "/"); parser = ne_xml_create(); ne_xml_push_handler(parser, startelm, NULL, NULL, &flag); ONREQ(ne_xml_dispatch_request(req, parser)); ONN("XML parser not invoked", !flag); ne_xml_destroy(parser); ne_request_destroy(req); ne_session_destroy(sess); return await_server(); } static int failure(void) { ne_session *sess; ne_request *req; ne_xml_parser *parser; CALL(make_session(&sess, single_serve_string, "HTTP/1.1 200 OK\r\n" "Content-Type: text/xml\r\n" "Connection: close\r\n" "\r\n" "\n" "")); req = ne_request_create(sess, "PARSE", "/"); parser = ne_xml_create(); ONN("XML parse did not fail", ne_xml_dispatch_request(req, parser) == NE_OK); NE_DEBUG(NE_DBG_HTTP, "error string: %s\n", ne_get_error(sess)); ONV(strstr(ne_get_error(sess), "200 OK") != NULL, ("no error string set on parse error: '%s'", ne_get_error(sess))); ne_xml_destroy(parser); ne_request_destroy(req); ne_session_destroy(sess); return await_server(); } static int types(void) { static const struct { const char *type; int is_xml; } ts[] = { { "text/xml", 1 }, { "tExT/XmL", 1 }, { "text/html", 0 }, { "application/foo+xml", 1 }, { "aPpLiCaTION/FoOOO+xMl", 1 }, { "application/xml", 1 }, { "application/+xml", 0 }, { "application/fish+xml2", 0 }, { "foo/bar+xml", 1 }, { "f/b", 0 }, { "garble garble wotsit", 0 } }; unsigned n; for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) { char resp[128]; ne_session *sess; ne_request *req; ne_xml_parser *parser; int flag = 0; ne_snprintf(resp, sizeof resp, "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Connection: close\r\n" "\r\n" "\n" "", ts[n].type); CALL(make_session(&sess, single_serve_string, resp)); req = ne_request_create(sess, "PARSE", "/"); parser = ne_xml_create(); ne_xml_push_handler(parser, startelm, NULL, NULL, &flag); ONREQ(ne_xml_dispatch_request(req, parser)); ONV(flag && !ts[n].is_xml, ("XML parser invoked for non-XML type: %s", ts[n].type)); ONV(!flag && ts[n].is_xml, ("XML parser not invoked for XML type: %s", ts[n].type)); ne_xml_destroy(parser); ne_request_destroy(req); ne_session_destroy(sess); CALL(await_server()); } return OK; } ne_test tests[] = { T(success), T(failure), T(types), T(NULL) }; davix-R_0_5_0/deps/rapidjson/000077500000000000000000000000001257152637300162115ustar00rootroot00000000000000davix-R_0_5_0/deps/rapidjson/include/000077500000000000000000000000001257152637300176345ustar00rootroot00000000000000davix-R_0_5_0/deps/rapidjson/include/rapidjson/000077500000000000000000000000001257152637300216255ustar00rootroot00000000000000davix-R_0_5_0/deps/rapidjson/include/rapidjson/allocators.h000066400000000000000000000173501257152637300241470ustar00rootroot00000000000000#ifndef RAPIDJSON_ALLOCATORS_H_ #define RAPIDJSON_ALLOCATORS_H_ #include "rapidjson.h" namespace rapidjson { /////////////////////////////////////////////////////////////////////////////// // Allocator /*! \class rapidjson::Allocator \brief Concept for allocating, resizing and freeing memory block. Note that Malloc() and Realloc() are non-static but Free() is static. So if an allocator need to support Free(), it needs to put its pointer in the header of memory block. \code concept Allocator { static const bool kNeedFree; //!< Whether this allocator needs to call Free(). // Allocate a memory block. // \param size of the memory block in bytes. // \returns pointer to the memory block. void* Malloc(size_t size); // Resize a memory block. // \param originalPtr The pointer to current memory block. Null pointer is permitted. // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) // \param newSize the new size in bytes. void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); // Free a memory block. // \param pointer to the memory block. Null pointer is permitted. static void Free(void *ptr); }; \endcode */ /////////////////////////////////////////////////////////////////////////////// // CrtAllocator //! C-runtime library allocator. /*! This class is just wrapper for standard C library memory routines. \implements Allocator */ class CrtAllocator { public: static const bool kNeedFree = true; void* Malloc(size_t size) { return malloc(size); } void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); } static void Free(void *ptr) { free(ptr); } }; /////////////////////////////////////////////////////////////////////////////// // MemoryPoolAllocator //! Default memory allocator used by the parser and DOM. /*! This allocator allocate memory blocks from pre-allocated memory chunks. It does not free memory blocks. And Realloc() only allocate new memory. The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. User may also supply a buffer as the first chunk. If the user-buffer is full then additional chunks are allocated by BaseAllocator. The user-buffer is not deallocated by this allocator. \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. \implements Allocator */ template class MemoryPoolAllocator { public: static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) //! Constructor with chunkSize. /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. \param baseAllocator The allocator for allocating memory chunks. */ MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) { if (!baseAllocator_) ownBaseAllocator_ = baseAllocator_ = new BaseAllocator(); AddChunk(chunk_capacity_); } //! Constructor with user-supplied buffer. /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. The user buffer will not be deallocated when this allocator is destructed. \param buffer User supplied buffer. \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. \param baseAllocator The allocator for allocating memory chunks. */ MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) { RAPIDJSON_ASSERT(buffer != 0); RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); chunkHead_ = (ChunkHeader*)buffer; chunkHead_->capacity = size - sizeof(ChunkHeader); chunkHead_->size = 0; chunkHead_->next = 0; } //! Destructor. /*! This deallocates all memory chunks, excluding the user-supplied buffer. */ ~MemoryPoolAllocator() { Clear(); delete ownBaseAllocator_; } //! Deallocates all memory chunks, excluding the user-supplied buffer. void Clear() { while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) { ChunkHeader* next = chunkHead_->next; baseAllocator_->Free(chunkHead_); chunkHead_ = next; } } //! Computes the total capacity of allocated memory chunks. /*! \return total capacity in bytes. */ size_t Capacity() { size_t capacity = 0; for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) capacity += c->capacity; return capacity; } //! Computes the memory blocks allocated. /*! \return total used bytes. */ size_t Size() { size_t size = 0; for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) size += c->size; return size; } //! Allocates a memory block. (concept Allocator) void* Malloc(size_t size) { size = RAPIDJSON_ALIGN(size); if (chunkHead_->size + size > chunkHead_->capacity) AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size); char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size; chunkHead_->size += size; return buffer; } //! Resizes a memory block (concept Allocator) void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { if (originalPtr == 0) return Malloc(newSize); // Do not shrink if new size is smaller than original if (originalSize >= newSize) return originalPtr; // Simply expand it if it is the last allocation and there is sufficient space if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) { size_t increment = newSize - originalSize; increment = RAPIDJSON_ALIGN(increment); if (chunkHead_->size + increment <= chunkHead_->capacity) { chunkHead_->size += increment; return originalPtr; } } // Realloc process: allocate and copy memory, do not free original buffer. void* newBuffer = Malloc(newSize); RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly. return memcpy(newBuffer, originalPtr, originalSize); } //! Frees a memory block (concept Allocator) static void Free(void *ptr) { (void)ptr; } // Do nothing private: //! Creates a new chunk. /*! \param capacity Capacity of the chunk in bytes. */ void AddChunk(size_t capacity) { ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity); chunk->capacity = capacity; chunk->size = 0; chunk->next = chunkHead_; chunkHead_ = chunk; } static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. //! Chunk header for perpending to each chunk. /*! Chunks are stored as a singly linked list. */ struct ChunkHeader { size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). size_t size; //!< Current size of allocated memory in bytes. ChunkHeader *next; //!< Next chunk in the linked list. }; ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. char *userBuffer_; //!< User supplied buffer. BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. }; } // namespace rapidjson #endif // RAPIDJSON_ENCODINGS_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/document.h000066400000000000000000000733001257152637300236170ustar00rootroot00000000000000#ifndef RAPIDJSON_DOCUMENT_H_ #define RAPIDJSON_DOCUMENT_H_ #include "reader.h" #include "internal/strfunc.h" #include // placement new #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant #endif namespace rapidjson { /////////////////////////////////////////////////////////////////////////////// // GenericValue //! Represents a JSON value. Use Value for UTF8 encoding and default allocator. /*! A JSON value can be one of 7 types. This class is a variant type supporting these types. Use the Value if UTF8 and default allocator \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) \tparam Allocator Allocator type for allocating memory of object, array and string. */ #pragma pack (push, 4) template > class GenericValue { public: //! Name-value pair in an object. struct Member { GenericValue name; //!< name of member (must be a string) GenericValue value; //!< value of member. }; typedef Encoding EncodingType; //!< Encoding type from template parameter. typedef Allocator AllocatorType; //!< Allocator type from template parameter. typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. typedef Member* MemberIterator; //!< Member iterator for iterating in object. typedef const Member* ConstMemberIterator; //!< Constant member iterator for iterating in object. typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. //!@name Constructors and destructor. //@{ //! Default constructor creates a null value. GenericValue() : flags_(kNullFlag) {} //! Copy constructor is not permitted. private: GenericValue(const GenericValue& rhs); public: //! Constructor with JSON value type. /*! This creates a Value of specified type with default content. \param type Type of the value. \note Default content for number is zero. */ GenericValue(Type type) { static const unsigned defaultFlags[7] = { kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag, kNumberFlag | kIntFlag | kUintFlag | kInt64Flag | kUint64Flag | kDoubleFlag }; RAPIDJSON_ASSERT(type <= kNumberType); flags_ = defaultFlags[type]; memset(&data_, 0, sizeof(data_)); } //! Constructor for boolean value. GenericValue(bool b) : flags_(b ? kTrueFlag : kFalseFlag) {} //! Constructor for int value. GenericValue(int i) : flags_(kNumberIntFlag) { data_.n.i64 = i; if (i >= 0) flags_ |= kUintFlag | kUint64Flag; } //! Constructor for unsigned value. GenericValue(unsigned u) : flags_(kNumberUintFlag) { data_.n.u64 = u; if (!(u & 0x80000000)) flags_ |= kIntFlag | kInt64Flag; } //! Constructor for int64_t value. GenericValue(int64_t i64) : flags_(kNumberInt64Flag) { data_.n.i64 = i64; if (i64 >= 0) { flags_ |= kNumberUint64Flag; if (!(i64 & 0xFFFFFFFF00000000LL)) flags_ |= kUintFlag; if (!(i64 & 0xFFFFFFFF80000000LL)) flags_ |= kIntFlag; } else if (i64 >= -2147483648LL) flags_ |= kIntFlag; } //! Constructor for uint64_t value. GenericValue(uint64_t u64) : flags_(kNumberUint64Flag) { data_.n.u64 = u64; if (!(u64 & 0x8000000000000000ULL)) flags_ |= kInt64Flag; if (!(u64 & 0xFFFFFFFF00000000ULL)) flags_ |= kUintFlag; if (!(u64 & 0xFFFFFFFF80000000ULL)) flags_ |= kIntFlag; } //! Constructor for double value. GenericValue(double d) : flags_(kNumberDoubleFlag) { data_.n.d = d; } //! Constructor for constant string (i.e. do not make a copy of string) GenericValue(const Ch* s, SizeType length) { RAPIDJSON_ASSERT(s != NULL); flags_ = kConstStringFlag; data_.s.str = s; data_.s.length = length; } //! Constructor for constant string (i.e. do not make a copy of string) GenericValue(const Ch* s) { SetStringRaw(s, internal::StrLen(s)); } //! Constructor for copy-string (i.e. do make a copy of string) GenericValue(const Ch* s, SizeType length, Allocator& allocator) { SetStringRaw(s, length, allocator); } //! Constructor for copy-string (i.e. do make a copy of string) GenericValue(const Ch*s, Allocator& allocator) { SetStringRaw(s, internal::StrLen(s), allocator); } //! Destructor. /*! Need to destruct elements of array, members of object, or copy-string. */ ~GenericValue() { if (Allocator::kNeedFree) { // Shortcut by Allocator's trait switch(flags_) { case kArrayFlag: for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) v->~GenericValue(); Allocator::Free(data_.a.elements); break; case kObjectFlag: for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { m->name.~GenericValue(); m->value.~GenericValue(); } Allocator::Free(data_.o.members); break; case kCopyStringFlag: Allocator::Free(const_cast(data_.s.str)); break; } } } //@} //!@name Assignment operators //@{ //! Assignment with move semantics. /*! \param rhs Source of the assignment. It will become a null value after assignment. */ GenericValue& operator=(GenericValue& rhs) { RAPIDJSON_ASSERT(this != &rhs); this->~GenericValue(); memcpy(this, &rhs, sizeof(GenericValue)); rhs.flags_ = kNullFlag; return *this; } //! Assignment with primitive types. /*! \tparam T Either Type, int, unsigned, int64_t, uint64_t, const Ch* \param value The value to be assigned. */ template GenericValue& operator=(T value) { this->~GenericValue(); new (this) GenericValue(value); return *this; } //@} //!@name Type //@{ Type GetType() const { return static_cast(flags_ & kTypeMask); } bool IsNull() const { return flags_ == kNullFlag; } bool IsFalse() const { return flags_ == kFalseFlag; } bool IsTrue() const { return flags_ == kTrueFlag; } bool IsBool() const { return (flags_ & kBoolFlag) != 0; } bool IsObject() const { return flags_ == kObjectFlag; } bool IsArray() const { return flags_ == kArrayFlag; } bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } bool IsInt() const { return (flags_ & kIntFlag) != 0; } bool IsUint() const { return (flags_ & kUintFlag) != 0; } bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } bool IsString() const { return (flags_ & kStringFlag) != 0; } //@} //!@name Null //@{ GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } //@} //!@name Bool //@{ bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } //@} //!@name Object //@{ //! Set this value as an empty object. GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } //! Get the value associated with the name. /*! \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. Since 0.2, if the name is not correct, it will assert. If user is unsure whether a member exists, user should use HasMember() first. A better approach is to use the now public FindMember(). */ GenericValue& operator[](const Ch* name) { if (Member* member = FindMember(name)) return member->value; else { RAPIDJSON_ASSERT(false); // see above note static GenericValue NullValue; return NullValue; } } const GenericValue& operator[](const Ch* name) const { return const_cast(*this)[name]; } //! Member iterators. ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members; } MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return data_.o.members + data_.o.size; } //! Check whether a member exists in the object. /*! \note It is better to use FindMember() directly if you need the obtain the value as well. */ bool HasMember(const Ch* name) const { return FindMember(name) != 0; } //! Find member by name. /*! \return Return the member if exists. Otherwise returns null pointer. */ Member* FindMember(const Ch* name) { RAPIDJSON_ASSERT(name); RAPIDJSON_ASSERT(IsObject()); Object& o = data_.o; for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member) if (name[member->name.data_.s.length] == '\0' && memcmp(member->name.data_.s.str, name, member->name.data_.s.length * sizeof(Ch)) == 0) return member; return 0; } const Member* FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } //! Add a member (name-value pair) to the object. /*! \param name A string value as name of member. \param value Value of any type. \param allocator Allocator for reallocating memory. \return The value itself for fluent API. \note The ownership of name and value will be transfered to this object if success. */ GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { RAPIDJSON_ASSERT(IsObject()); RAPIDJSON_ASSERT(name.IsString()); Object& o = data_.o; if (o.size >= o.capacity) { if (o.capacity == 0) { o.capacity = kDefaultObjectCapacity; o.members = (Member*)allocator.Malloc(o.capacity * sizeof(Member)); } else { SizeType oldCapacity = o.capacity; o.capacity *= 2; o.members = (Member*)allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)); } } o.members[o.size].name.RawAssign(name); o.members[o.size].value.RawAssign(value); o.size++; return *this; } GenericValue& AddMember(const Ch* name, Allocator& nameAllocator, GenericValue& value, Allocator& allocator) { GenericValue n(name, internal::StrLen(name), nameAllocator); return AddMember(n, value, allocator); } GenericValue& AddMember(const Ch* name, GenericValue& value, Allocator& allocator) { GenericValue n(name, internal::StrLen(name)); return AddMember(n, value, allocator); } template GenericValue& AddMember(const Ch* name, T value, Allocator& allocator) { GenericValue n(name, internal::StrLen(name)); GenericValue v(value); return AddMember(n, v, allocator); } //! Remove a member in object by its name. /*! \param name Name of member to be removed. \return Whether the member existed. \note Removing member is implemented by moving the last member. So the ordering of members is changed. */ bool RemoveMember(const Ch* name) { RAPIDJSON_ASSERT(IsObject()); if (Member* m = FindMember(name)) { RAPIDJSON_ASSERT(data_.o.size > 0); RAPIDJSON_ASSERT(data_.o.members != 0); Member* last = data_.o.members + (data_.o.size - 1); if (data_.o.size > 1 && m != last) { // Move the last one to this place m->name = last->name; m->value = last->value; } else { // Only one left, just destroy m->name.~GenericValue(); m->value.~GenericValue(); } --data_.o.size; return true; } return false; } //@} //!@name Array //@{ //! Set this value as an empty array. GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } //! Get the number of elements in array. SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } //! Get the capacity of array. SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } //! Check whether the array is empty. bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } //! Remove all elements in the array. /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. */ void Clear() { RAPIDJSON_ASSERT(IsArray()); for (SizeType i = 0; i < data_.a.size; ++i) data_.a.elements[i].~GenericValue(); data_.a.size = 0; } //! Get an element from array by index. /*! \param index Zero-based index of element. \note \code Value a(kArrayType); a.PushBack(123); int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of const char* type. int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. int z = a[0u].GetInt(); // This works too. \endcode */ GenericValue& operator[](SizeType index) { RAPIDJSON_ASSERT(IsArray()); RAPIDJSON_ASSERT(index < data_.a.size); return data_.a.elements[index]; } const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } //! Element iterator ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } ConstValueIterator Begin() const { return const_cast(*this).Begin(); } ConstValueIterator End() const { return const_cast(*this).End(); } //! Request the array to have enough capacity to store elements. /*! \param newCapacity The capacity that the array at least need to have. \param allocator The allocator for allocating memory. It must be the same one use previously. \return The value itself for fluent API. */ GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { RAPIDJSON_ASSERT(IsArray()); if (newCapacity > data_.a.capacity) { data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); data_.a.capacity = newCapacity; } return *this; } //! Append a value at the end of the array. /*! \param value The value to be appended. \param allocator The allocator for allocating memory. It must be the same one use previously. \return The value itself for fluent API. \note The ownership of the value will be transfered to this object if success. \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. */ GenericValue& PushBack(GenericValue& value, Allocator& allocator) { RAPIDJSON_ASSERT(IsArray()); if (data_.a.size >= data_.a.capacity) Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator); data_.a.elements[data_.a.size++].RawAssign(value); return *this; } template GenericValue& PushBack(T value, Allocator& allocator) { GenericValue v(value); return PushBack(v, allocator); } //! Remove the last element in the array. GenericValue& PopBack() { RAPIDJSON_ASSERT(IsArray()); RAPIDJSON_ASSERT(!Empty()); data_.a.elements[--data_.a.size].~GenericValue(); return *this; } //@} //!@name Number //@{ int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } double GetDouble() const { RAPIDJSON_ASSERT(IsNumber()); if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) } GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } //@} //!@name String //@{ const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return data_.s.str; } //! Get the length of string. /*! Since rapidjson permits "\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). */ SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return data_.s.length; } //! Set this value as a string without copying source string. /*! This version has better performance with supplied length, and also support string containing null character. \param s source string pointer. \param length The length of source string, excluding the trailing null terminator. \return The value itself for fluent API. */ GenericValue& SetString(const Ch* s, SizeType length) { this->~GenericValue(); SetStringRaw(s, length); return *this; } //! Set this value as a string without copying source string. /*! \param s source string pointer. \return The value itself for fluent API. */ GenericValue& SetString(const Ch* s) { return SetString(s, internal::StrLen(s)); } //! Set this value as a string by copying from source string. /*! This version has better performance with supplied length, and also support string containing null character. \param s source string. \param length The length of source string, excluding the trailing null terminator. \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). \return The value itself for fluent API. */ GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, length, allocator); return *this; } //! Set this value as a string by copying from source string. /*! \param s source string. \param allocator Allocator for allocating copied buffer. Commonly use document.GetAllocator(). \return The value itself for fluent API. */ GenericValue& SetString(const Ch* s, Allocator& allocator) { SetString(s, internal::StrLen(s), allocator); return *this; } //@} //! Generate events of this value to a Handler. /*! This function adopts the GoF visitor pattern. Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. It can also be used to deep clone this value via GenericDocument, which is also a Handler. \tparam Handler type of handler. \param handler An object implementing concept Handler. */ template const GenericValue& Accept(Handler& handler) const { switch(GetType()) { case kNullType: handler.Null(); break; case kFalseType: handler.Bool(false); break; case kTrueType: handler.Bool(true); break; case kObjectType: handler.StartObject(); for (Member* m = data_.o.members; m != data_.o.members + data_.o.size; ++m) { handler.String(m->name.data_.s.str, m->name.data_.s.length, false); m->value.Accept(handler); } handler.EndObject(data_.o.size); break; case kArrayType: handler.StartArray(); for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) v->Accept(handler); handler.EndArray(data_.a.size); break; case kStringType: handler.String(data_.s.str, data_.s.length, false); break; case kNumberType: if (IsInt()) handler.Int(data_.n.i.i); else if (IsUint()) handler.Uint(data_.n.u.u); else if (IsInt64()) handler.Int64(data_.n.i64); else if (IsUint64()) handler.Uint64(data_.n.u64); else handler.Double(data_.n.d); break; } return *this; } private: template friend class GenericDocument; enum { kBoolFlag = 0x100, kNumberFlag = 0x200, kIntFlag = 0x400, kUintFlag = 0x800, kInt64Flag = 0x1000, kUint64Flag = 0x2000, kDoubleFlag = 0x4000, kStringFlag = 0x100000, kCopyFlag = 0x200000, // Initial flags of different types. kNullFlag = kNullType, kTrueFlag = kTrueType | kBoolFlag, kFalseFlag = kFalseType | kBoolFlag, kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, kConstStringFlag = kStringType | kStringFlag, kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, kObjectFlag = kObjectType, kArrayFlag = kArrayType, kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler }; static const SizeType kDefaultArrayCapacity = 16; static const SizeType kDefaultObjectCapacity = 16; struct String { const Ch* str; SizeType length; unsigned hashcode; //!< reserved }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode // By using proper binary layout, retrieval of different integer types do not need conversions. union Number { #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN struct I { int i; char padding[4]; }i; struct U { unsigned u; char padding2[4]; }u; #else struct I { char padding[4]; int i; }i; struct U { char padding2[4]; unsigned u; }u; #endif int64_t i64; uint64_t u64; double d; }; // 8 bytes struct Object { Member* members; SizeType size; SizeType capacity; }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode struct Array { GenericValue* elements; SizeType size; SizeType capacity; }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode union Data { String s; Number n; Object o; Array a; }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode // Initialize this value as array with initial data, without calling destructor. void SetArrayRaw(GenericValue* values, SizeType count, Allocator& alloctaor) { flags_ = kArrayFlag; data_.a.elements = (GenericValue*)alloctaor.Malloc(count * sizeof(GenericValue)); memcpy(data_.a.elements, values, count * sizeof(GenericValue)); data_.a.size = data_.a.capacity = count; } //! Initialize this value as object with initial data, without calling destructor. void SetObjectRaw(Member* members, SizeType count, Allocator& alloctaor) { flags_ = kObjectFlag; data_.o.members = (Member*)alloctaor.Malloc(count * sizeof(Member)); memcpy(data_.o.members, members, count * sizeof(Member)); data_.o.size = data_.o.capacity = count; } //! Initialize this value as constant string, without calling destructor. void SetStringRaw(const Ch* s, SizeType length) { RAPIDJSON_ASSERT(s != NULL); flags_ = kConstStringFlag; data_.s.str = s; data_.s.length = length; } //! Initialize this value as copy string with initial data, without calling destructor. void SetStringRaw(const Ch* s, SizeType length, Allocator& allocator) { RAPIDJSON_ASSERT(s != NULL); flags_ = kCopyStringFlag; data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch)); data_.s.length = length; memcpy(const_cast(data_.s.str), s, length * sizeof(Ch)); const_cast(data_.s.str)[length] = '\0'; } //! Assignment without calling destructor void RawAssign(GenericValue& rhs) { memcpy(this, &rhs, sizeof(GenericValue)); rhs.flags_ = kNullFlag; } Data data_; unsigned flags_; }; #pragma pack (pop) //! Value with UTF8 encoding. typedef GenericValue > Value; /////////////////////////////////////////////////////////////////////////////// // GenericDocument //! A document for parsing JSON text as DOM. /*! \implements Handler \tparam Encoding encoding for both parsing and string storage. \tparam Alloactor allocator for allocating memory for the DOM, and the stack during parsing. */ template > class GenericDocument : public GenericValue { public: typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. typedef GenericValue ValueType; //!< Value type of the document. typedef Allocator AllocatorType; //!< Allocator type from template parameter. //! Constructor /*! \param allocator Optional allocator for allocating stack memory. \param stackCapacity Initial capacity of stack in bytes. */ GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} //! Parse JSON text from an input stream. /*! \tparam parseFlags Combination of ParseFlag. \param stream Input stream to be parsed. \return The document itself for fluent API. */ template GenericDocument& ParseStream(InputStream& is) { ValueType::SetNull(); // Remove existing root if exist GenericReader reader; if (reader.template Parse(is, *this)) { RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object this->RawAssign(*stack_.template Pop(1)); // Add this-> to prevent issue 13. parseError_ = 0; errorOffset_ = 0; } else { parseError_ = reader.GetParseError(); errorOffset_ = reader.GetErrorOffset(); ClearStack(); } return *this; } //! Parse JSON text from a mutable string. /*! \tparam parseFlags Combination of ParseFlag. \param str Mutable zero-terminated string to be parsed. \return The document itself for fluent API. */ template GenericDocument& ParseInsitu(Ch* str) { GenericInsituStringStream s(str); return ParseStream(s); } template GenericDocument& ParseInsitu(Ch* str) { return ParseInsitu(str); } //! Parse JSON text from a read-only string. /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag). \param str Read-only zero-terminated string to be parsed. */ template GenericDocument& Parse(const Ch* str) { RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); GenericStringStream s(str); return ParseStream(s); } template GenericDocument& Parse(const Ch* str) { return Parse(str); } //! Whether a parse error was occured in the last parsing. bool HasParseError() const { return parseError_ != 0; } //! Get the message of parsing error. const char* GetParseError() const { return parseError_; } //! Get the offset in character of the parsing error. size_t GetErrorOffset() const { return errorOffset_; } //! Get the allocator of this document. Allocator& GetAllocator() { return stack_.GetAllocator(); } //! Get the capacity of stack in bytes. size_t GetStackCapacity() const { return stack_.GetCapacity(); } //private: //friend class GenericReader; // for Reader to call the following private handler functions // Implementation of Handler void Null() { new (stack_.template Push()) ValueType(); } void Bool(bool b) { new (stack_.template Push()) ValueType(b); } void Int(int i) { new (stack_.template Push()) ValueType(i); } void Uint(unsigned i) { new (stack_.template Push()) ValueType(i); } void Int64(int64_t i) { new (stack_.template Push()) ValueType(i); } void Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); } void Double(double d) { new (stack_.template Push()) ValueType(d); } void String(const Ch* str, SizeType length, bool copy) { if (copy) new (stack_.template Push()) ValueType(str, length, GetAllocator()); else new (stack_.template Push()) ValueType(str, length); } void StartObject() { new (stack_.template Push()) ValueType(kObjectType); } void EndObject(SizeType memberCount) { typename ValueType::Member* members = stack_.template Pop(memberCount); stack_.template Top()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); } void StartArray() { new (stack_.template Push()) ValueType(kArrayType); } void EndArray(SizeType elementCount) { ValueType* elements = stack_.template Pop(elementCount); stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); } private: // Prohibit assignment GenericDocument& operator=(const GenericDocument&); void ClearStack() { if (Allocator::kNeedFree) while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) (stack_.template Pop(1))->~ValueType(); else stack_.Clear(); } static const size_t kDefaultStackCapacity = 1024; internal::Stack stack_; const char* parseError_; size_t errorOffset_; }; typedef GenericDocument > Document; } // namespace rapidjson #ifdef _MSC_VER #pragma warning(pop) #endif #endif // RAPIDJSON_DOCUMENT_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/encodedstream.h000066400000000000000000000175071257152637300246250ustar00rootroot00000000000000#ifndef RAPIDJSON_ENCODEDSTREAM_H_ #define RAPIDJSON_ENCODEDSTREAM_H_ #include "rapidjson.h" namespace rapidjson { //! Input byte stream wrapper with a statically bound encoding. /*! \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. \tparam InputByteStream Type of input byte stream. For example, FileReadStream. */ template class EncodedInputStream { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); public: typedef typename Encoding::Ch Ch; EncodedInputStream(InputByteStream& is) : is_(is) { current_ = Encoding::TakeBOM(is_); } Ch Peek() const { return current_; } Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } size_t Tell() const { return is_.Tell(); } // Not implemented void Put(Ch c) { RAPIDJSON_ASSERT(false); } void Flush() { RAPIDJSON_ASSERT(false); } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } private: // Prohibit assignment for VC C4512 warning EncodedInputStream& operator=(const EncodedInputStream&); InputByteStream& is_; Ch current_; }; //! Output byte stream wrapper with statically bound encoding. /*! \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. \tparam InputByteStream Type of input byte stream. For example, FileWriteStream. */ template class EncodedOutputStream { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); public: typedef typename Encoding::Ch Ch; EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { if (putBOM) Encoding::PutBOM(os_); } void Put(Ch c) { Encoding::Put(os_, c); } void Flush() { os_.Flush(); } // Not implemented Ch Peek() const { RAPIDJSON_ASSERT(false); } Ch Take() { RAPIDJSON_ASSERT(false); } size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } private: // Prohibit assignment for VC C4512 warning EncodedOutputStream& operator=(const EncodedOutputStream&); OutputByteStream& os_; }; #define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x //! Input stream wrapper with dynamically bound encoding and automatic encoding detection. /*! \tparam CharType Type of character for reading. \tparam InputByteStream type of input byte stream to be wrapped. */ template class AutoUTFInputStream { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); public: typedef CharType Ch; //! Constructor. /*! \param is input stream to be wrapped. \param type UTF encoding type if it is not detected from the stream. */ AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { DetectType(); static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; takeFunc_ = f[type_]; current_ = takeFunc_(*is_); } UTFType GetType() const { return type_; } bool HasBOM() const { return hasBOM_; } Ch Peek() const { return current_; } Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } size_t Tell() const { return is_->Tell(); } // Not implemented void Put(Ch) { RAPIDJSON_ASSERT(false); } void Flush() { RAPIDJSON_ASSERT(false); } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } private: // Detect encoding type with BOM or RFC 4627 void DetectType() { // BOM (Byte Order Mark): // 00 00 FE FF UTF-32BE // FF FE 00 00 UTF-32LE // FE FF UTF-16BE // FF FE UTF-16LE // EF BB BF UTF-8 const unsigned char* c = (const unsigned char *)is_->Peek4(); if (!c) return; unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); hasBOM_ = false; if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } // RFC 4627: Section 3 // "Since the first two characters of a JSON text will always be ASCII // characters [RFC0020], it is possible to determine whether an octet // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking // at the pattern of nulls in the first four octets." // 00 00 00 xx UTF-32BE // 00 xx 00 xx UTF-16BE // xx 00 00 00 UTF-32LE // xx 00 xx 00 UTF-16LE // xx xx xx xx UTF-8 if (!hasBOM_) { unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); switch (pattern) { case 0x08: type_ = kUTF32BE; break; case 0x0A: type_ = kUTF16BE; break; case 0x01: type_ = kUTF32LE; break; case 0x05: type_ = kUTF16LE; break; case 0x0F: type_ = kUTF8; break; } } // RUntime check whether the size of character type is sufficient. It only perform checks with assertion. switch (type_) { case kUTF8: // Do nothing break; case kUTF16LE: case kUTF16BE: RAPIDJSON_ASSERT(sizeof(Ch) >= 2); break; case kUTF32LE: case kUTF32BE: RAPIDJSON_ASSERT(sizeof(Ch) >= 4); break; } } typedef Ch (*TakeFunc)(InputByteStream& is); InputByteStream* is_; UTFType type_; Ch current_; TakeFunc takeFunc_; bool hasBOM_; }; //! Output stream wrapper with dynamically bound encoding and automatic encoding detection. /*! \tparam CharType Type of character for writing. \tparam InputByteStream type of output byte stream to be wrapped. */ template class AutoUTFOutputStream { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); public: typedef CharType Ch; //! Constructor. /*! \param os output stream to be wrapped. \param type UTF encoding type. \param putBOM Whether to write BOM at the beginning of the stream. */ AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { // RUntime check whether the size of character type is sufficient. It only perform checks with assertion. switch (type_) { case kUTF16LE: case kUTF16BE: RAPIDJSON_ASSERT(sizeof(Ch) >= 2); break; case kUTF32LE: case kUTF32BE: RAPIDJSON_ASSERT(sizeof(Ch) >= 4); break; case kUTF8: // Do nothing break; } static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; putFunc_ = f[type_]; if (putBOM) PutBOM(); } UTFType GetType() const { return type_; } void Put(Ch c) { putFunc_(*os_, c); } void Flush() { os_->Flush(); } // Not implemented Ch Peek() const { RAPIDJSON_ASSERT(false); } Ch Take() { RAPIDJSON_ASSERT(false); } size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } private: void PutBOM() { typedef void (*PutBOMFunc)(OutputByteStream&); static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; f[type_](*os_); } typedef void (*PutFunc)(OutputByteStream&, Ch); OutputByteStream* os_; UTFType type_; PutFunc putFunc_; }; #undef RAPIDJSON_ENCODINGS_FUNC } // namespace rapidjson #endif // RAPIDJSON_FILESTREAM_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/encodings.h000066400000000000000000000435171257152637300237610ustar00rootroot00000000000000#ifndef RAPIDJSON_ENCODINGS_H_ #define RAPIDJSON_ENCODINGS_H_ #include "rapidjson.h" namespace rapidjson { /////////////////////////////////////////////////////////////////////////////// // Encoding /*! \class rapidjson::Encoding \brief Concept for encoding of Unicode characters. \code concept Encoding { typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. //! \brief Encode a Unicode codepoint to an output stream. //! \param os Output stream. //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. template static void Encode(OutputStream& os, unsigned codepoint); //! \brief Decode a Unicode codepoint from an input stream. //! \param is Input stream. //! \param codepoint Output of the unicode codepoint. //! \return true if a valid codepoint can be decoded from the stream. template static bool Decode(InputStream& is, unsigned* codepoint); //! \brief Validate one Unicode codepoint from an encoded stream. //! \param is Input stream to obtain codepoint. //! \param os Output for copying one codepoint. //! \return true if it is valid. //! \note This function just validating and copying the codepoint without actually decode it. template static bool Validate(InputStream& is, OutputStream& os); // The following functions are deal with byte streams. //! Take a character from input byte stream, skip BOM if exist. template static CharType TakeBOM(InputByteStream& is); //! Take a character from input byte stream. template static Ch Take(InputByteStream& is); //! Put BOM to output byte stream. template static void PutBOM(OutputByteStream& os); //! Put a character to output byte stream. template static void Put(OutputByteStream& os, Ch c); }; \endcode */ /////////////////////////////////////////////////////////////////////////////// // UTF8 //! UTF-8 encoding. /*! http://en.wikipedia.org/wiki/UTF-8 http://tools.ietf.org/html/rfc3629 \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. \implements Encoding */ template struct UTF8 { typedef CharType Ch; template static void Encode(OutputStream& os, unsigned codepoint) { if (codepoint <= 0x7F) os.Put(codepoint & 0xFF); else if (codepoint <= 0x7FF) { os.Put(0xC0 | ((codepoint >> 6) & 0xFF)); os.Put(0x80 | ((codepoint & 0x3F))); } else if (codepoint <= 0xFFFF) { os.Put(0xE0 | ((codepoint >> 12) & 0xFF)); os.Put(0x80 | ((codepoint >> 6) & 0x3F)); os.Put(0x80 | (codepoint & 0x3F)); } else { RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); os.Put(0xF0 | ((codepoint >> 18) & 0xFF)); os.Put(0x80 | ((codepoint >> 12) & 0x3F)); os.Put(0x80 | ((codepoint >> 6) & 0x3F)); os.Put(0x80 | (codepoint & 0x3F)); } } template static bool Decode(InputStream& is, unsigned* codepoint) { #define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu) #define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) #define TAIL() COPY(); TRANS(0x70) Ch c = is.Take(); if (!(c & 0x80)) { *codepoint = (unsigned char)c; return true; } unsigned char type = GetRange((unsigned char)c); *codepoint = (0xFF >> type) & (unsigned char)c; bool result = true; switch (type) { case 2: TAIL(); return result; case 3: TAIL(); TAIL(); return result; case 4: COPY(); TRANS(0x50); TAIL(); return result; case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; case 6: TAIL(); TAIL(); TAIL(); return result; case 10: COPY(); TRANS(0x20); TAIL(); return result; case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; default: return false; } #undef COPY #undef TRANS #undef TAIL } template static bool Validate(InputStream& is, OutputStream& os) { #define COPY() os.Put(c = is.Take()) #define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) #define TAIL() COPY(); TRANS(0x70) Ch c; COPY(); if (!(c & 0x80)) return true; bool result = true; switch (GetRange((unsigned char)c)) { case 2: TAIL(); return result; case 3: TAIL(); TAIL(); return result; case 4: COPY(); TRANS(0x50); TAIL(); return result; case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; case 6: TAIL(); TAIL(); TAIL(); return result; case 10: COPY(); TRANS(0x20); TAIL(); return result; case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; default: return false; } #undef COPY #undef TRANS #undef TAIL } static unsigned char GetRange(unsigned char c) { // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. static const unsigned char type[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, }; return type[c]; } template static CharType TakeBOM(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); Ch c = Take(is); if ((unsigned char)c != 0xEFu) return c; c = is.Take(); if ((unsigned char)c != 0xBBu) return c; c = is.Take(); if ((unsigned char)c != 0xBFu) return c; c = is.Take(); return c; } template static Ch Take(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); return is.Take(); } template static void PutBOM(OutputByteStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu); } template static void Put(OutputByteStream& os, Ch c) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(static_cast(c)); } }; /////////////////////////////////////////////////////////////////////////////// // UTF16 //! UTF-16 encoding. /*! http://en.wikipedia.org/wiki/UTF-16 http://tools.ietf.org/html/rfc2781 \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. \implements Encoding \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. For streaming, use UTF16LE and UTF16BE, which handle endianness. */ template struct UTF16 { typedef CharType Ch; RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); template static void Encode(OutputStream& os, unsigned codepoint) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); if (codepoint <= 0xFFFF) { RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair os.Put(static_cast(codepoint)); } else { RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); unsigned v = codepoint - 0x10000; os.Put(static_cast((v >> 10) | 0xD800)); os.Put((v & 0x3FF) | 0xDC00); } } template static bool Decode(InputStream& is, unsigned* codepoint) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); Ch c = is.Take(); if (c < 0xD800 || c > 0xDFFF) { *codepoint = c; return true; } else if (c <= 0xDBFF) { *codepoint = (c & 0x3FF) << 10; c = is.Take(); *codepoint |= (c & 0x3FF); *codepoint += 0x10000; return c >= 0xDC00 && c <= 0xDFFF; } return false; } template static bool Validate(InputStream& is, OutputStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); Ch c; os.Put(c = is.Take()); if (c < 0xD800 || c > 0xDFFF) return true; else if (c <= 0xDBFF) { os.Put(c = is.Take()); return c >= 0xDC00 && c <= 0xDFFF; } return false; } }; //! UTF-16 little endian encoding. template struct UTF16LE : UTF16 { template static CharType TakeBOM(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = Take(is); return (unsigned short)c == 0xFEFFu ? Take(is) : c; } template static CharType Take(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = (unsigned char)is.Take(); c |= (unsigned char)is.Take() << 8; return c; } template static void PutBOM(OutputByteStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(0xFFu); os.Put(0xFEu); } template static void Put(OutputByteStream& os, CharType c) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(c & 0xFFu); os.Put((c >> 8) & 0xFFu); } }; //! UTF-16 big endian encoding. template struct UTF16BE : UTF16 { template static CharType TakeBOM(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = Take(is); return (unsigned short)c == 0xFEFFu ? Take(is) : c; } template static CharType Take(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = (unsigned char)is.Take() << 8; c |= (unsigned char)is.Take(); return c; } template static void PutBOM(OutputByteStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(0xFEu); os.Put(0xFFu); } template static void Put(OutputByteStream& os, CharType c) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put((c >> 8) & 0xFFu); os.Put(c & 0xFFu); } }; /////////////////////////////////////////////////////////////////////////////// // UTF32 //! UTF-32 encoding. /*! http://en.wikipedia.org/wiki/UTF-32 \tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. \implements Encoding \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. For streaming, use UTF32LE and UTF32BE, which handle endianness. */ template struct UTF32 { typedef CharType Ch; RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); template static void Encode(OutputStream& os, unsigned codepoint) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); os.Put(codepoint); } template static bool Decode(InputStream& is, unsigned* codepoint) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); Ch c = is.Take(); *codepoint = c; return c <= 0x10FFFF; } template static bool Validate(InputStream& is, OutputStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); Ch c; os.Put(c = is.Take()); return c <= 0x10FFFF; } }; //! UTF-32 little endian enocoding. template struct UTF32LE : UTF32 { template static CharType TakeBOM(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = Take(is); return (unsigned)c == 0x0000FEFFu ? Take(is) : c; } template static CharType Take(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = (unsigned char)is.Take(); c |= (unsigned char)is.Take() << 8; c |= (unsigned char)is.Take() << 16; c |= (unsigned char)is.Take() << 24; return c; } template static void PutBOM(OutputByteStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u); } template static void Put(OutputByteStream& os, CharType c) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(c & 0xFFu); os.Put((c >> 8) & 0xFFu); os.Put((c >> 16) & 0xFFu); os.Put((c >> 24) & 0xFFu); } }; //! UTF-32 big endian encoding. template struct UTF32BE : UTF32 { template static CharType TakeBOM(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = Take(is); return (unsigned)c == 0x0000FEFFu ? Take(is) : c; } template static CharType Take(InputByteStream& is) { RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); CharType c = (unsigned char)is.Take() << 24; c |= (unsigned char)is.Take() << 16; c |= (unsigned char)is.Take() << 8; c |= (unsigned char)is.Take(); return c; } template static void PutBOM(OutputByteStream& os) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu); } template static void Put(OutputByteStream& os, CharType c) { RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); os.Put((c >> 24) & 0xFFu); os.Put((c >> 16) & 0xFFu); os.Put((c >> 8) & 0xFFu); os.Put(c & 0xFFu); } }; /////////////////////////////////////////////////////////////////////////////// // AutoUTF //! Runtime-specified UTF encoding type of a stream. enum UTFType { kUTF8 = 0, //!< UTF-8. kUTF16LE = 1, //!< UTF-16 little endian. kUTF16BE = 2, //!< UTF-16 big endian. kUTF32LE = 3, //!< UTF-32 little endian. kUTF32BE = 4, //!< UTF-32 big endian. }; //! Dynamically select encoding according to stream's runtime-specified UTF encoding type. /*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). */ template struct AutoUTF { typedef CharType Ch; #define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x template RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { typedef void (*EncodeFunc)(OutputStream&, unsigned); static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; (*f[os.GetType()])(os, codepoint); } template RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { typedef bool (*DecodeFunc)(InputStream&, unsigned*); static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; return (*f[is.GetType()])(is, codepoint); } template RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { typedef bool (*ValidateFunc)(InputStream&, OutputStream&); static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; return (*f[is.GetType()])(is, os); } #undef RAPIDJSON_ENCODINGS_FUNC }; /////////////////////////////////////////////////////////////////////////////// // Transcoder //! Encoding conversion. template struct Transcoder { //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. template RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { unsigned codepoint; if (!SourceEncoding::Decode(is, &codepoint)) return false; TargetEncoding::Encode(os, codepoint); return true; } //! Validate one Unicode codepoint from an encoded stream. template RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { return Transcode(is, os); // Since source/target encoding is different, must transcode. } }; //! Specialization of Transcoder with same source and target encoding. template struct Transcoder { template RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. return true; } template RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { return Encoding::Validate(is, os); // source/target encoding are the same } }; } // namespace rapidjson #endif // RAPIDJSON_ENCODINGS_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/filereadstream.h000066400000000000000000000035141257152637300247700ustar00rootroot00000000000000#ifndef RAPIDJSON_FILEREADSTREAM_H_ #define RAPIDJSON_FILEREADSTREAM_H_ #include "rapidjson.h" #include namespace rapidjson { //! File byte stream for input using fread(). /*! \implements Stream */ class FileReadStream { public: typedef char Ch; //!< Character type (byte). //! Constructor. /*! \param fp File pointer opened for read. \param buffer user-supplied buffer. \param bufferSize size of buffer in bytes. Must >=4 bytes. */ FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { RAPIDJSON_ASSERT(fp_ != 0); RAPIDJSON_ASSERT(bufferSize >= 4); Read(); } Ch Peek() const { return *current_; } Ch Take() { Ch c = *current_; Read(); return c; } size_t Tell() const { return count_ + (current_ - buffer_); } // Not implemented void Put(Ch) { RAPIDJSON_ASSERT(false); } void Flush() { RAPIDJSON_ASSERT(false); } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } // For encoding detection only. const Ch* Peek4() const { return (current_ + 4 <= bufferLast_) ? current_ : 0; } private: void Read() { if (current_ < bufferLast_) ++current_; else if (!eof_) { count_ += readCount_; readCount_ = fread(buffer_, 1, bufferSize_, fp_); bufferLast_ = buffer_ + readCount_ - 1; current_ = buffer_; if (readCount_ < bufferSize_) { buffer_[readCount_] = '\0'; ++bufferLast_; eof_ = true; } } } FILE* fp_; Ch *buffer_; size_t bufferSize_; Ch *bufferLast_; Ch *current_; size_t readCount_; size_t count_; //!< Number of characters read bool eof_; }; } // namespace rapidjson #endif // RAPIDJSON_FILESTREAM_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/filestream.h000066400000000000000000000023021257152637300241260ustar00rootroot00000000000000#ifndef RAPIDJSON_FILESTREAM_H_ #define RAPIDJSON_FILESTREAM_H_ #include "rapidjson.h" #include namespace rapidjson { //! (Depreciated) Wrapper of C file stream for input or output. /*! This simple wrapper does not check the validity of the stream. \implements Stream \deprecated { This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. } */ class FileStream { public: typedef char Ch; //!< Character type. Only support char. FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); } char Peek() const { return current_; } char Take() { char c = current_; Read(); return c; } size_t Tell() const { return count_; } void Put(char c) { fputc(c, fp_); } void Flush() { fflush(fp_); } // Not implemented char* PutBegin() { return 0; } size_t PutEnd(char*) { return 0; } private: void Read() { RAPIDJSON_ASSERT(fp_ != 0); int c = fgetc(fp_); if (c != EOF) { current_ = (char)c; count_++; } else if (current_ != '\0') current_ = '\0'; } FILE* fp_; char current_; size_t count_; }; } // namespace rapidjson #endif // RAPIDJSON_FILESTREAM_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/filewritestream.h000066400000000000000000000032141257152637300252040ustar00rootroot00000000000000#ifndef RAPIDJSON_FILEWRITESTREAM_H_ #define RAPIDJSON_FILEWRITESTREAM_H_ #include "rapidjson.h" #include namespace rapidjson { //! Wrapper of C file stream for input using fread(). /*! \implements Stream */ class FileWriteStream { public: typedef char Ch; //!< Character type. Only support char. FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { RAPIDJSON_ASSERT(fp_ != 0); } void Put(char c) { if (current_ >= bufferEnd_) Flush(); *current_++ = c; } void PutN(char c, size_t n) { size_t avail = bufferEnd_ - current_; while (n > avail) { memset(current_, c, avail); current_ += avail; Flush(); n -= avail; avail = bufferEnd_ - current_; } if (n > 0) { memset(current_, c, n); current_ += n; } } void Flush() { if (current_ != buffer_) { fwrite(buffer_, 1, current_ - buffer_, fp_); current_ = buffer_; } } // Not implemented char Peek() const { RAPIDJSON_ASSERT(false); return 0; } char Take() { RAPIDJSON_ASSERT(false); return 0; } size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } private: FILE* fp_; char *buffer_; char *bufferEnd_; char *current_; }; //! Implement specialized version of PutN() with memset() for better performance. template<> inline void PutN(FileWriteStream& stream, char c, size_t n) { stream.PutN(c, n); } } // namespace rapidjson #endif // RAPIDJSON_FILESTREAM_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/internal/000077500000000000000000000000001257152637300234415ustar00rootroot00000000000000davix-R_0_5_0/deps/rapidjson/include/rapidjson/internal/pow10.h000066400000000000000000000116151257152637300245640ustar00rootroot00000000000000#ifndef RAPIDJSON_POW10_ #define RAPIDJSON_POW10_ namespace rapidjson { namespace internal { //! Computes integer powers of 10 in double (10.0^n). /*! This function uses lookup table for fast and accurate results. \param n positive/negative exponent. Must <= 308. \return 10.0^n */ inline double Pow10(int n) { static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes 1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300, 1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280, 1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260, 1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240, 1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220, 1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200, 1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180, 1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160, 1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140, 1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120, 1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100, 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 }; RAPIDJSON_ASSERT(n <= 308); return n < -308 ? 0.0 : e[n + 308]; } } // namespace internal } // namespace rapidjson #endif // RAPIDJSON_POW10_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/internal/stack.h000066400000000000000000000045521257152637300247250ustar00rootroot00000000000000#ifndef RAPIDJSON_INTERNAL_STACK_H_ #define RAPIDJSON_INTERNAL_STACK_H_ namespace rapidjson { namespace internal { /////////////////////////////////////////////////////////////////////////////// // Stack //! A type-unsafe stack for storing different types of data. /*! \tparam Allocator Allocator for allocating stack memory. */ template class Stack { public: Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) { RAPIDJSON_ASSERT(stack_capacity_ > 0); if (!allocator_) own_allocator_ = allocator_ = new Allocator(); stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_); stack_end_ = stack_ + stack_capacity_; } ~Stack() { Allocator::Free(stack_); delete own_allocator_; // Only delete if it is owned by the stack } void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; } template T* Push(size_t count = 1) { // Expand the stack if needed if (stack_top_ + sizeof(T) * count >= stack_end_) { size_t new_capacity = stack_capacity_ * 2; size_t size = GetSize(); size_t new_size = GetSize() + sizeof(T) * count; if (new_capacity < new_size) new_capacity = new_size; stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity); stack_capacity_ = new_capacity; stack_top_ = stack_ + size; stack_end_ = stack_ + stack_capacity_; } T* ret = (T*)stack_top_; stack_top_ += sizeof(T) * count; return ret; } template T* Pop(size_t count) { RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); stack_top_ -= count * sizeof(T); return (T*)stack_top_; } template T* Top() { RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); return (T*)(stack_top_ - sizeof(T)); } template T* Bottom() { return (T*)stack_; } Allocator& GetAllocator() { return *allocator_; } bool Empty() const { return stack_top_ == stack_; } size_t GetSize() const { return stack_top_ - stack_; } size_t GetCapacity() const { return stack_capacity_; } private: Allocator* allocator_; Allocator* own_allocator_; char *stack_; char *stack_top_; char *stack_end_; size_t stack_capacity_; }; } // namespace internal } // namespace rapidjson #endif // RAPIDJSON_STACK_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/internal/strfunc.h000066400000000000000000000012501257152637300252740ustar00rootroot00000000000000#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ #define RAPIDJSON_INTERNAL_STRFUNC_H_ namespace rapidjson { namespace internal { //! Custom strlen() which works on different character types. /*! \tparam Ch Character type (e.g. char, wchar_t, short) \param s Null-terminated input string. \return Number of characters in the string. \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. */ template inline SizeType StrLen(const Ch* s) { const Ch* p = s; while (*p != '\0') ++p; return SizeType(p - s); } } // namespace internal } // namespace rapidjson #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/prettywriter.h000066400000000000000000000126171257152637300245710ustar00rootroot00000000000000#ifndef RAPIDJSON_PRETTYWRITER_H_ #define RAPIDJSON_PRETTYWRITER_H_ #include "writer.h" namespace rapidjson { //! Writer with indentation and spacing. /*! \tparam OutputStream Type of ouptut os. \tparam Encoding Encoding of both source strings and output. \tparam Allocator Type of allocator for allocating memory of stack. */ template, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > class PrettyWriter : public Writer { public: typedef Writer Base; typedef typename Base::Ch Ch; //! Constructor /*! \param os Output os. \param allocator User supplied allocator. If it is null, it will create a private one. \param levelDepth Initial capacity of */ PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} //! Set custom indentation. /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\t', '\n', '\r'). \param indentCharCount Number of indent characters for each indentation level. \note The default indentation is 4 spaces. */ PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); indentChar_ = indentChar; indentCharCount_ = indentCharCount; return *this; } //@name Implementation of Handler. //@{ PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; } PrettyWriter& Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; } PrettyWriter& Int(int i) { PrettyPrefix(kNumberType); Base::WriteInt(i); return *this; } PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; } PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; } PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; } PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; } PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { (void)copy; PrettyPrefix(kStringType); Base::WriteString(str, length); return *this; } PrettyWriter& StartObject() { PrettyPrefix(kObjectType); new (Base::level_stack_.template Push()) typename Base::Level(false); Base::WriteStartObject(); return *this; } PrettyWriter& EndObject(SizeType memberCount = 0) { (void)memberCount; RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; if (!empty) { Base::os_.Put('\n'); WriteIndent(); } Base::WriteEndObject(); if (Base::level_stack_.Empty()) // end of json text Base::os_.Flush(); return *this; } PrettyWriter& StartArray() { PrettyPrefix(kArrayType); new (Base::level_stack_.template Push()) typename Base::Level(true); Base::WriteStartArray(); return *this; } PrettyWriter& EndArray(SizeType memberCount = 0) { (void)memberCount; RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; if (!empty) { Base::os_.Put('\n'); WriteIndent(); } Base::WriteEndArray(); if (Base::level_stack_.Empty()) // end of json text Base::os_.Flush(); return *this; } //@} //! Simpler but slower overload. PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); } protected: void PrettyPrefix(Type type) { (void)type; if (Base::level_stack_.GetSize() != 0) { // this value is not at root typename Base::Level* level = Base::level_stack_.template Top(); if (level->inArray) { if (level->valueCount > 0) { Base::os_.Put(','); // add comma if it is not the first element in array Base::os_.Put('\n'); } else Base::os_.Put('\n'); WriteIndent(); } else { // in object if (level->valueCount > 0) { if (level->valueCount % 2 == 0) { Base::os_.Put(','); Base::os_.Put('\n'); } else { Base::os_.Put(':'); Base::os_.Put(' '); } } else Base::os_.Put('\n'); if (level->valueCount % 2 == 0) WriteIndent(); } if (!level->inArray && level->valueCount % 2 == 0) RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name level->valueCount++; } else RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); } void WriteIndent() { size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; PutN(Base::os_, indentChar_, count); } Ch indentChar_; unsigned indentCharCount_; }; } // namespace rapidjson #endif // RAPIDJSON_RAPIDJSON_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/rapidjson.h000066400000000000000000000166451257152637300240030ustar00rootroot00000000000000#ifndef RAPIDJSON_RAPIDJSON_H_ #define RAPIDJSON_RAPIDJSON_H_ // Copyright (c) 2011 Milo Yip (miloyip@gmail.com) // Version 0.1 #include // malloc(), realloc(), free() #include // memcpy() /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_NO_INT64DEFINE // Here defines int64_t and uint64_t types in global namespace. // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this. #ifndef RAPIDJSON_NO_INT64DEFINE #ifdef _MSC_VER typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #define RAPIDJSON_FORCEINLINE __forceinline #else #include #define RAPIDJSON_FORCEINLINE #endif #endif // RAPIDJSON_NO_INT64TYPEDEF /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_ENDIAN #define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine #define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine //! Endianness of the machine. /*! GCC provided macro for detecting endianness of the target machine. But other compilers may not have this. User can define RAPIDJSON_ENDIAN to either RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN. */ #ifndef RAPIDJSON_ENDIAN #ifdef __BYTE_ORDER__ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN #else #define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN #endif // __BYTE_ORDER__ #else #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise. #endif #endif // RAPIDJSON_ENDIAN /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_ALIGNSIZE //! Data alignment of the machine. /*! Some machine requires strict data alignment. Currently the default uses 4 bytes alignment. User can customize this. */ #ifndef RAPIDJSON_ALIGN #define RAPIDJSON_ALIGN(x) ((x + 3) & ~3) #endif /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD // Enable SSE2 optimization. //#define RAPIDJSON_SSE2 // Enable SSE4.2 optimization. //#define RAPIDJSON_SSE42 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) #define RAPIDJSON_SIMD #endif /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_NO_SIZETYPEDEFINE #ifndef RAPIDJSON_NO_SIZETYPEDEFINE namespace rapidjson { //! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t. /*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE. */ typedef unsigned SizeType; } // namespace rapidjson #endif /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_ASSERT //! Assertion. /*! By default, rapidjson uses C assert() for assertion. User can override it by defining RAPIDJSON_ASSERT(x) macro. */ #ifndef RAPIDJSON_ASSERT #include #define RAPIDJSON_ASSERT(x) assert(x) #endif // RAPIDJSON_ASSERT /////////////////////////////////////////////////////////////////////////////// // RAPIDJSON_STATIC_ASSERT // Adopt from boost #ifdef RAPIDJSON_DEBUG #ifndef RAPIDJSON_STATIC_ASSERT namespace rapidjson { template struct STATIC_ASSERTION_FAILURE; template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; template struct StaticAssertTest {}; } // namespace rapidjson #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) #define RAPIDJSON_DO_JOIN2(X, Y) X##Y #define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\ sizeof(::rapidjson::STATIC_ASSERTION_FAILURE)>\ RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) #endif #else #define RAPIDJSON_STATIC_ASSERT(x) #endif /////////////////////////////////////////////////////////////////////////////// // Helpers #define RAPIDJSON_MULTILINEMACRO_BEGIN do { #define RAPIDJSON_MULTILINEMACRO_END \ } while((void)0, 0) /////////////////////////////////////////////////////////////////////////////// // Allocators and Encodings #include "allocators.h" #include "encodings.h" namespace rapidjson { /////////////////////////////////////////////////////////////////////////////// // Stream /*! \class rapidjson::Stream \brief Concept for reading and writing characters. For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). For write-only stream, only need to implement Put() and Flush(). \code concept Stream { typename Ch; //!< Character type of the stream. //! Read the current character from stream without moving the read cursor. Ch Peek() const; //! Read the current character from stream and moving the read cursor to next character. Ch Take(); //! Get the current read cursor. //! \return Number of characters read from start. size_t Tell(); //! Begin writing operation at the current read pointer. //! \return The begin writer pointer. Ch* PutBegin(); //! Write a character. void Put(Ch c); //! Flush the buffer. void Flush(); //! End the writing operation. //! \param begin The begin write pointer returned by PutBegin(). //! \return Number of characters written. size_t PutEnd(Ch* begin); } \endcode */ //! Put N copies of a character to a stream. template inline void PutN(Stream& stream, Ch c, size_t n) { for (size_t i = 0; i < n; i++) stream.Put(c); } /////////////////////////////////////////////////////////////////////////////// // StringStream //! Read-only string stream. /*! \implements Stream */ template struct GenericStringStream { typedef typename Encoding::Ch Ch; GenericStringStream(const Ch *src) : src_(src), head_(src) {} Ch Peek() const { return *src_; } Ch Take() { return *src_++; } size_t Tell() const { return src_ - head_; } Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } void Put(Ch) { RAPIDJSON_ASSERT(false); } void Flush() { RAPIDJSON_ASSERT(false); } size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } const Ch* src_; //!< Current read position. const Ch* head_; //!< Original head of the string. }; typedef GenericStringStream > StringStream; /////////////////////////////////////////////////////////////////////////////// // InsituStringStream //! A read-write string stream. /*! This string stream is particularly designed for in-situ parsing. \implements Stream */ template struct GenericInsituStringStream { typedef typename Encoding::Ch Ch; GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} // Read Ch Peek() { return *src_; } Ch Take() { return *src_++; } size_t Tell() { return src_ - head_; } // Write Ch* PutBegin() { return dst_ = src_; } void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } void Flush() {} size_t PutEnd(Ch* begin) { return dst_ - begin; } Ch* src_; Ch* dst_; Ch* head_; }; typedef GenericInsituStringStream > InsituStringStream; /////////////////////////////////////////////////////////////////////////////// // Type //! Type of JSON value enum Type { kNullType = 0, //!< null kFalseType = 1, //!< false kTrueType = 2, //!< true kObjectType = 3, //!< object kArrayType = 4, //!< array kStringType = 5, //!< string kNumberType = 6, //!< number }; } // namespace rapidjson #endif // RAPIDJSON_RAPIDJSON_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/reader.h000066400000000000000000000506221257152637300232450ustar00rootroot00000000000000#ifndef RAPIDJSON_READER_H_ #define RAPIDJSON_READER_H_ // Copyright (c) 2011 Milo Yip (miloyip@gmail.com) // Version 0.1 #include "rapidjson.h" #include "encodings.h" #include "internal/pow10.h" #include "internal/stack.h" #include #ifdef RAPIDJSON_SSE42 #include #elif defined(RAPIDJSON_SSE2) #include #endif #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant #endif #ifndef RAPIDJSON_PARSE_ERROR #define RAPIDJSON_PARSE_ERROR(msg, offset) \ RAPIDJSON_MULTILINEMACRO_BEGIN \ parseError_ = msg; \ errorOffset_ = offset; \ longjmp(jmpbuf_, 1); \ RAPIDJSON_MULTILINEMACRO_END #endif namespace rapidjson { /////////////////////////////////////////////////////////////////////////////// // ParseFlag //! Combination of parseFlags enum ParseFlag { kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer. kParseInsituFlag = 1, //!< In-situ(destructive) parsing. kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. }; /////////////////////////////////////////////////////////////////////////////// // Handler /*! \class rapidjson::Handler \brief Concept for receiving events from GenericReader upon parsing. \code concept Handler { typename Ch; void Null(); void Bool(bool b); void Int(int i); void Uint(unsigned i); void Int64(int64_t i); void Uint64(uint64_t i); void Double(double d); void String(const Ch* str, SizeType length, bool copy); void StartObject(); void EndObject(SizeType memberCount); void StartArray(); void EndArray(SizeType elementCount); }; \endcode */ /////////////////////////////////////////////////////////////////////////////// // BaseReaderHandler //! Default implementation of Handler. /*! This can be used as base class of any reader handler. \implements Handler */ template > struct BaseReaderHandler { typedef typename Encoding::Ch Ch; void Default() {} void Null() { Default(); } void Bool(bool) { Default(); } void Int(int) { Default(); } void Uint(unsigned) { Default(); } void Int64(int64_t) { Default(); } void Uint64(uint64_t) { Default(); } void Double(double) { Default(); } void String(const Ch*, SizeType, bool) { Default(); } void StartObject() { Default(); } void EndObject(SizeType) { Default(); } void StartArray() { Default(); } void EndArray(SizeType) { Default(); } }; /////////////////////////////////////////////////////////////////////////////// // SkipWhitespace //! Skip the JSON white spaces in a stream. /*! \param stream A input stream for skipping white spaces. \note This function has SSE2/SSE4.2 specialization. */ template void SkipWhitespace(InputStream& is) { InputStream s = is; // Use a local copy for optimization while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t') s.Take(); is = s; } #ifdef RAPIDJSON_SSE42 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. inline const char *SkipWhitespace_SIMD(const char* p) { static const char whitespace[16] = " \n\r\t"; __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]); for (;;) { __m128i s = _mm_loadu_si128((const __m128i *)p); unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); if (r == 0) // all 16 characters are whitespace p += 16; else { // some of characters may be non-whitespace #ifdef _MSC_VER // Find the index of first non-whitespace unsigned long offset; if (_BitScanForward(&offset, r)) return p + offset; #else if (r != 0) return p + __builtin_ffs(r) - 1; #endif } } } #elif defined(RAPIDJSON_SSE2) //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. inline const char *SkipWhitespace_SIMD(const char* p) { static const char whitespaces[4][17] = { " ", "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r", "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"}; __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]); __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]); __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]); __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]); for (;;) { __m128i s = _mm_loadu_si128((const __m128i *)p); __m128i x = _mm_cmpeq_epi8(s, w0); x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); unsigned short r = ~_mm_movemask_epi8(x); if (r == 0) // all 16 characters are whitespace p += 16; else { // some of characters may be non-whitespace #ifdef _MSC_VER // Find the index of first non-whitespace unsigned long offset; if (_BitScanForward(&offset, r)) return p + offset; #else if (r != 0) return p + __builtin_ffs(r) - 1; #endif } } } #endif // RAPIDJSON_SSE2 #ifdef RAPIDJSON_SIMD //! Template function specialization for InsituStringStream template<> inline void SkipWhitespace(InsituStringStream& is) { is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); } //! Template function specialization for StringStream template<> inline void SkipWhitespace(StringStream& is) { is.src_ = SkipWhitespace_SIMD(is.src_); } #endif // RAPIDJSON_SIMD /////////////////////////////////////////////////////////////////////////////// // GenericReader //! SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator. /*! GenericReader parses JSON text from a stream, and send events synchronously to an object implementing Handler concept. It needs to allocate a stack for storing a single decoded string during non-destructive parsing. For in-situ parsing, the decoded string is directly written to the source text string, no temporary buffer is required. A GenericReader object can be reused for parsing multiple JSON text. \tparam SourceEncoding Encoding of the input stream. \tparam TargetEncoding Encoding of the parse output. \tparam Allocator Allocator type for stack. */ template > class GenericReader { public: typedef typename SourceEncoding::Ch Ch; //! Constructor. /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) */ GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {} //! Parse JSON text. /*! \tparam parseFlags Combination of ParseFlag. \tparam InputStream Type of input stream. \tparam Handler Type of handler which must implement Handler concept. \param stream Input stream to be parsed. \param handler The handler to receive events. \return Whether the parsing is successful. */ template bool Parse(InputStream& is, Handler& handler) { parseError_ = 0; errorOffset_ = 0; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable #endif if (setjmp(jmpbuf_)) { #ifdef _MSC_VER #pragma warning(pop) #endif stack_.Clear(); return false; } SkipWhitespace(is); if (is.Peek() == '\0') RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", is.Tell()); else { switch (is.Peek()) { case '{': ParseObject(is, handler); break; case '[': ParseArray(is, handler); break; default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", is.Tell()); } SkipWhitespace(is); if (is.Peek() != '\0') RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", is.Tell()); } return true; } bool HasParseError() const { return parseError_ != 0; } const char* GetParseError() const { return parseError_; } size_t GetErrorOffset() const { return errorOffset_; } private: // Parse object: { string : value, ... } template void ParseObject(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == '{'); is.Take(); // Skip '{' handler.StartObject(); SkipWhitespace(is); if (is.Peek() == '}') { is.Take(); handler.EndObject(0); // empty object return; } for (SizeType memberCount = 0;;) { if (is.Peek() != '"') RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", is.Tell()); ParseString(is, handler); SkipWhitespace(is); if (is.Take() != ':') RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", is.Tell()); SkipWhitespace(is); ParseValue(is, handler); SkipWhitespace(is); ++memberCount; switch(is.Take()) { case ',': SkipWhitespace(is); break; case '}': handler.EndObject(memberCount); return; default: RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", is.Tell()); } } } // Parse array: [ value, ... ] template void ParseArray(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == '['); is.Take(); // Skip '[' handler.StartArray(); SkipWhitespace(is); if (is.Peek() == ']') { is.Take(); handler.EndArray(0); // empty array return; } for (SizeType elementCount = 0;;) { ParseValue(is, handler); ++elementCount; SkipWhitespace(is); switch (is.Take()) { case ',': SkipWhitespace(is); break; case ']': handler.EndArray(elementCount); return; default: RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", is.Tell()); } } } template void ParseNull(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == 'n'); is.Take(); if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') handler.Null(); else RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1); } template void ParseTrue(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == 't'); is.Take(); if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') handler.Bool(true); else RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell()); } template void ParseFalse(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == 'f'); is.Take(); if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') handler.Bool(false); else RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1); } // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). template unsigned ParseHex4(InputStream& is) { InputStream s = is; // Use a local copy for optimization unsigned codepoint = 0; for (int i = 0; i < 4; i++) { Ch c = s.Take(); codepoint <<= 4; codepoint += c; if (c >= '0' && c <= '9') codepoint -= '0'; else if (c >= 'A' && c <= 'F') codepoint -= 'A' - 10; else if (c >= 'a' && c <= 'f') codepoint -= 'a' - 10; else RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1); } is = s; // Restore is return codepoint; } class StackStream { public: typedef typename TargetEncoding::Ch Ch; StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} void Put(Ch c) { *stack_.template Push() = c; ++length_; } internal::Stack& stack_; SizeType length_; private: // Prohibit assignment for VC C4512 warning StackStream& operator=(const StackStream&); }; // Parse string and generate String event. Different code paths for kParseInsituFlag. template void ParseString(InputStream& is, Handler& handler) { InputStream s = is; // Local copy for optimization if (parseFlags & kParseInsituFlag) { Ch *head = s.PutBegin(); ParseStringToStream(s, s); size_t length = s.PutEnd(head) - 1; RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false); } else { StackStream stackStream(stack_); ParseStringToStream(s, stackStream); handler.String(stack_.template Pop(stackStream.length_), stackStream.length_ - 1, true); } is = s; // Restore is } // Parse string to an output is // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. template RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 static const char escape[256] = { Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 }; #undef Z16 RAPIDJSON_ASSERT(is.Peek() == '\"'); is.Take(); // Skip '\"' for (;;) { Ch c = is.Peek(); if (c == '\\') { // Escape is.Take(); Ch e = is.Take(); if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) os.Put(escape[(unsigned char)e]); else if (e == 'u') { // Unicode unsigned codepoint = ParseHex4(is); if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair if (is.Take() != '\\' || is.Take() != 'u') RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", is.Tell() - 2); unsigned codepoint2 = ParseHex4(is); if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", is.Tell() - 2); codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; } TEncoding::Encode(os, codepoint); } else RAPIDJSON_PARSE_ERROR("Unknown escape character", is.Tell() - 1); } else if (c == '"') { // Closing double quote is.Take(); os.Put('\0'); // null-terminate the string return; } else if (c == '\0') RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", is.Tell() - 1); else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", is.Tell() - 1); else { if (parseFlags & kParseValidateEncodingFlag ? !Transcoder::Validate(is, os) : !Transcoder::Transcode(is, os)) RAPIDJSON_PARSE_ERROR("Invalid encoding", is.Tell()); } } } template void ParseNumber(InputStream& is, Handler& handler) { InputStream s = is; // Local copy for optimization // Parse minus bool minus = false; if (s.Peek() == '-') { minus = true; s.Take(); } // Parse int: zero / ( digit1-9 *DIGIT ) unsigned i; bool try64bit = false; if (s.Peek() == '0') { i = 0; s.Take(); } else if (s.Peek() >= '1' && s.Peek() <= '9') { i = s.Take() - '0'; if (minus) while (s.Peek() >= '0' && s.Peek() <= '9') { if (i >= 214748364) { // 2^31 = 2147483648 if (i != 214748364 || s.Peek() > '8') { try64bit = true; break; } } i = i * 10 + (s.Take() - '0'); } else while (s.Peek() >= '0' && s.Peek() <= '9') { if (i >= 429496729) { // 2^32 - 1 = 4294967295 if (i != 429496729 || s.Peek() > '5') { try64bit = true; break; } } i = i * 10 + (s.Take() - '0'); } } else RAPIDJSON_PARSE_ERROR("Expect a value here.", is.Tell()); // Parse 64bit int uint64_t i64 = 0; bool useDouble = false; if (try64bit) { i64 = i; if (minus) while (s.Peek() >= '0' && s.Peek() <= '9') { if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808 if (i64 != 922337203685477580uLL || s.Peek() > '8') { useDouble = true; break; } i64 = i64 * 10 + (s.Take() - '0'); } else while (s.Peek() >= '0' && s.Peek() <= '9') { if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615 if (i64 != 1844674407370955161uLL || s.Peek() > '5') { useDouble = true; break; } i64 = i64 * 10 + (s.Take() - '0'); } } // Force double for big integer double d = 0.0; if (useDouble) { d = (double)i64; while (s.Peek() >= '0' && s.Peek() <= '9') { if (d >= 1E307) RAPIDJSON_PARSE_ERROR("Number too big to store in double", is.Tell()); d = d * 10 + (s.Take() - '0'); } } // Parse frac = decimal-point 1*DIGIT int expFrac = 0; if (s.Peek() == '.') { if (!useDouble) { d = try64bit ? (double)i64 : (double)i; useDouble = true; } s.Take(); if (s.Peek() >= '0' && s.Peek() <= '9') { d = d * 10 + (s.Take() - '0'); --expFrac; } else RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", is.Tell()); while (s.Peek() >= '0' && s.Peek() <= '9') { if (expFrac > -16) { d = d * 10 + (s.Peek() - '0'); --expFrac; } s.Take(); } } // Parse exp = e [ minus / plus ] 1*DIGIT int exp = 0; if (s.Peek() == 'e' || s.Peek() == 'E') { if (!useDouble) { d = try64bit ? (double)i64 : (double)i; useDouble = true; } s.Take(); bool expMinus = false; if (s.Peek() == '+') s.Take(); else if (s.Peek() == '-') { s.Take(); expMinus = true; } if (s.Peek() >= '0' && s.Peek() <= '9') { exp = s.Take() - '0'; while (s.Peek() >= '0' && s.Peek() <= '9') { exp = exp * 10 + (s.Take() - '0'); if (exp > 308) RAPIDJSON_PARSE_ERROR("Number too big to store in double", is.Tell()); } } else RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell()); if (expMinus) exp = -exp; } // Finish parsing, call event according to the type of number. if (useDouble) { d *= internal::Pow10(exp + expFrac); handler.Double(minus ? -d : d); } else { if (try64bit) { if (minus) handler.Int64(-(int64_t)i64); else handler.Uint64(i64); } else { if (minus) handler.Int(-(int)i); else handler.Uint(i); } } is = s; // restore is } // Parse any JSON value template void ParseValue(InputStream& is, Handler& handler) { switch (is.Peek()) { case 'n': ParseNull (is, handler); break; case 't': ParseTrue (is, handler); break; case 'f': ParseFalse (is, handler); break; case '"': ParseString(is, handler); break; case '{': ParseObject(is, handler); break; case '[': ParseArray (is, handler); break; default : ParseNumber(is, handler); } } static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. jmp_buf jmpbuf_; //!< setjmp buffer for fast exit from nested parsing function calls. const char* parseError_; size_t errorOffset_; }; // class GenericReader //! Reader with UTF8 encoding and default allocator. typedef GenericReader, UTF8<> > Reader; } // namespace rapidjson #ifdef _MSC_VER #pragma warning(pop) #endif #endif // RAPIDJSON_READER_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/stringbuffer.h000066400000000000000000000025621257152637300245030ustar00rootroot00000000000000#ifndef RAPIDJSON_STRINGBUFFER_H_ #define RAPIDJSON_STRINGBUFFER_H_ #include "rapidjson.h" #include "internal/stack.h" namespace rapidjson { //! Represents an in-memory output stream. /*! \tparam Encoding Encoding of the stream. \tparam Allocator type for allocating memory buffer. \implements Stream */ template struct GenericStringBuffer { typedef typename Encoding::Ch Ch; GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} void Put(Ch c) { *stack_.template Push() = c; } void Flush() {} void Clear() { stack_.Clear(); } const Ch* GetString() const { // Push and pop a null terminator. This is safe. *stack_.template Push() = '\0'; stack_.template Pop(1); return stack_.template Bottom(); } size_t GetSize() const { return stack_.GetSize(); } static const size_t kDefaultCapacity = 256; mutable internal::Stack stack_; }; typedef GenericStringBuffer > StringBuffer; //! Implement specialized version of PutN() with memset() for better performance. template<> inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { memset(stream.stack_.Push(n), c, n * sizeof(c)); } } // namespace rapidjson #endif // RAPIDJSON_STRINGBUFFER_H_ davix-R_0_5_0/deps/rapidjson/include/rapidjson/writer.h000066400000000000000000000162341257152637300233200ustar00rootroot00000000000000#ifndef RAPIDJSON_WRITER_H_ #define RAPIDJSON_WRITER_H_ #include "rapidjson.h" #include "internal/stack.h" #include "internal/strfunc.h" #include // snprintf() or _sprintf_s() #include // placement new #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant #endif namespace rapidjson { //! JSON writer /*! Writer implements the concept Handler. It generates JSON text by events to an output os. User may programmatically calls the functions of a writer to generate JSON text. On the other side, a writer can also be passed to objects that generates events, for example Reader::Parse() and Document::Accept(). \tparam OutputStream Type of output stream. \tparam SourceEncoding Encoding of both source strings. \tparam TargetEncoding Encoding of and output stream. \implements Handler */ template, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > class Writer { public: typedef typename SourceEncoding::Ch Ch; Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : os_(os), level_stack_(allocator, levelDepth * sizeof(Level)) {} //@name Implementation of Handler //@{ Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; } Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; } Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; } Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } Writer& String(const Ch* str, SizeType length, bool copy = false) { (void)copy; Prefix(kStringType); WriteString(str, length); return *this; } Writer& StartObject() { Prefix(kObjectType); new (level_stack_.template Push()) Level(false); WriteStartObject(); return *this; } Writer& EndObject(SizeType memberCount = 0) { (void)memberCount; RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); level_stack_.template Pop(1); WriteEndObject(); if (level_stack_.Empty()) // end of json text os_.Flush(); return *this; } Writer& StartArray() { Prefix(kArrayType); new (level_stack_.template Push()) Level(true); WriteStartArray(); return *this; } Writer& EndArray(SizeType elementCount = 0) { (void)elementCount; RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); level_stack_.template Pop(1); WriteEndArray(); if (level_stack_.Empty()) // end of json text os_.Flush(); return *this; } //@} //! Simpler but slower overload. Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } protected: //! Information for each nested level struct Level { Level(bool inArray_) : inArray(inArray_), valueCount(0) {} bool inArray; //!< true if in array, otherwise in object size_t valueCount; //!< number of values in this level }; static const size_t kDefaultLevelDepth = 32; void WriteNull() { os_.Put('n'); os_.Put('u'); os_.Put('l'); os_.Put('l'); } void WriteBool(bool b) { if (b) { os_.Put('t'); os_.Put('r'); os_.Put('u'); os_.Put('e'); } else { os_.Put('f'); os_.Put('a'); os_.Put('l'); os_.Put('s'); os_.Put('e'); } } void WriteInt(int i) { if (i < 0) { os_.Put('-'); i = -i; } WriteUint((unsigned)i); } void WriteUint(unsigned u) { char buffer[10]; char *p = buffer; do { *p++ = (u % 10) + '0'; u /= 10; } while (u > 0); do { --p; os_.Put(*p); } while (p != buffer); } void WriteInt64(int64_t i64) { if (i64 < 0) { os_.Put('-'); i64 = -i64; } WriteUint64((uint64_t)i64); } void WriteUint64(uint64_t u64) { char buffer[20]; char *p = buffer; do { *p++ = char(u64 % 10) + '0'; u64 /= 10; } while (u64 > 0); do { --p; os_.Put(*p); } while (p != buffer); } //! \todo Optimization with custom double-to-string converter. void WriteDouble(double d) { char buffer[100]; #if _MSC_VER int ret = sprintf_s(buffer, sizeof(buffer), "%g", d); #else int ret = snprintf(buffer, sizeof(buffer), "%g", d); #endif RAPIDJSON_ASSERT(ret >= 1); for (int i = 0; i < ret; i++) os_.Put(buffer[i]); } void WriteString(const Ch* str, SizeType length) { static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static const char escape[256] = { #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //0 1 2 3 4 5 6 7 8 9 A B C D E F 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 Z16, Z16, // 30~4F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF #undef Z16 }; os_.Put('\"'); GenericStringStream is(str); while (is.Tell() < length) { const Ch c = is.Peek(); if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) { is.Take(); os_.Put('\\'); os_.Put(escape[(unsigned char)c]); if (escape[(unsigned char)c] == 'u') { os_.Put('0'); os_.Put('0'); os_.Put(hexDigits[(unsigned char)c >> 4]); os_.Put(hexDigits[(unsigned char)c & 0xF]); } } else Transcoder::Transcode(is, os_); } os_.Put('\"'); } void WriteStartObject() { os_.Put('{'); } void WriteEndObject() { os_.Put('}'); } void WriteStartArray() { os_.Put('['); } void WriteEndArray() { os_.Put(']'); } void Prefix(Type type) { (void)type; if (level_stack_.GetSize() != 0) { // this value is not at root Level* level = level_stack_.template Top(); if (level->valueCount > 0) { if (level->inArray) os_.Put(','); // add comma if it is not the first element in array else // in object os_.Put((level->valueCount % 2 == 0) ? ',' : ':'); } if (!level->inArray && level->valueCount % 2 == 0) RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name level->valueCount++; } else RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); } OutputStream& os_; internal::Stack level_stack_; private: // Prohibit assignment for VC C4512 warning Writer& operator=(const Writer& w); }; } // namespace rapidjson #ifdef _MSC_VER #pragma warning(pop) #endif #endif // RAPIDJSON_RAPIDJSON_H_ davix-R_0_5_0/deps/simple_getpass/000077500000000000000000000000001257152637300172375ustar00rootroot00000000000000davix-R_0_5_0/deps/simple_getpass/simple_get_pass.cpp000066400000000000000000000044051257152637300231240ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "simple_get_pass.h" #include #include #if defined HAVE_TERMIOS_H #include #elif defined HAVE_GETPASS #include #elif defined HAVE_SETCONSOLEMODE #include #else #error "impossible to compile simple_get_pass" #endif int simple_get_pass(char* passwd, size_t max_size){ int ret = 0; #if defined HAVE_TERMIOS_H struct termios old_term, new_term; FILE* stream = stdin; /* Turn echoing off and fail if we can't. */ if (tcgetattr (fileno (stream), &old_term) != 0) return -1; new_term = old_term; new_term.c_lflag &= ~ECHO; if (tcsetattr (fileno (stream), TCSAFLUSH, &new_term) != 0) return -1; /* Read the password. */ std::cin.getline(passwd, max_size); ret = strlen(passwd); /* Restore terminal. */ (void) tcsetattr (fileno (stream), TCSAFLUSH, &old_term); #elif HAVE_SETCONSOLEMODE HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE); DWORD mode; if (!GetConsoleMode(hstdin, &mode)) return -1; if (hstdin == INVALID_HANDLE_VALUE || !(SetConsoleMode(hstdin, 0))) return -1; std::cin.getline(passwd, max_size); ret = strlen(passwd); if (!SetConsoleMode(hstdin, mode)) return -1; #else char* p; if((p = getpass("")) == NULL) return -1; *passwd = strdup(p); ret = strlen(p); #endif return ret; } davix-R_0_5_0/deps/simple_getpass/simple_get_pass.h000066400000000000000000000021341257152637300225660ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #pragma once #ifndef SIMPLE_GET_PASS_H #define SIMPLE_GET_PASS_H #ifdef __cplusplus extern "C" { #endif int simple_get_pass(char* passwd, size_t max_size); #ifdef __cplusplus } #endif #endif // SIMPLE_GET_PASS_H davix-R_0_5_0/deps/string_utils/000077500000000000000000000000001257152637300167465ustar00rootroot00000000000000davix-R_0_5_0/deps/string_utils/stringutils.cpp000066400000000000000000000020521257152637300220400ustar00rootroot00000000000000#include #include "stringutils.hpp" #include #include namespace StrUtil{ std::vector tokenSplit(const std::string & str, const std::string & delimiter){ std::vector res; std::string::const_iterator it_prev, it_cur; for(it_prev = it_cur = str.begin(); it_cur < str.end(); ((it_prev != str.end())?(it_prev++):(it_prev))){ it_cur = std::find_first_of(it_prev, str.end(), delimiter.begin(), delimiter.end()); if(it_prev != it_cur) res.push_back(std::string(it_prev,it_cur)); it_prev = it_cur; } return res; } int compare_ncase(const std::string & str1, const std::string & str2){ return strcasecmp(str1.c_str(), str2.c_str()); } int compare_ncase(const std::string &str1, const std::string &str2, size_t max){ return strncasecmp(str1.c_str(), str2.c_str(), max); } int compare_ncase(const std::string & str1, off_t offset, size_t size, const char* cstr2){ return strncasecmp(str1.c_str(), cstr2+ offset, size); } } davix-R_0_5_0/deps/string_utils/stringutils.hpp000066400000000000000000000064511257152637300220540ustar00rootroot00000000000000#ifndef STRINGUTILS_HPP #define STRINGUTILS_HPP #include #include #include #include #include #include #include #include typedef std::vector stringVec; namespace StrUtil{ struct isSlash{ bool operator()(char c) const{ return ( c == '/'); } typedef char argument_type; }; struct isCrLf{ bool operator()(char c) const{ return (( c == '\n') || (c == '\r')); } typedef char argument_type; }; struct isSpace{ bool operator()(char c) const{ return ::isspace(c); } typedef char argument_type; }; struct isHexa{ bool operator()(char c) const{ return (isdigit(c) || (isalpha(c) && ( tolower(c) >= 'a' && tolower(c) <= 'f'))); } typedef char argument_type; }; // predicates inline bool charEqCase(char c1, char c2){ return (c1 == c2 || ::tolower(c1) == ::tolower(c2)); } ///////////////////////////// // Parsing ///////////////////////////// //split a string following an array of delimiter ( strtok like ) std::vector tokenSplit(const std::string & str, const std::string & delimiter); inline std::vector &split(const std::string &s, char delim, std::vector &res) { std::stringstream ss(s); std::string item; item.reserve(s.size()); while (std::getline(ss, item, delim)) { res.push_back(item); } return res; } inline std::string & remove(std::string & str, char c){ std::string::iterator it = std::remove(str.begin(), str.end(), c); str.erase(it, str.end()); return str; } /////////////////////////// /// compare utils ////////////////////// // compare two C++ string case insensitive int compare_ncase(const std::string & str1, const std::string & str2); int compare_ncase(const std::string &str1, const std::string &str2, size_t max); int compare_ncase(const std::string & str1, off_t offset, size_t size, const char* cstr2); inline size_t copy_std_string_to_buff(char* buffer, size_t max_size, const std::string & str){ const size_t str_size = str.copy(buffer, max_size-1); buffer[str_size]= '\0'; return str_size; } /////////////////////////////////// ///// String utilities ////////////////////////////////// // trim from start template inline std::string <rim(std::string &s, const Func & pred) { s.erase(s.begin(), static_cast(std::find_if(s.begin(), s.end(), std::not1(pred)))); return s; } inline std::string <rim(std::string &s) { return ltrim(s, isSpace()); } // trim from end template inline std::string &rtrim(std::string &s, const Func & pred) { s.erase(static_cast(std::find_if(s.rbegin(), s.rend(), std::not1(pred)).base()), s.end()); return s; } inline std::string &rtrim(std::string &s) { return rtrim(s, isSpace()); } // trim from both template inline std::string &trim(std::string &s, const Func & pred) { return ltrim(rtrim(s, pred), pred); } inline std::string &trim(std::string &s) { return ltrim(rtrim(s)); } inline std::string & toLower(std::string & str){ std::transform(str.begin(), str.end(), str.begin(), ::tolower); return str; } } #endif // STRINGUTILS_HPP davix-R_0_5_0/deps/strptime/000077500000000000000000000000001257152637300160675ustar00rootroot00000000000000davix-R_0_5_0/deps/strptime/strptime.c000066400000000000000000000447101257152637300201100ustar00rootroot00000000000000/* Convert a string representation of time to a time value. Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. 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. */ /** * @file src/strptime.c * @brief This is a slightly modified version by the "R Project" * with locale support removed. * Support for Windows locales added by Nils Durner for PlibC */ #include //#include "plibc_private.h" void get_locale_strings(void); /* XXX This version of the implementation is not really complete. Some of the fields cannot add information alone. But if seeing some of them in the same format (such as year, week and weekday) this is enough information for determining the date. */ #include #include #include #include #define match_char(ch1, ch2) if (ch1 != ch2) return NULL #ifndef Macintosh #if defined __GNUC__ && __GNUC__ >= 2 # define match_string(cs1, s2) \ ({ size_t len = strlen (cs1); \ int result = strncasecmp ((cs1), (s2), len) == 0; \ if (result) (s2) += len; \ result; }) #else /* Oh come on. Get a reasonable compiler. */ # define match_string(cs1, s2) \ (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) #endif #else # define match_string(cs1, s2) \ (strncmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) #endif /* mac */ /* We intentionally do not use isdigit() for testing because this will lead to problems with the wide character version. */ #define get_number(from, to, n) \ do { \ int __n = n; \ val = 0; \ while (*rp == ' ') \ ++rp; \ if (*rp < '0' || *rp > '9') \ return NULL; \ do { \ val *= 10; \ val += *rp++ - '0'; \ } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ if (val < from || val > to) \ return NULL; \ } while (0) # define get_alt_number(from, to, n) \ /* We don't have the alternate representation. */ \ get_number(from, to, n) #define recursive(new_fmt) \ (*(new_fmt) != '\0' \ && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL) /* This version: may overwrite these with versions for the locale */ static char weekday_name[][20] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static char ab_weekday_name[][10] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static char month_name[][20] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static char ab_month_name[][10] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char am_pm[][4] = {"AM", "PM"}; static int have_used_strptime = 0; static const unsigned short int __mon_yday[2][13] = { /* Normal years. */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, /* Leap years. */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; /* Status of lookup: do we use the locale data or the raw data? */ enum locale_status { not, loc, raw }; # define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) /* Convert Windows date picture to POSIX style. The converted format string may not mach exactly. */ void conv_winpic(char *win, char **posix) { char *src, *dst; src = win; *posix = dst = malloc(strlen(src) * 2 + 1); while(*src) { if (src[0] == 'y') if (src[1] == 'y') if (src[2] == 'y') if (src[3] == 'y') { strcpy(dst, "%Y"); if (src[4] == 'y') src += 5; // yyyyy else src += 4; // yyyy dst += 2; } else // yyy { // undefined strcpy(dst, "yyy"); dst += 3; src += 3; } else // yy { strcpy(dst, "%y"); dst += 2; src += 2; } else // y { // impossible to convert properly strcpy(dst, "%y"); dst += 2; src++; } else if (src[0] == 'M') { if (src[1] == 'M') if (src[2] == 'M') if (src[3] == 'M') // MMMM { strcpy(dst, "%b"); src += 4; } else // MMM { // impossible to convert properly strcpy(dst, "%m"); src += 3; } else // MM { strcpy(dst, "%m"); src += 2; } else // M { strcpy(dst, "%m"); src += 1; } dst += 2; } else if (src[0] == 'd') { if (src[1] == 'd') if (src[2] == 'd') if (src[3] == 'd') // dddd { strcpy(dst, "%a"); src += 4; } else // ddd { // impossible to convert properly strcpy(dst, "%d"); src += 3; } else // dd { strcpy(dst, "%d"); src += 2; } else // d { strcpy(dst, "%d"); src++; } dst += 2; } else if (src[0] == 'g' && src[1] == 'g') // impossible to convert src += 2; else if (src[0] == 'h') { strcpy(dst, "%I"); dst += 2; if (src[1] == 'h') src += 2; else src += 1; } else if (src[0] == 'H') { strcpy(dst, "%H"); dst += 2; if (src[1] == 'H') src += 2; else src += 1; } else if (src[0] == 'm') { strcpy(dst, "%M"); dst += 2; if (src[1] == 'm') src += 2; else src += 1; } else if (src[0] == 's') { strcpy(dst, "%S"); dst += 2; if (src[1] == 's') src += 2; else src += 1; } else if (src[0] == 't') { strcpy(dst, "%p"); dst += 2; if (src[1] == 't') src += 2; else src += 1; } else { *dst = *src; dst++; src++; } } dst[0] = 0; } /* Compute the day of the week. */ void day_of_the_week (struct tm *tm) { /* We know that January 1st 1970 was a Thursday (= 4). Compute the the difference between this data in the one on TM and so determine the weekday. */ int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); int wday = (-473 + (365 * (tm->tm_year - 70)) + (corr_year / 4) - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + (((corr_year / 4) / 25) / 4) + __mon_yday[0][tm->tm_mon] + tm->tm_mday - 1); tm->tm_wday = ((wday % 7) + 7) % 7; } /* Compute the day of the year. */ void day_of_the_year (struct tm *tm) { tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] + (tm->tm_mday - 1)); } char * strptime_internal (const char *rp, const char *fmt, struct tm *tm, enum locale_status *decided) { const char *rp_backup; int cnt; size_t val; int have_I, is_pm; int century, want_century; int have_wday, want_xday; int have_yday; int have_mon, have_mday; have_I = is_pm = 0; century = -1; want_century = 0; have_wday = want_xday = have_yday = have_mon = have_mday = 0; while (*fmt != '\0') { /* A white space in the format string matches 0 more or white space in the input string. */ if (isspace (*fmt)) { while (isspace (*rp)) ++rp; ++fmt; continue; } /* Any character but `%' must be matched by the same character in the iput string. */ if (*fmt != '%') { match_char (*fmt++, *rp++); continue; } ++fmt; /* We need this for handling the `E' modifier. */ start_over: /* Make back up of current processing pointer. */ rp_backup = rp; switch (*fmt++) { case '%': /* Match the `%' character itself. */ match_char ('%', *rp++); break; case 'a': case 'A': /* Match day of week. */ for (cnt = 0; cnt < 7; ++cnt) { if (*decided != loc && (match_string (weekday_name[cnt], rp) || match_string (ab_weekday_name[cnt], rp))) { *decided = raw; break; } } if (cnt == 7) /* Does not match a weekday name. */ return NULL; tm->tm_wday = cnt; have_wday = 1; break; case 'b': case 'B': case 'h': /* Match month name. */ for (cnt = 0; cnt < 12; ++cnt) { if (match_string (month_name[cnt], rp) || match_string (ab_month_name[cnt], rp)) { *decided = raw; break; } } if (cnt == 12) /* Does not match a month name. */ return NULL; tm->tm_mon = cnt; want_xday = 1; break; case 'c': /* Match locale's date and time format. */ return strptime_internal (rp, "%x %X", tm, decided); break; case 'C': /* Match century number. */ get_number (0, 99, 2); century = val; want_xday = 1; break; case 'd': case 'e': /* Match day of month. */ get_number (1, 31, 2); tm->tm_mday = val; have_mday = 1; want_xday = 1; break; case 'F': if (!recursive ("%Y-%m-%d")) return NULL; want_xday = 1; break; case 'x': { char *pic; unsigned int loc; char winpic[100]; int ret; loc = GetThreadLocale(); GetLocaleInfo(loc, LOCALE_SSHORTDATE, winpic, 100); conv_winpic(winpic, &pic); ret = recursive(pic); free(pic); if (!ret) return NULL; want_xday = 1; } break; case 'D': /* Match standard day format. */ if (!recursive ("%m/%d/%y")) return NULL; want_xday = 1; break; case 'k': case 'H': /* Match hour in 24-hour clock. */ get_number (0, 23, 2); tm->tm_hour = val; have_I = 0; break; case 'I': /* Match hour in 12-hour clock. */ get_number (1, 12, 2); tm->tm_hour = val % 12; have_I = 1; break; case 'j': /* Match day number of year. */ get_number (1, 366, 3); tm->tm_yday = val - 1; have_yday = 1; break; case 'm': /* Match number of month. */ get_number (1, 12, 2); tm->tm_mon = val - 1; have_mon = 1; want_xday = 1; break; case 'M': /* Match minute. */ get_number (0, 59, 2); tm->tm_min = val; break; case 'n': case 't': /* Match any white space. */ while (isspace (*rp)) ++rp; break; case 'p': /* Match locale's equivalent of AM/PM. */ if (!match_string (am_pm[0], rp)) if (match_string (am_pm[1], rp)) is_pm = 1; else return NULL; break; case 'r': return strptime_internal (rp, "%x %X", tm, decided); break; case 'R': if (!recursive ("%H:%M")) return NULL; break; case 's': { /* The number of seconds may be very high so we cannot use the `get_number' macro. Instead read the number character for character and construct the result while doing this. */ time_t secs = 0; if (*rp < '0' || *rp > '9') /* We need at least one digit. */ return NULL; do { secs *= 10; secs += *rp++ - '0'; } while (*rp >= '0' && *rp <= '9'); if ((tm = localtime (&secs)) == NULL) /* Error in function. */ return NULL; } break; case 'S': get_number (0, 61, 2); tm->tm_sec = val; break; case 'X': { char *pic; unsigned int loc; char winpic[100]; int ret; loc = GetThreadLocale(); GetLocaleInfo(loc, LOCALE_STIMEFORMAT, winpic, 100); conv_winpic(winpic, &pic); ret = recursive(pic); free(pic); if (!ret) return NULL; } break; case 'T': return strptime_internal (rp, "%H:%M:%S", tm, decided); break; case 'u': get_number (1, 7, 1); tm->tm_wday = val % 7; have_wday = 1; break; case 'g': get_number (0, 99, 2); /* XXX This cannot determine any field in TM. */ break; case 'G': if (*rp < '0' || *rp > '9') return NULL; /* XXX Ignore the number since we would need some more information to compute a real date. */ do ++rp; while (*rp >= '0' && *rp <= '9'); break; case 'U': case 'V': case 'W': get_number (0, 53, 2); /* XXX This cannot determine any field in TM without some information. */ break; case 'w': /* Match number of weekday. */ get_number (0, 6, 1); tm->tm_wday = val; have_wday = 1; break; case 'y': /* Match year within century. */ get_number (0, 99, 2); /* The "Year 2000: The Millennium Rollover" paper suggests that values in the range 69-99 refer to the twentieth century. */ tm->tm_year = val >= 69 ? val : val + 100; /* Indicate that we want to use the century, if specified. */ want_century = 1; want_xday = 1; break; case 'Y': /* Match year including century number. */ get_number (0, 9999, 4); tm->tm_year = val - 1900; want_century = 0; want_xday = 1; break; case 'Z': /* XXX How to handle this? */ break; case 'E': /* We have no information about the era format. Just use the normal format. */ if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' && *fmt != 'x' && *fmt != 'X') /* This is an invalid format. */ return NULL; goto start_over; case 'O': switch (*fmt++) { case 'd': case 'e': /* Match day of month using alternate numeric symbols. */ get_alt_number (1, 31, 2); tm->tm_mday = val; have_mday = 1; want_xday = 1; break; case 'H': /* Match hour in 24-hour clock using alternate numeric symbols. */ get_alt_number (0, 23, 2); tm->tm_hour = val; have_I = 0; break; case 'I': /* Match hour in 12-hour clock using alternate numeric symbols. */ get_alt_number (1, 12, 2); tm->tm_hour = val - 1; have_I = 1; break; case 'm': /* Match month using alternate numeric symbols. */ get_alt_number (1, 12, 2); tm->tm_mon = val - 1; have_mon = 1; want_xday = 1; break; case 'M': /* Match minutes using alternate numeric symbols. */ get_alt_number (0, 59, 2); tm->tm_min = val; break; case 'S': /* Match seconds using alternate numeric symbols. */ get_alt_number (0, 61, 2); tm->tm_sec = val; break; case 'U': case 'V': case 'W': get_alt_number (0, 53, 2); /* XXX This cannot determine any field in TM without further information. */ break; case 'w': /* Match number of weekday using alternate numeric symbols. */ get_alt_number (0, 6, 1); tm->tm_wday = val; have_wday = 1; break; case 'y': /* Match year within century using alternate numeric symbols. */ get_alt_number (0, 99, 2); tm->tm_year = val >= 69 ? val : val + 100; want_xday = 1; break; default: return NULL; } break; default: return NULL; } } if (have_I && is_pm) tm->tm_hour += 12; if (century != -1) { if (want_century) tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; else /* Only the century, but not the year. Strange, but so be it. */ tm->tm_year = (century - 19) * 100; } if (want_xday && !have_wday) { if ( !(have_mon && have_mday) && have_yday) { /* we don't have tm_mon and/or tm_mday, compute them */ int t_mon = 0; while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) t_mon++; if (!have_mon) tm->tm_mon = t_mon - 1; if (!have_mday) tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1; } day_of_the_week (tm); } if (want_xday && !have_yday) day_of_the_year (tm); return (char *) rp; } char * __strptime (const char *buf, const char *format, struct tm *tm) { enum locale_status decided; #ifdef HAVE_LOCALE_H if(!have_used_strptime) { get_locale_strings(); /* have_used_strptime = 1; might change locale during session */ } #endif decided = raw; return strptime_internal (buf, format, tm, &decided); } #ifdef HAVE_LOCALE_H void get_locale_strings(void) { int i; struct tm tm; char buff[4]; tm.tm_sec = tm.tm_min = tm.tm_hour = tm.tm_mday = tm.tm_mon = tm.tm_isdst = 0; tm.tm_year = 30; for(i = 0; i < 12; i++) { tm.tm_mon = i; strftime(ab_month_name[i], 10, "%b", &tm); strftime(month_name[i], 20, "%B", &tm); } tm.tm_mon = 0; for(i = 0; i < 7; i++) { tm.tm_mday = tm.tm_yday = i+1; /* 2000-1-2 was a Sunday */ tm.tm_wday = i; strftime(ab_weekday_name[i], 10, "%a", &tm); strftime(weekday_name[i], 20, "%A", &tm); } tm.tm_hour = 1; /* in locales where these are unused, they may be empty: better not to reset them then */ strftime(buff, 4, "%p", &tm); if(strlen(buff)) strcpy(am_pm[0], buff); tm.tm_hour = 13; strftime(buff, 4, "%p", &tm); if(strlen(buff)) strcpy(am_pm[1], buff); } #endif davix-R_0_5_0/deps/system_utils/000077500000000000000000000000001257152637300167645ustar00rootroot00000000000000davix-R_0_5_0/deps/system_utils/env_utils.hpp000066400000000000000000000004511257152637300215050ustar00rootroot00000000000000#ifndef ENV_UTILS_HPP #define ENV_UTILS_HPP #include namespace EnvUtils{ inline std::string getEnv(const std::string & key, const std::string & default_value){ char* env = getenv(key.c_str()); return ((env!=NULL)?(std::string(env)):default_value); } } #endif // ENV_UTILS_HPP davix-R_0_5_0/dist/000077500000000000000000000000001257152637300142305ustar00rootroot00000000000000davix-R_0_5_0/dist/CMakeLists.txt000066400000000000000000000005251257152637300167720ustar00rootroot00000000000000 # configure abi checker configure_file(${CMAKE_CURRENT_SOURCE_DIR}/abi/abi_checker_last.xml.in ${CMAKE_CURRENT_BINARY_DIR}/abi/abi_checker_last.xml) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/abi/check_abi.sh.in ${CMAKE_CURRENT_BINARY_DIR}/abi/check_abi.sh) add_custom_target(abi-check "${CMAKE_CURRENT_BINARY_DIR}/abi/check_abi.sh") davix-R_0_5_0/dist/abi/000077500000000000000000000000001257152637300147635ustar00rootroot00000000000000davix-R_0_5_0/dist/abi/abi_checker_last.xml.in000066400000000000000000000016251257152637300213600ustar00rootroot00000000000000 @VERSION_STRING@ @CMAKE_SOURCE_DIR@/include/davix/ @CMAKE_BINARY_DIR@/src/ _ZN5Davix19httpcodeToDavixCodeEiRKSsS1_PPNS_10DavixErrorE _ZN5Davix15httpcodeIsValidEi _ZN5Davix4HookINS_17HookReceiveHeaderEE7getTypeEPS2_ _ZN5Davix4HookINS_17HookReceiveHeaderEE7getTypeEv _ZN5Davix4HookINS_19HookRequestPostExecEE7getTypeEPS2_ _ZN5Davix4HookINS_19HookRequestPostExecEE7getTypeEv _ZN5Davix4HookINS_18HookRequestPreExecEE7getTypeEPS2_ _ZN5Davix4HookINS_18HookRequestPreExecEE7getTypeEv _ZN5Davix4HookINS_14HookSendHeaderEE7getTypeEPS2_ _ZN5Davix4HookINS_14HookSendHeaderEE7getTypeEv _ZlsRSoRKN5Davix3UriE davix-R_0_5_0/dist/abi/abi_checker_std_version.xml000066400000000000000000000012731257152637300223460ustar00rootroot00000000000000 stdversion /usr/include/davix/ /usr/lib/ /usr/lib64/ _ZN5Davix19httpcodeToDavixCodeEiRKSsS1_PPNS_10DavixErrorE _ZN5Davix15httpcodeIsValidEi _ZN5Davix4HookINS_17HookReceiveHeaderEE7getTypeEPS2_ _ZN5Davix4HookINS_19HookRequestPostExecEE7getTypeEPS2_ _ZN5Davix4HookINS_18HookRequestPreExecEE7getTypeEPS2_ _ZN5Davix4HookINS_14HookSendHeaderEE7getTypeEPS2_ _ZlsRSoRKN5Davix3UriE davix-R_0_5_0/dist/abi/abi_checker_std_version_32.xml000066400000000000000000000012531257152637300226500ustar00rootroot00000000000000 stdversion /usr/include/davix/ /usr/lib/ _ZN5Davix19httpcodeToDavixCodeEiRKSsS1_PPNS_10DavixErrorE _ZN5Davix15httpcodeIsValidEi _ZN5Davix4HookINS_17HookReceiveHeaderEE7getTypeEPS2_ _ZN5Davix4HookINS_19HookRequestPostExecEE7getTypeEPS2_ _ZN5Davix4HookINS_18HookRequestPreExecEE7getTypeEPS2_ _ZN5Davix4HookINS_14HookSendHeaderEE7getTypeEPS2_ _ZlsRSoRKN5Davix3UriE davix-R_0_5_0/dist/abi/abi_dumps/000077500000000000000000000000001257152637300167265ustar00rootroot00000000000000davix-R_0_5_0/dist/abi/abi_dumps/davix_0.2.8-gcc48-x86_64-linux-gnu.abi.tar.gz000066400000000000000000004560011257152637300262430ustar00rootroot00000000000000S]mo8+ \8ɇ=lO ;Hz%D4"eųGRٱdf;qzX|*F/L`*2%_?˕?;W^{y~å׽_M+WgDΆ?~˻ǻ?޳??|n>4xdO_~޻}_?~~Xd?z~ow4]"rY'tۿ"+inRY*xxywy8;WmoG6q2f/O˗?Іowmz m #:%4;Z毵wxnǏwOw6,?~}j w{+>>~roA~$xsK~VT'>&$bx>$Qbr wqL:+/὞Ȳ$c>bd.S';ZJZ!tUE&?RdO.YRr~O;{ǻєB/O|HAk<՜ "mAKd:@<5['SǷ㽎L3>GBܖW:=[Eiu;Qu\TIH3HjX6emӻ{ <~\Ǒz6Ԯ[,M?i%v.H,@{H%nT!T򶮌$!-Zf&Nhz= uΌJ=;+#03aA=Q XRG1ot4*>RrdɝE"Pk.#gn_$e0o'K]j$Ú - Q] ;1مp#ݺo1W57~2Dt Zt0׹YnD{ { &ZlʳʯZDJqƲ> 1VP #qC2@wBlap OX+rUڦWMpc&y Z -.F8u]>=y- @(-`%-`YljlȕhIKQ6UM)U/3dݵTgYt[1GZX.z0 .T^ˢ+jgo7RjptZMjꯧ#7XިO#4_I=^ʣaG.\z]Koy]JW//d7EfTq+ w߀-aC_ qi:o ;gdΓ1Ĵ $bOkfՋpo~5|kpcZR,7sa}Ք֑CǔH>Q/nEBvm$^A I6>ک:WH[>ڑ:1tZFۇ $)vc,TGФN,*8̒ emnM"_t"-7'(emIPл$v@F1E_óϓdM Ѻx g\7siNAV)ym>VXↇՒ7<,@}Hl!rusu.vxXAmx{X.ԃ<> ú9[=,V =a<>r}"[VVSyXúv sO[=,IJ= q!͞mȁaϞ ɷY 0c~˰K8cCoK|klm&/gCpy.,Y${S dd{'b׏Y9xmF{gFr%N0tI!X.^,!bomLN҇lNSQv[a F#ڗ@[<'NMacWE8ԩ@qIvsߗ?R E:0ΑV$ Vi KX@9m t|[(&)c#aN9dT>f4kxFmyRɵP%-㿈?f:^*$BxŞHJ^%ɥ󗐀іK&pp 8a h ,* )y L*<ѹwAtJ]'jArZЄ 0Ɍ1Fskbq mxd7qr͌MfFq[YO( Q^Xs`R4BoQ-2- e3e5~2Lb BTp U`}t0D:_eMGѦɁN^%HܱY6NV[>uO͵qڽ5auY/ߣ9x&ʝM +LT,DV|a =PApwhm+[SqH)|Y*6DIs@[dxP,S m g"ɀ,2eOKH bwt-M! X0 KrbO,Cܐf;60%,_ M5_~6B _e>a0cT~!1H@81a"DH#ٍ2,âZY%- 9lh޲MsIHI"L m'BrLsCUjLU~uܰ+XĊ5S e W HU/~x8Q+\Գ@,J(eeHw?N !e y8stya [ iNjmu`Ic e<3A@9\l(%Zp*Y'jC/0WT*0T[j Y&`̐ף0R 20rt\N͆ve*pu|(Sv'rxɡN̂ EdDh]m*{ᤄ5 Rm&Z8J0$M7,Js[5SZwjm p4+;k-Ik|,e64BZ~քM0\`a\ N`U _d0 шk12 X԰ !S)T lvF6>IsX57,bN) l4N!#`-lH\hd,>| tlXdZ1A#{ugF9 _ѨdIyõtW3&1rXbd/J8XFV"F ޸S8p*$Υ*&y(gm;-x[*8n^m\!-jQO&B0MR(~Uyx/ld KI`OQa&h}|  ' )q /!ީ`w+`JlF9p&0kZ -цԡF`gJ%=8"2 D pI$*Q4Ó˄9$v;]JDtQ"e, h@ؕX^f,|I(44C0gZ'1&#1zdT Ek4'"㉒1RLa=0"Rjl9f*NFN]7 [3G)\s\\޻FtM#g-ۖ5^eE?krE}{ Pmy\̦ȧ{llJAS#RMۍn3S,8b"(#FMGo1PSc9B_ <|v zpJ!$VX<|;,ב!Jh'&APs$c A>ڀGjuƋ;Z\[p)"+e}dǙ hG^&2]%eΗtlL\Y,D.s=RG>&X3G 2ә:*Yw mtWbkAE6pS$(Kq\k ,*ܽkw%s:Y|6n:tGrgE6oMY_(lK *sVBP(^*t׻Ih( :Gm_mQ*>qGX V%r}'^Ge6s{!q/}`:%v/8 V`6P&z!mZa[rxHm kȈèyd]ktJRxN r3{Tj\eS?ã#9FI _JyTHP-lU  e+ZxvFz^BeCmˣ*:Rly.hsJ`큚om2]38K%qDӯA.2֬FW(<˶yT:Xtr oq(!V+ZP֋QTyVL+E? cFל$۴BNua HKdUVԂ>}ڶ>f@T\i[{#5R"|6K:XڃUV,dД5nF=|t2Z4ס^ѵ*р) qR)k[dBtV! H׃_é|Ec(DnpT :jZ!dHT!OBh]%գ٤N\$T@^ȅ €ݜPр,Ek"YK8u< =,jJ[_2#3'5_uZ&^d~79ݬiK_ǁm#)/-1)ޭ!rN}H]pz.fY#n(^"Q(s6p3'E]&팶 ]uz͐^V}Q&!)`FG6%zWxZ, ,-I֔pj M!N4y%lJ! 5Ҙ(xd1U1ƋjE*l&. X ~vE^_:G}Qsq0ϥL琾 ڭwtN w wX}hO]gɒʵm \#XHBxAZxJJDPn*ݎ?+"o59v|6UЫXaQ1(]?qEQw<4=3盦Ls;-wfnP$c[RNIbQU 礕sȀ $s,*J-r,v@RaN͞fҶ,n1N80:,Kp焛\@fNx.Ǣ9ժ2TH"QAZHB(j/HsJ82+PP~p`tgM%?ULDj+qX G9TZs,f!UO&zjGEjKRh,OQ?'ݠݴPj`TfO|AT-?|+!ߨo$[ 0|qƓ}yd%{zYGXX9RXXAQHI`)(xd+BH@~^<*w"TK7S$ѝ+LAJ8by^Cǜt^N4kWXTAs9ʪB2hdXIA$,պvNlE,܊N:WCM)FEvAlo>)N: ܚxw]ωOHx*wF&"&XFguD]yMhnA_VcD9Q-A:TH/X00]Xnj/"YĂ'ZE˵zbpBj>tܘ{B~qK/G Dqh1 =m:B+5U06d'@JU}otz"]om 0z)K4Du\.'@ xXHP%$_PR`T]HVJ(aF[p"tޞr@ ڨ4J4RܧE#.LtS]P9rD=IrRXBBϣHYE 岗TG>BS*#G7*tXh9֊K-٠4eR>:fi% UHBIeJDZ)) 16&Ӯ&!Uya@77, <^J JRn#0qNTRELT[(\E"Rb7k$$vLBgAMa(XCo)e$.y j AGhQfW5t1 s}.=H9W0i%t49|tO*T5# {cPF0\BqJ:[Hb9)JG)!]y2F~s2IIvAXAxF.Q/iY:E*Q|(ǖ2&FI)q8<5T`ptiEFY=ZÑ+%p/w4&ek)r..pFXtH,QynS~-]Ow2"sAb3EӋA݀RN9٘ls[T(k+XT+2As̟z!ע!coQ]~@w|6K$@#*$,bNdh~.mEvRwLE?yÉ6hU1!^Jjͨ Q=W ZW 0fV[cqC+*֬HߢR`][zN"%Y c$A-EL(.#|wٛq&J\S2غ VD)qdYy)Erv*Ę.|Z@ZnAGܟR;_,%Qu!QƤ{;1$#jв]iR]WWgzH(ڵB''-ӏ/p+Oܑ<]اh+Цz #/H,*bU@Ցr,HX^Ri-cw;EK"#LخK&MRUH8S W<+j fhF&Y:qTGΝWvm[ѹAF.U? EEf^Q`T,@\A)_b)_s%R~6d JF^dJ4覒,#20/#2@/#2(#2 ()L6Ұ*#2P(#2H!# 2҅4#]I3ҥ4#]K34#]M34]O_i+R874`Tfu.JbwqYDR(h`D㒊C=9K]B,3MY5"˅%tn)ҋ. ݆GV1K? `#(sR' *_Q9!{QCQ̡{#+uY(oy.^]!z/B"FH"8BY ~4]OPj02tT= G򈟑(/ iAfhn}_DrV.m!UI&oɅ(xj;u*DJHILT qn*Fu_ȗJ+AUŢ5/;ҁQ(g^,вQM #E#{nZT 5$.g)AϥcrT6*%QuUHyL\G ,4 |7ØJe/K &&N6#_.پAcQ}z̏[hX7WxDh;j6ֈG70*GEI,"4O!BQi=tu7ϡZ.@%L@$VdIG2ƣNUS&}$s)$ւ,f&:`Xjߛd~޺nYJ:{Nm!$dK9?=Ϊarmp`8'cPϣET{X\' _ IV )ĢF$lz̳qZ8x!H%TPD Qc~m`9`2p&<lnwq1h &!mKՓwM|m6+R@+,.Bb5q(QU.߄Z@iMEDV`^HTF`粢qj`ض;`(Ȋ/\oxw ɮDVCRhE͡#K=TKQ !Tf[ ҽCc?2!\U^HtqI UFԓ*lBJ%-`)AIg HSUb("zYm@G,* U?f:HR.~o8irQ?>lBjakpN=kAGi, ^KȈjO"\7]8|nȆr D'CM| **pQ(PE1UBji'REBOEn-E:8@# m.[9]>b7d2xp!W9+3ԏ> vTN],8!#׊2Bv0|3J. "Pe/ /K6 `lЁ%aQU6;7zxEU}C   И]قi̕ ? 8'뜙cQStm7}cdEֵ[bD)3 +x&-h*$ӨF'[#{*0|K.#+ +* Xs2.C gIՍз܀.$!%]t +%lNjqsARJ5ZR p>x Pw tBils$U')ΖjydK,UMޛ/t[m5];#pS:%1|ؤp$‹+-&NbNnK8ʅ;& xvE6WgH9>it*B)x(/v)444~c$;ON5(:KNlZ!iJ =JUĂ?mM#8)${ABr>+.-L'̨69"TpCD_y~0 oF#C(~)eTB*~l.!ќpAױp7N"E(>gd'w.DJ2ǚW̥éca |G'6rJ_+'JT %bIЊTEto]GUQ"Lѵ&|>YUĒ&LV:PƊ,ȫr(h w{- h)XpK$T< ˣk4:h+:ٜv`mbiۻǁtt=DU2:Bضɶg%;H£$U˚+H\R, 0:㠜"%Cz:n[l褛d1);=$%V@ԫK@JJPHDw7TΫhg^uxr@⑆ .̍Iwypj|PRm5\.ݍWG7%aБt/,3Teuuh[2F8)cҺnLW<<`T6BV Qh G$BjSHzmH,A鎕%j`?GDR{M5SVwtcy0 ȿJSg mG7cUCjC*f*!r*ҒC^H~}c+L2u"6KT$m^+ڠ2kFѶ'*nj%,zXtM 0^bP-T)$[2:I9uߵ`r%KE' n:b;Ψ0Kģċ ՑAm(nF)hb]tRDf&'ֲEQh}>UӶ,Z쮅GЁ>j.UˎĞ{!ѳ +DV3, GBÑ]Oln" H{$8f"!}~<$ <΍EUOU:"($D짏vr8PB ZHdWwb 25sv Εh,$T`2`4IFdJNbUNpdґiF:f3ʸ2NU(o+(L5]W&jKN2ˣ2U1#,Գ_!JRABmFE7)@AѝX4)+O6%Ҫ𙑓%TnQi_**F' Sopf)aTAe)4T M 7i#Litp+·WigCFVg*R/?1Y[ $<"蜰b5'p-`AunE"|2+RSjЊIR[YіEHV'+}YT4B;CAt t4c<сQY*f6]wEwq=$-Hlh2%]5T`AךFXL6hd@֥Bb62}-]# F3 Q*zH0n! C)YE#"d>r,B:|h8:'ɑc'GF)(uF|{h,¸GF+lna5fF'$$bSn HK$:"(,*(>]v lG!pE50&*Ʋ0v+Hy̩F&bRCP&_nkW'fm(#Vq N WtcNWQW<&U'Z,iuBuߥChl}Atxj/JK1xiC  ǃ(Vhs/ʲj85T_IGx&:?bCb bb<:0Xߦ5%*)JT ߈EIA?dsuNE.}|7҄f#>_B4 RYƒ 0@', PS$Y$WGgTP!+ 3Ǩ$!G YOW4YPG443K,(Ƀ-, I]swXMm @Z4<}4af ]vƶ;tX8 :*yh46hL56f@?syx)@@)yTn>J5 ˯Qab4 XQ??R66qCNxu$rk%L -ؓ@ۓ0`O„= =I|b4i@F4Q6,pmPރ`:T?Cϧ@> FJa{ !mkF0B%lvVbё bϭKXRB]v*GbT39p:=ClƟfs T}R%!H Ŷ |5[P,%i\B Eh9_8^ǖÝm8=O#^CC,^ac_humvryCe4  6 x9LFMТӤoE:\<# :*x)'rC2e >9}e@hJ6@f"T'ab 4w :& Ht\x, >G*h.وؠQ w 4NdiTQ6M1,@yإ[՘ WF|7qW,m 0>2JCD Bm @N=CL[#s?&FYc¢3s9so6~Ȋ֍mdO[yǻ:{ s`@*g Wҧ?>L'wg]r+j^U_pF|vuCӔn B5 iv)q%y3O~|G񣚍kUty." ]H8Lv{x[+<;]3{;GN$ʘ[꩟_)GF?[Ap>)C(c.(,}g颜oEl,6c)Թ8N+>F9z%r)^3K \9`.ΙFK OQ%x\q<ךQWil%X砢t$+YRB؊ B]UtE0p ֫`H X6^X@ӟ_!e.B/gkAEfo+5; T@2_ʑbUJ 5 T*6,)t; 2 |c@\㺈V#F^[) 8*^SIJ)q?14gGek`z(L@] {Qb(-rTD\ *J ,H -6BXLZOV|K(0#iJV dJ ԐzؑWYĬP:%:(h4'?Q}` ~a,xrW$vwp\^9oq9e_pRL3ʈ @vtL [. 4`)H׎[_k'V*-}s>eRpasj2  Z?ؤ;>b.\?"1؜q^6mU3KhC#pɍж0_8iP 4B\D0Ғ!:@-5G-} ˗M| D`̌4}@<*A/OsVSVYЇ⢘YǘWUv nzsʂ T"OxbYn3 ~(chr< ?<~MSD,EJ{[Y^YP{_wqgCX_oR$}#psDL$,q=ۢ^Q7e!9p@3Ƈra0d['*=Yye|/㎧oQo!_(Z_t}8uS=G;dк~$oBlɲ3$_ܠ&yhLs6KO}$}ܝ%~ ( !D$ D=ހyjj\:[P@-hoAKX |ع'xNӓL.N"6IO?F~y>X"GNaǥJg@JpBZZV8|9CLchq9@EzD7,^Sz`"g Տ&@IZ/9/3l[#E#rFK[}~j1Qa--nw.t=LtSw]mYcfՉ8 ݲ W >w.}$^F7p敖'C8ѯ3pGKUZ|f`'9 BZ6LFŒ5(݄mXڲ\z ;jO*leUMҞ`z` =o%`]%=rK3CHF2SXjtGfy l%pi. c9a8G Lޅݻ0W ^al+Lm{m/Q:YJ7_ss-s0%2諒)_,ِ` `6gtJ(:t!y4ճYnRhV48Ӑr8Յ7A*F#K'pS8hpcm})sjf>o9[F r&eAqM 2A qPBзS{ct(M*=&(S>xY P&hL (QP$~AjE;^COgY ӫ[;( `DGe -#b9vG$# LDG$ Hn`#_ 0#6dЏI`|+*Q!{Q Z2a3ͱ#>z3q*ݲ&%zz8C _ܠ}&c]9 ^Y2i%2bP-5,`h 09p۷I`™o_WG@sx3`܄<}k-8@~!M܆!VRo &͊QE vįEIVAM% NK+Qy)bP94$[^&ϫBn 5x1Zܲ9[:bק '@$З֣;櫤(U 4~4^rt^㸼s\H5M@CPl&_  :X9-2"Ӯކ/_1lxeN TuV;n 34M=v^=zoZ}`#ς&0@F93#.*"x 'wUsua0>q_e(pD=OޑEDIy b^:1.SBHrN3*f/xtaܣeD~\̽OMB Y@xH]/qzyt7yFO(O<>~6e%J̙:Gc&f@/B lQvX3nV7@NMbr`(6Uw0lu }r|8m7ZW5L:ިK'9U+7X6Έ UH | ;$_۰T`xYps᱆%c;EhP-:hˤ7+߳Wmd):fKgFU-pHuL`lr-4Ds-Ѧ `dtڊ .lvZwC{XkpeQ-``7t1_ S2/Mr7Z@[V phUT-Z#vԋ}UgU|a &v]%< W$ h_ ߧhOp&?=I?%P_JʟiDS5Gy , Ox? SG<OC$`AS3z1uyv0E~LC8AmLؠi5,)TO[,(jr[1 \7߀tfA 3Ԙ[" 遘{Sry&*SS'K4E"f" Y95SpNhƟ+btp|<Mt4}hNQp@UcFA&Nx_?(?f^h @ڥ5( *w9ZA@N`b t(Bu"@ÅJݺ oIRgQeh ޶O^ ZW} $”JswY .~WIT'?s;t'A&c4\RC i~6%.bk|@ѧ"^ 5?yPt#2\P4] |~=)N 6 8d|71Goѻ䏊mڂԔTGKhXQ2മbB6#4f~4-hAc`1W_7çأfq© `C JA_!UEQ "rݠsOk4%M cwf ##t<*:}*P̈` Oj4i"D3f%W?5<~&h7Ju.2u-^mKmQmWG㫠iLirUo:`9W&BJ$`p,E TH8Sw`%o᷁}fR"F%:8ytP=:\ǂ `.! qDɣfR t68K.Ov" ruo ~t`p:7ح/Y[ ȥ@gLhݼHF5|`^$ǭfONVI}infr2%vS% 6(.iЮPhh6L8PXYo3,,v!l@B n}Qecnk\#WM3F dZX+ؽvT-V၇e[A#]XC\1PF: s@ S  L,:)yՅNa;l0a TREbi5(r?%3PGP*# 17 Ʉs*2o@oa:WiZCёæMS 6MWTUMҾN >);j*p؄U Gp糫 2@$.dlZLvH诀QlPx7(Xڤ@ؠPa hWM W` ؖH.Q1ERhUpD 28 hW?!#Ge)|(x`|U#^N+h,@b#}8x` EӗQl(Ð8#Eq#j}@| 3VW8l0fiQАeEC<lCp!Mvf En^?&,}|滀r؍ ; #T2'52dR 좸{HL:½` !ҍ( ㎿GGU==1}RK^+J{?_OSUJVZG7p}4 m~TZTC'o[Cǎl~ H/ΉOs;6:#6s_1`ωs94K\s9* Rc^ n?X^h \cc EwO&l:rF!v"O_ ՅjiN^4 vy:#h\gZmP":02 \ƥ%_g٠vy,W$ -j)UGCϕȐ E}D'uYkL_SBGTďR?~UpS0rѠ~JAb{p4Y-navEn xZo+kV}RWfk ɟSa]gG\i`X :nqٱTOt|?Mu\`H@9'4`ՠ8CMVyv?M\wMƻA@V*> *ࠉ__>}{8%o2T044 Rha*ȖУYP:,X%Í]L 4d(y$#jnAtc4}F ȇl|C$ [>ɆrX(5.PYcM/ϐB nP:}=Xv:P5}|"^@h|zp+_G-l&GM* %{1-JE%JC8۬36A覴53ߠsa\mj !jZy,Q"7a" &3;MD2k^1b+ AVx[p= FȄ4zwuMŐK0W:n0Z㤏=؞Xb'DF<}uuv"1H01U|bFEV,8KcD"%OHI_a5ݐB/[~M2] NӷŮs` <,PA/p%NƅffsƠ3:"E@G .|0<$nx_FYFLl/_Q`}O'wFp]%C}_[,}!v07F@:aӀ:iY`鋞ڿnN\&F,:V KW6syJ]/qSqjW`!Ԃ2VL0w}ʱOl-dpSb%6@b}vՑ㖋T@3 mo4<} &w[lzbj>~4-:B+[tzŌrנ%|&Ckacdrtc@wd #Z'klw"A (i 39+rlpϙ-×E;GiRկU5z~$#_=$Q,YGQOAȟ~z+˾Rݬr@4xB[bt^ k [=@~Es&XÍub3)t6;*B!ᵫxO$oHAv Z:8r|D \aF"#a4QfnJ|#fCbd6<ప>0Cfm`VI @' yhи(6KБU `L r6P4Rpx7h[7БaA5ac- .P+9 Ѷؘ Ϊ,Ȭ J|t/$VB%",u`YtLk uX#?ppKb&ŧ<l 6 xh|]5q,l>x3`$ǧbk<Lc xď68K9czҊt;p+;-=un2T2uVq98@O+/|HA|v I!j ۄӧ2ۭ&Gy+jD*D/a mS636{]Z _]wنмv y\˜oac%IP"z } 0ji4IUw0h"Id/ڷIaVGHF(zP4Y-M];Vb!)bvHfB:fԪ E040` 6Ku}.aCbad `2ǽĥ7. Z?݃;~^ gޢr:w' P_09 <|k ,=$hfO8lQGP@50U9&az*pJ*@O?FvY;7V3Å]&2j2?1;"ӠFBHvC-s;t c݃Kp@Od:$^ en崅DN Y`=5%Q* C7vEPjŒ"2X//L~d9jr V~b=~r@[pr oP͔( n KTwOO%n,6/_]),Ǐem/H@VUfk߸EWU?0ՏS'52_ QaroMSTcDg>O!B3s (39W5b爡c *(+I:;1 ~왍kɈ(`npRÀC"o0 daa@=%0Fσ+$V [p -bĹ-ZgI*:<>گ#}!{>Rk ~4l3)>[ZbɨF)ti;NW/CB=:%O(x,FUtƉJrDMo^J7ϤTRPnq~ϻ0m#Pl\ 01/\ LC,] ϱ*2!y&&N mg;\@K˹ж`-ٛ9P!+(}W!? LJ/ İ `l3>Oĭs>L*< =*1A#!cQB`4,1Aw~C?C$&h2d0H×tG ҰBhXfB9 h03̀}>Asfucn9z'"Jm~7dD;G)<Gh|-f yӽµ=kgFF x1 n[,^tOGa3i"a0O((-9F$,!<"A>TUYPsLRMz=7d \G_ 1?VCOL+Jb wDFSvwcrw7}]y躶ѵ㐸v\0v8@ #! @:.|gQ3sJLJ/ڢaoI# KD%U sz`ikr eK,@oAx`92Lb~ooek dhQjaj,kTSP<0 $@%KDS|ɾW;\Q] Fv%Jڕ ϼ'] {oŏR9P-$@' &uӇ>uHExDo`auTIFv*vĢ<$:WDɭ)4*_S\`CO{IZRA;@c{aJA!((|jMs[p-KKF5$CnʦMU0jXnXgX) Q_9ѯFN %!8}Ӭ 8yrdVƝİ#qelzKhoFEyF=7"'SM-$e8 S$Yk zR_hkG8g` dԐVN@]R! /T`˕ Ջ;ac'U@!Wy $ aKp]EiYH9Yr"NJ=SBe-/ńv%>_3@@z˂x[^ZĉC%oTG>[ sN=G<"k2>rU; _8 E{,pyVMϤD}DਐQv8$VNƅzh7=m$]fӹg jr@%*XD9p$56nlGֈ\!R^x7HsLOHWHÑ-@B5| 0[_q;*6&LeD[|P\%paR$>U0_uabrԑ1`O*+ s7Xny`2eN}K*AL]1Tm[UѡY, 3DGϓZ+&RkT0Qa4+ p[+<€`$`> Xj<@ׅ9ЛS/rtGuP-9y&s8uyQ k0[lz @p `߂3~n/M!?kO.$ҥ"6bO̓+n u$\𤑤V짯#Occ\3΅r9Az؅O}EHc=`KTT!,ֈ$Q:=`;Py C ^~6LhDmL74ỳ)@ |.Aj'?>Vh@6 ˩X nI6*V!7pYssrkrxTlJBR>cUԟQQEAZAcy8^np4_ľ1C<󡎾vi 2wBϵ,1`f/-7h̘N(L:~ gQB#z ,M ](PK`EHȥni"} uGZiaׄO {o K < S6H@u}v{e!61Igѯv p${9S M\:BK v} 2=aJUd%K+;~4&<1= Y`}9>Hx :-`[Ɩ5 3`iKl;XZ :hPИdot7w%vkiwScR.5͸ʰ `CdDk[=*x6Zwq9Ґw@]PR#ҫ0WiGXMG* Q{U*̝zx+7c@6S98ȡA>Nrus|ŴeAhQ hh.^NK t`]e7\>HIy{fn" wϠ4xh }.*'jeV 7n ]q+oڬUM4Ѐ̀0s}{bzv ]ˀ/F$x ɅBm ߉@]Pʴ~f0369],A"]$;P1ٖJɌڣȑE(+P~HqBIsTLaB0J-ϝr R҆axԸÕʘa>` pTMZ-,[ IR)X^ ᱳ+M[rD]xX \+if3EwIx459۳sʒ3ezPQ^}E2Ʀ|hf #@:Edhh~a,x5\S0˜- Ze3&)Qc#,VJ7AmK+ι<W|.H8{ʷ:0XCM#ʴ*n>z}4{J>}~} M_N>~y2NݍțpY"/nRjy2Rf7g]黾jl[Ɩ N1N('նBYu%4}W:"!/;*х@2:е (Uhz??=ȁ|?>~ݡԃǕEfkGɭ& t wX|(~|F8-<$ݧo(,_1= @D|5؞~BA:?G))xjcck%Y #d\<#oyM&!*M?MAZѝݏ&/{'>=~ߏGSv q0'Zn&nL! yUO3{zČ?t3D* 8;cNA݉cÀ9)ӏOrmAbt)M0C=L'Pt4Ut>}?M,*ɬWx:1h2$62n`yyYm؏Q76a~d u=w"cz >9E{pсctu;~pTD,[\%1~A?(y 2i]>g?«Gi= '¶"&S}>yhIA@TUO` &G+*C1e>}3"J+1 a 308ǯr3Sou$' &(Mem2œ`œO~ C LqW.Xa\XA02_Ç lDIA_`4G{OHxu xo( %/swah2?13QYA?>0s s>7裍& CT2OGQNkO9(`Oҧ>"|*2dD}O8sRvW 9UAti%xN<ކ`+` & i-`4T2 0O)yFN*%> Ocl/ȈjXDy*LK>Fh|486#) 29.L- D*D4:6yi$@ht4ɏ1Mo?.m 9d3H_ d?ݍQz/ zHqoAx480SG9̹t F@ԫ <:XEFNTX[&jQB\ "-52n 1dB8ǥks{x?s68 帾"nVP_6qy~]울gC \WW YU8nĺZW՜;}4UIR#z,{pg6wmlcd9U@{mJtKs k@Իok}.-8w_Iݷ \ j!JtP->α+,ztLs\q)-}s=oW4SwN m6 S iz\O##z8Jp p;ymaԦS:6L ^ \oK@\F4+!*z5|BkWoW5+Pz|Ls=MiA h24U1*z|H \oM\4ۢC1^k[|ps-g.۸oˀh@G4S ٮրJ>USR#QDB6oCy 5yӼQi޸B4opQ8Y>_< ؼq{l vwlƂyռad>bLKXycռqc/ռ S0ּ yciiּQᣚ7*lL ycpl޸ŧX"c77nɛ7n7VA ׼pY捻(G{6o, 7nA;/L*2r"]X 8yctiX"~Cu ~H; sF@ |SThn ^Z!RyKp'6<ʬDǜ^ n xL0C< Db%אkK>*܄S_1ObmE/- ,3'|¡ |"eg;WSn`#:᱕15h# nUbc%:n{!^ 1n ˢx*$&-@%`"N]rWchzsSByIsLyE)ut)A7XbV6O|"aWқ?<&sw:.|YQy7E˻5щnM}+Qmsg f7pb?L,%-[uSb~ցQx_FB<9m '_?]~k½Oഒ>?QݗoC"oVHFv箭K+/OK-rOo 0"I%Հ,ϒefmJ<TY3r! JX]tBsd~]EssϔX+buUXz dbSaDfEvL 'l[1-{I$^,f&KN&*(?JL[V{37h;:kgpu$bB7 X80 5,?#LyG`t9 F(# (0$;PXT' d@e> h*չ¢; }~E˕*Q峣0CIWɗrH49 E3 hd 8@x`;3Ƣ㾀NxB Fw(,CaI )5+`Jx:Jo[.p;a-3}&7J1 &BsDan!QC엹5Ђ%5m vIkJ9+p䢦[4RA*n,`B,XNphqLJKhEAѠ /$ b- H+\ lfy8 N q[Tnw iE%\p}iZ+yDT3l#@߁ah@a"F*0%X l:FKrЭ \L, ic,:C2DS:,ȀrRS ;+R *\1h$~ 8B(q> 9 P2f9ڡkH˜.ˀ ?u^&M8EƹI@}z U" (8tQ b &9.h\3 >W bIOB*XH) ;@EZ߀~B*L4Ȕ`٪K Xqq4q8J3:3VHI+BMJ:BѕJ~}A^,~]#T04yX%O0?}IUZU8>==ҽJ;;T( ME"1Nlu+с  5Ӽ5 *˥i貜MGKXVPH`c7wMo@#?ADVl0`ڤnsAQ+&ThVLЪ- .*=Pp@ЄEm\^ً $j 2T!M *0a2X 2D1u{ rL%Cۥ԰ Bg_4P8R/$0~7$R%ftN~d:(J(Kk 4 !Sֈ x]߰D?8P:uI!UܣP"0Y# ?OޚJB]qB&,W6)\| V~^+&*s]H:aN y#3J/Qq؊EQ$Ld@eqDdtl@?eZAf&RŤO A)g Ȩ%8؎ZuP =yuE-R 8[/K0A #K@.R@J{/.‚hW"6onM‚67Iby `$݃#'j+:DF Ivl]`ɳVlG { 0P5US )Tje:(nrs %4yAD B-Dt7~( b7@*q9$]Hh A<%sk\e #7 T!!Uup[-ͩBD&MT'rb^BUDU;N;T! \"]ܣڗj,R3xK9+cV+7v91H[N+ZH8P拮# `UZ8@ `J5 [U$c,,GX}kɤ>d|7Tyi/"ǜSS>ϭ@; y3~avSƋ%K(vWʷ5#Krz9j$)8QW6hۘScÌ5&pFIƒ? _\^I('ژfs,<,<ŹUB,A UCTqMWigcc]CfS f9WYDa3)#]g AvfD(4An`rӭCOʦ0&OW(D˘%Pn2BabPESFp>> \G{BrxďDbm3<4q S K)[}O@B@n0]E(Reu"n\] ; HUiQ@OuY,j{gOXyLVb’* &`@UisUpǁ 9qWcyvd3 2V:,ۖ1*eS qx*v"JP&EClbQEQ5 ^դ |Gؖ2mȊjwt H= V8`:m!b 0۱ 2M'|P=Y?4ܐe͓@# HdKǀs8E0MK/M HJo"jLnZKj+qggPE2`] $ Cy@ĥ.UF9v 0׎77*r#7 |0KiF--r?R%`Y<ϝVn9Rnm͠+ U$CG1/38dff1_!ҎUSD6ⰨMvOr 9?Yf#S `~MYJJJ"g Vf.W.V/U dK@r];`8d*I^p#q?%} =71C JhpDh}.]. B߂۪CyCyɦdJC%:s<840h䲠K.g'-n\ a x.S*J |SS!X1C0V1Iz3tA>8#o$y+e0}4"3Wk+x1Z|6Zq_w:i!1+90ˆתYBj&#^ܨVx6ZD%Θ^[9mv(>O>1!jw)^5iB Vo\{X 5]^^\3{`Î"HY}sE"p⚋egxropZYh"iWi?ye:* $9#T=u \q*X0V&ݚJ`%e/,<>zzW;Wh֛J؋nKE}XCAm/Ɇ2o-^pS7Գ>\G(˵\ˠ˜^=2u :}bbrEt_ xԃ@MH\UyܓDp;>mt|RHʖ`Ie-ڪOץ2# COYSh` z՘KߋE.z aK+XpfL[؞&CnbM.òGsν0;i^+NF(U}=/|>8ҡǍ# NF(ir1?ՊdtR߄+ឆ@*[w2SD`tƏDDHyN$$!I֔$/>hM6i a5#PD'6Dmo|&R?A$`xԕYx컁r:Yc-UF3IK.ӪZNd)۳\ͼ~~4]/}C~F{;O_VOQo2oR qZ}[p_zmh/FѩY ¾S_QuuܖI+@KF%%{<9d{^bpdfT!k:c/n:%5''WIuR@3ϵ'N -Q@fߔr[OX +I[:uEy0ZԡJ"v7B_ (uTXIMThF{D^m"7@ 6bgK3`7dJCiS+6 a[I}.#%9)7iE#I5RAc{e8f)JqZrьu^ʒҏy\"zzS\f2d"cj~@ż*?"&Y1Uk%8IuX7K&?~EO-\f߫W Lfq_"@a Z ùMv䯄+7Cnx&qAtlw!R["ѿ}Dch5OЌx{p9i-=xK[漜&U8iː܏ftfs+ fÊ+"|e)PᕯD:Sn RG8=Do5_oNH'ƈZzjMmذܽ<_L{ 3o6NnbڅVdٮ(FiQU>HsvD؂IW3|SuqR 4Om! 0@ι1'GǨu(`w(pz(p~z'ʃ4yWЁy_C4{0j܋]]=D"AŠbGd1'Y ,D~"A?ŠbSd1-Y z,EEC"!gYd},~rY?9EO"'gzYd=,rYo9E["3zYd=,>rY9EO"'gYd,~rYO9E["-gzYdFr-U"|)kuԫ9=$VaVZ0k6ʕ"׏4hu=9oe/jȣ4Q7$ak^m+o6m9fVgtVƈ3>ge|2¾Y/U:3qVYYʚ2AXwVF/\_"!SO˸ jq # 4< =47$V)B,Wt4pQ/~;PL㎯ y&oh>*^ =̈́7MP\Jݕ%OuuASߒB\6.dc&.v6у/lwEle4_/>=c_VQ?yLͧdouSQYzKDZ mC&ga+AhLvzU=AcdbZz ȰqN *3?WC*-k?s!⻩~Zܪ ҃$Rir5҃&'b#øFȹU_,-O|gd{k,vg!©  4W4aa8(ͻ_yLQKjG%;yi*>S B/x3Cx#5OݠT[6(ͭȤX| $r%Q!_2L j; ] 4G&F DU(aq"?e%^F R~۞LP%1ؠ3e+jLJ6$c *~Z*۶D/.0 ҝ'lG4)h){cԽԪE{^ ru2u3*6˯hqr/\ɟ\0MNA cJ5UJĤܑܤܡ69)w O& ̄$IMQLNJϓ:c&L^#T-Uj?`Zh[Pwc,ZCRPN&a6?Rƾei9k0324T4v!^ig6?i[>[Dߺes[I}r*Nd,WdܸPD@_R?y> H7>cg̽JFs~¹|H'6,_(/ e e/ 9eFe~ʼ>U߸~" -ᇈ}B!bB~'" -燈}B+!bТ~'" -퇈 ]ݳ}b]=D (Hf $3tq 5dn@2CK %'S:<(NZO&Ƀ>d8OhQ?<(NZO"E6p*mjOMXpnOUm\NӗxyROO镺u}Z3r[-iiwGh~B>}m$히m퇈䃅Dbn"`Q*|'GQ-gd{ T.$`}>!O]<>Oi>Ou><'b{n>! O8P2.ĭ5pNK|jTpz3c 5*tk>ᴄn3pJ !4@% M ƥAR)|'n Y=SZ yBz'xBN{'xB{'p79<\oxƞb,!Bϵ׃zŁ&lH4{2$8w>J$m%["x^'1o##ւ4^jRUxq̐&U^]뺮O/+"zњNc5UK !b*ͦj&= z:sW=hY_7x IdwUZt6[HM[0Dwp-OLϗ,TX#OMJß(~危pcl"ܚQ'Y'a'y'1IRFGt2>sS)ap̣G 6YͥaȰv_ܓWg8(zT 0? vhBV/I/wb: SrTؿf$˿zJ XSo|P؏LNE9~I7`_ݜTt`>s\t'cGo5쓋htltz2pVt{F4>st|(?atZKӉZ'e/zQm\ڀw^RsF='\`,ϊck=Gs2x- mdAdͤZg[M'#G]X_D+ТS9|aqQ2 v 'L8OS5+ Y9{8m]y[ì'ٚ̃d>df Y|jǐ4pJ0!7R,I";LQdqy(w"Lu{9z:eOO+ӔƁfL#hMR>(Wkksy"cȯaxW.5\]v'=.40lCCПQ8F h62mdxsSf~d|Ӏ >dw-]ĞԂ?70I 8N}[Y@ ÓNF~/__`p"HU@{PIE#-^g6aZi2i1oM/6/OOLGɚň&=orkEkRQ|.)-T,-Ur*],C4+XnݝeR7l,3+}UmoB)eEaUء6ذuÏj6`pq&kv~o;a6lq{V-f!5k<]O f?[|k[%Z͚bm?8RxZazַF}^oQ2Kh<8\C#d':\n!F>܏o;f7vv&w<+ۀ(Xq5Y]>ڤ abܜ&ɮѡRڨa|ZKsZG͓>8.NSgڇimŒ`MJէ7>|b{°f3wlsȇm :^PXM=&Vaɰdj2<դjv5j2u5@gi{/j8U&/42Rv_樢oI27'y$W#2o\v(j\a {&Z|>BYMZ٧h4JQjf1č1͍14c1%Ƙ^1L; 2c@~PU"Q(^H;F|)22G֊Lwf Z :oi=Ut1)ិ, @y.0棺єTab8*Yы-xku:ugCp 8ƛU u&}|}fz܁k\H\L@4"ϔ6瞞!iysz"oZH }W)XKf?c`!%o؞VHK&aɟa +vMCcrb XBML7t]qwňvxeⰺ qC(<$+A^!ǵ,W}BRU 7C㙡мYizMDAk $ BH ,%57!"Q' J>+h`n>OP >KP >GPS TJTB(TB(T0*}IG|OP.[Nb[yɞ 0P=%t L>&ԔXGr' GΔv|Am-_%cP!!zIHYZBS&^f^!ZȧV_ѱba}1GQ]8 _{G޹lwd=L#>ʋ~eLKC2\ؾ2+TY*:bT|e'0&\r"vgW$>res%Cݢc O`Zk&?V rd|#I,CyB>9-4@#1{$7)?1 }*'|f0=cA1R@bz,zqXt S`$zp9|PL @D0czAZG r&#/`M]\Q;O#ެFa ʞЁfV@@ZTCW=<ű$ ɰҬ@%>Ć`G8:!qpw{Zރᾒ2*t#|QG84!J\IW<&z wvy IO=c:h,%vƩoslʤ?sJaImm>h.%\: {(c}!YKw1 ΀X$0\Z6[ҲDK bIYwRElEK8fv7 f[j{x"B]"%B.%}ՠW_5xW ̞)_5W UmW L)_50⫲S^콸*3g⪬׸*{/2mLU*3WeWeU{qUfdLUYqU^\eTF|*3Weи*4p\帚ǜ k4:;׏n<,0DՁr\KKכj]>Qjo ܜL ^+7\vwG G^;Z(el`N^>*`G|{:gf{i#`> CG{ۃ2m3;ެɜmvrmo$}xۄٿzw2m~ydjFnnÎMrۗC)w= PxdvҎw'mrُo_J`t&o+so{03;V޴ 5]s<=ĝod {-:ğy)N6-)ƥ7 ^bͬ_'7yWBO7M_{b1^ׯvo1~ƥ7jfa3T̃3]ĖVd:d;.3;-q8i㝖8i8%κwq<y}=~"2 U;݅UU}F]D@/rE^:N]9LU$|D{ޢIg啻˜7(^sʵnn¢'q~հqB|+\YކW?)?Ү1ޖZ}`$[,34ÃI@[: frQ' W?Bc]4'f ׇݳ464V! b;KOa@=Έ#ysYkl HQԆ?jh13x|!jO 2G/uc*<|Dlc91. oS-ߓԆ?ߊ]ަ -f(@=Έ~%o]N"Q4'fH'ͩ Mbf~g65H4#{:|>E!jeŌ2hAz3fcd6dX;f kfX65&x\8si Id$2&4̔IdL"cEo7K@86"ڱ)XQ<*gKK0a +,Tc:{h1_+iK SH7\7P}9Bzp$@~"Q 1j z!>Wc+uy|!'Zy|Q] C:f/y&5~:Bm>W͘ r_", el9aLb+29W67$Vղ9gfoU[ä~^hTPˀ'xUWW* ^E_-xUWc*z ^U^UWG*^EF "델bVx7bU܇ZoHҽ!*7o@ڷR Iqo8-x Cam!(lXOؗOvCN6P¶PJfgc̙sf>Ɯc1g=Ř>bY1欗sO9'Ɯcz1g=Řb̙sf2Ɯ1gc̙sf:Ɯ1gcL|i1m1Cic=Řv1GicĘv?1Oic=Řvo1m2ƴMƘ6cچcLti1m1c>tǘ!t1bL#tz1~bL'tz1bL1c:&cLh11c:tLǘ11y1&#=Řc^bLO1y?1&)=Ř1111sn>Ɯ1cy1漏sS9#Ɯc{1Ę~by?1漧sS9-Ɯ1&c̹sn8Ɯ1c̹sn:\1c̥sC#\c.1}Ę^be?1沟sO)\c.{1&c̥si4\1c̥si:\1jpfxfǘ}5?bwK0f1f{wؗ1{1y1w4c4c4c!Gg1>b̟Ę?1c'Sgo1O1O1O1O1O1O1O1O1g>ǘ!1bL#z1~bL'z1bL3cz&cLh1=1g:Lǘ7ccL|c}Ę~O1GcĘ~?1Oc=Ř~O1[雌1}1o4 ǘ7ccLt5p7A~WЁo=To?͐o}t ϑo~T;{>R9s{=Ϟ>p@}Ժs,gXQa/QjKDaOQjS=Ea_Qj[EaQj_pRCQjh>J {R԰(U?zy^t^/8}׋^E?zy^t^/z;&za^>za^>Oǘ31c&=ĘI1fSc&}ĘI/1fOc&ĘIO1fSc&&cd11fb8LLǘ31cfc|1b̬3)1>b̬3'1~b̬3)z131ff2̌Ƙ33cfct1_ǘcW1k1k1kO1k1k1k/1k?1k?1k?1kO1kO1ko1dj4|5c1_MǘcW1|6cǘbu1溧sG#\c1Ę~buO1溧s[6cMƘk1p6cMǘk1c+Ͻ0c<~0|]&r!ga% %抄|pƾKvw8>ns 9+\OS6=cf/aC%2+MvCw亖תI](-PJ Fzm(qÀEI<8rck%ݧ1v۹r}_VQ?rW}{?}{~s?_kM͍/%!h:4Bpr[!g|lK+VFأ,Jgp>y/ 8l*qcsLjrAbFMq,#CDb%%ӑuȘ-f }Շ(Q\,FO%EKџḒߕ4BzQϚ i ?O({ڣ R=Z4+>gHB!683)k@|Vqf GHZAk0ke^"l tn:6Y\Io ջپ׽[ 3 =N[Հު*8,O+{ەcN*?=ۛAqwά r)g35̹)Ezs}S96Qkf.O(?mM\[{ [%1sm7s`$o@\^UG̹͹ P=9v\[exls`6*G㧘smdεM9VʜD+&L%ڛB9|k eε0tεM9=}޾Tε17sm6suŞ吗D䨐/T-VʣƔ $<u#RzO=\jd~ȆCrʮ=ao'{zw1T*&d_1'Hq5f'%x`%BdE9qq&ʀAqLm'6T̄%9Pm9O,T+l%T 1p~Ocw1*pWj L3eJe iQZтAmx6Tl>'U/~xa2dJ2ݏkdBYd7MX+}mK^PGmNjh dTl¸]G̙df$aV*S& ˀ]\Y"y]*ؚCÀ;-aD0f}"kTT\_JC6տO(h}0j00{;ƽrr;f>sa<| W֛Ubv.cV :ڹY%,Y+&y-i-\M"`K/'~mveRf^>Ьy|V30o5V30l5V5y_5a_5y_5a_50Va,GLM%KKھA'}Шz7ہi6[}ШٚY63m3XAhlžmff-4}ШmJe^-O1PNO&sndBdyd0lm&sD}L8Tӓ xr2C[(&aDteŮ5,wf`AAڋLy4QjOWʙܕɥ&udLPݓoYˑ> etu &P vzBV, Y[wpH}ap'IdzpPLAIA2}\ t>*|TN$cq OPKxzBG=A>(,(%I`FmD*` 5pKS\_R1i|psx~Ž +N}A $|cX}*&-ZqJ31oeG 1ڑ`Ha/m 5Ä` @apl O! ΀hG3#pOa|0`>P( Ā߯t҅Up.;߸CD=f[T-< drĠkNH.wt ,g*L|ҹEf, cGr.:Y&K& GPkpy3~#U"umQm: *x\r)swrJ jMr\WRd%u[Q&TIn f|%֎ts`]v5Ay \7.687uwx|˹Ќ•E[],*K4+A\g\Tō2-ǫB]݄%,zD4Iufv@U`EصX`IR93gJr:ǁieQH(ǧ1ngaY^4[4xlc{{^ܑɠAfhoi 0icdUQWvx=Cv2UYcuQ؉p=7QQ`1U&+V~v%K`2ٓ>1r'U;2Iv*e&ggXㄅ U$NXtReXtZc=XБҀXi0y4`+>&GKSnr4`+> '4rhiV|*wNhŧrd+)\;9Zœ[I\=<it gAX\ah;03*ܦWnw {b0LHmm7kZ\bc"دۛ>z]o:dp=u/vE]xwݪ+pfU! _0PnCgzYuCUMK\\$5 sK^",GrƉ/]EX2D~GJԫ]tOhp0ZD;7㶊L {ÓRA+;,zNmVi Z-pjyhg&MMeyGS(hUToDS hhM}T?ZIDS=M1ؠh@cG>RŁ?-؎cG6S<^)BEMj qN(xq|*eNj4S) s Nj6S <^)Bu୤%8?`1pD-J1خJPLc?t*%To*e`[|&c8sy->@?URһ_ ,'u,ҊI5vj{Qk(K6[Kxe#>+Dqut.mw+O_V+<$`Wl5vFM;-g޷<(dKbK$I[HZ-+EL3x ~ s6'rY[ٓzg|F+uzμp Mɖ,;GEՂ<߅5kpk=,U]%Y#vuA:`%\ZFnPv: \LPtv '-7%h&u'BF`,M|T&,TKZGMԯ5Nx8?&0}ۮpKKߩrڰk2,{*qo]Dt>(eE74Y6NqtBn M'Ʌ-gl+12,t.ơIDN>Sb 4.^*빐wE_f($AI"\'6ZorElzɞo 'Ũ|oG DyA|T2X^BĢh4mŞgWBܼoufVJ[pk[X[i۟ "C֫ 'Y͎xjṽ?VvǴ_C* JX}\ZFP/fȇ"zḏ-{dהd苅xRXݦS|}fЏ{KAd}k C{aZ_ޏ;xb{~;~<01/M?B<{b6{UB @ A"VĂXO b5A,& VBXG0fA,"5 VX?NKce궀^tzCdp}! RڞwN;g:ΏA_K&Y#7;dxam%<ɐuI" b<̋bؾ~A@2T=֋zXR:a0㭳wX}DQ}1,AR}DQY:GQTEg1_R u"nKf b_FLi\6HiL \ko6cF9d6g `/޴2+"FCq360V5u6yPq<̖T0^!d0ovtΔޅ-cpY]]x:(IC2IT.͛5.<ourcr#b5-x:"\r#b-7x:"\r#b-w:"\rw#b՝-7w:"\xNz֫;A߻w/%W)z-i!``OG|`(W)J@|d%uYaIl t|h%sfi@'#NOQ2Û{m< 9nRF𺛥yTAR$$ӏ= n#ٴ :+GӶPhλ$:d.R/1L{H 츴~]52X3gkk8Қ` ^s ~/C.u\Vv+Vb_f&o/5IZ^(Hn/B0ai/Budcƭ%@ۘvK)McBPDŽ>&1|ɻLh8hdB:P2M%{BE|A q{Ffϑ`_w1!󡇎F|9GzF|xYa}H6ě#FF4B4Bbj^#9s$CFǺP}X "n#k}2(P8Wn#Bm#F(h.r&AZm˓o$R%8L:ٛ4u][a| zUAGBewPC;Z3)4Mo);P:0(UnFoJ`D%#`%|HZ>$-8!3Zx[ZGb^/FsG˂aw`(Ldƈf>XhF3l3l{ 9*dk)DFeN"b%%Π3+ }1'BO%#ʤa5\MW+Q%x s犘c[@A# W~Jw5:KU, -q;4kƣDp;i+7NRC}+XxC <_uukGV#"YxvKgs'ZV0k8pWƀir&RojHj41=5nmL[dF%wF4KWf1!8-8L|"ϑ l-Aȴ-w&E<a`ynf3Z09𵽝PfM[2%\$̒mo_;{o"mmėk.*+`]zV2 E3!gJdzr$<w\J 0X0H䮠#\1 'CsBk!C#SYGsvGV\:bJ>9T6ej/u8^Kˑ?td]I! dHx: R N=r~q-(G:;Z`XGBp=)f-8),&=҈3x)w4}7]?T'7 a/謐_ʄ)ۢ Uiӯ_wM0,UsFr1)=_݌WQ+:jOwhԵ7)0)4] 832^>w3ƝPи<83On2ۇ&COgjŰ+̹.L+v1@}q׻J''̣Y%Q2^&OBAͪB!¾*#!?y]NhJ@_7fwpK:r⹛f1IdQxB:殂G^B;2r"?n'1>rs 2A1[ȌoQ_@8!I 9I-w3-s)0@Wf!b~F U2 ?k}Mb`7&n~qPu|iBS<;_4(ñ+thoE y8^<yԏDۄ6jcԢEF:$'ȶ;CpRYC@pvU_#(K*#e`h`!G.'`T ?6a8u(^YY}ĪL@gCj:~RC'Q,SsyL 8&Z ;Ay6S0 n]I3X?4H#$ =o„gq#I|LƄp5O5f08I)ɑ1e`t$V!o>FW^f|%)`&B"no>pN'g;9Riy [/AGcKwԥYtБ᳤+d!Y?n%L23'?_97?V fFNѰGH 9z.-v{ oħ*8ܔc8&/xgXe5CtE)Fa 8+Kj8^KYќJW=mʒ]$Y1ΐ\J_} s-*ZBq*DoMU qo 2Z$~JAfh3] A+TE}fpTfJ6M֓Pgńӌ"(&fC^A]biM)j6G _\_&8_\>ʌ1+ClC\W݀IcU+Q L%JY@!@}/09N8\ؕpXB=L4Sԣ,ojo0GX ,-^`nF $PZ Bg~'-tuwɫ 9 '(lRfWK2ykW0oj ?c?%Wzr!&ccd 9fC\37 | .,|odf*> 3W2 =Fϐ1lRx; ̦N|#I):t19_>,8́u0d>B&˗9nrNjXҗWGa- BG7AW^3h7BFI[U\ +#o̲ArzbDU̡9NbEmpB# W\y xG-Qq:5'$ y"N2\—=WЁz޹ !GːCh= .PE>}KwF9b_ZîNM^2!)|¶Xj,T.F29gtIV!škcrTc⍹!`BpQ&g(|-*QT.WE􂀔kfdD$a+m}? XZ%PH }84D)!2TKа|%`xJ8p/2.K{" q0e3G?cwy-ҺG #l}6>C#^zT,z4$vwu%,7 & R6mP0Wރ_1`ᯄ`GW0 8HAqMyAUܖ-SIx糊mT3t*WbGT9ÑX5 :1/ĸ)SͬO8ި0y"ї[34w\T ՔDh?_]!5OaOXG]Ρk'Ĉ#sj6s87%] 4\f}TpFD@YKA}gӃR"LW@XUSopUV tL hb膬jt~Cm$~G袏]x,<1Ad`aWw|+pf`9,C&RIC`ob` 5(A,7?:v=1,i06, 4 3!pk@YpM߱Ĝ>7ρN€.x"ýCiCM 8)*9,=2rr 936RFHaqzV_Q=LZ+6r^FOQ3TżacD \t 1r{*քe [dBR֕AyZ.whڄ:'h2S+̙`0gu3tN:,gO7@ow2`S8설w`RH!0lQP2rE"?/i : ZRg1Ifo7. ;M[wWhf}5?p5em3w-°kc(^ϘbPZv( Rh^" A,a?IYB6u>]Acm͹:\B;jA8"PzCFltFu%LPg3[g& g%ĵ"Eٟ Owf ((-b,y:10ܬee(+o\  ` 2HIps"0՟XcfW!k׀sJY.{UISw|F&/)\A;2Z}̨7h[BKP\RtڣH$YHo`S+g$P.?/T@aPn8.CJ I`Qr`vG%  ;g(Kb-_C4#F" < )5xA!1|н=G |$n"qq#=2Ñ;dqF=zcj& %d 1ڋ --V1›$.+cj^+>Z˘|ѥ0 [TL/W?Y.Y#[cmVmnyrw y )zŀm. dMGB3Cr=. 3M>B(zn}،FЫLKL~G*$ h+ giKtBHS1 1X W_)Bٸk;2VwN x,E_` Nΰk;. !_H/xhy"mfKF8WM -@ɑ|n4ȁ *qٽ3ױ;{5MQc\6 $Cs_B)*.u=FpE$g2"=xp }w:>Qh).FU(k7cpJlV q&7κQ*Ýb xV}2!ΆGcد`|*~ az7RV jTjsяP_3tbT1(e]Uo.@1 -@Op-A#-g:ńI7cJPL˗psC Q ޲.5:{ e[j!9w7+4zMPd$YEvqbe(Y#!^Į.m(mʹd 횥`m,j7*Wd*$6Ĝ^-}[R/]HyF3^4x186?[Jhٸ7\PRm #ӫeO&x ]} dgY ј?1S ) TBL̐qrNrl_-NR\, 73'BR2渗hobKmy#b9i%F .ι=3hIaXgngBbNLBx22&{q%/D WqZrh6Mb ԩ-cK@3sj>Og {դixٕgnG5_:TTlY]s%Y6q@yVMn~,sl݇n@ߋ .?dR/+BdBp>?!ǽrd?Z&%bÈEQ eHYQ Zw@7 lEK͢a8h7!>92dԂFz Erz,dqdX(͉r\,u!@owhep]8Jg8fPƂ0T6$lDd 1rK&ۏr~rTD:4PgvES%YJapf|{2ZDFRJmH\ Ꮑ)57M6s(jcVHP+?dۦB.cҰ?Ppe>㑤orq\u{ C=O!z Up4ǑC̫z8I֑G̣_ɔbfe|wdJS;t#$"0|/}EQOonNnףIIRF N4!87\ Z $SB9x%lVaC9vzsE|!k=+BAMЗ(q"˸Q2䧛իPR?"r"X~Oqda/dѻAbb xj7{$Ix;t[ 9=`I4ScE\xSd#\lhSqtܵO(qHN t2? QEG|?XQ {XҖu_Eu_7H-AEy9(.9=xGs#CM2c]OѦz5+8#;g`cB\}Fa׳A;mlS^)hGo 1x&WO{v=R/ 5QJ@"i<`(d̩oA6]$Oi= &1$ffV 0ߖ( "O?zn,k4!m= ĤqCpFM i``a%z$/hτ+0,&y,\W? >s蜂IĹ%GXOT:]R!' cfYUwrXHp$=C,^$m#l0зӆ5![M>"kbX TP?q$pv173ɣ+) ZFCe79Fbн)Đϒ#ѓVÏn5ry [FiC)* GL) ́t9y:Z+|c6Ra,7uGN PnZuAvGD V zLM>3T=7s'sXTb yX-=bBgMZwfIKFN&UBmny ЁQb^Er x_^ǭS#.M)(>5^BMYuUUZ?QJ0C"߸+,LMy*'}t!E晄zp XD++ASQǒS@N^ʁ&< PMĘo\/gstʊe Rw{hC Y(6@JQ45Q+O@jOu)RZ Qգ"b|O=%n%^t +) abuzȔ #|dMB@! }r0zO`%-`HSbn& ?`djLJOޚLM\ąlWb*#G&hK!hy,z] :J?Y/#C5ay#\14z& ]EegS9eB|Gvr&}=$ C**A>g"<X;<?tySG= QYz^=ɋ) 0j.8TG8/7:;8#B5"q9;sH-y8Cr!o_c((]? |_ |_Cd^ H&1CP1Oic߇! ;s/b?J'A>; @)CWP4+yqCwetG$mAe,(X@ ni/nJHȄeE`^ CS{#tQoƟWWQ8_y˨#`'(^qBoasQٛ_b) uSk5(dygK J>}o.Ρ4.pn̫"S Λpn3( fp?XV?$n%Ws@l|^n)c 2.FHGw?}!}X~AQGk3+y(EV(pαZHgX?8CG5瘠L2DZ'ؠ='j {91>dz08]@E<ǧN73et?9)ŀ*i"߫{.p&Zv aB?+·k 1zu}Nv8cI )'5W!YsRÇzt!ԴG_ IKШCo`D\?}_M03 NQ7.o?+a? V\P!gXF]SES] X&OW_E} 꾻(_>݄^no} ^GpCnbUM"껀NtÚ .i&p@A^JLۻ5!)ʓtMпDQ@ܐbpWnr, _Nv%m@\ [9a?V@.q2x) /9#`rWl'\3&g#.Y{:zmh Vi&)w!Q]uq!xzOuZ_}!)jD`Lr!J҆=!_1z[༈"|Y7‡r$Cg(N r/'K7ď:0n*I`i&b^IXpi!$;` !Z:N7xxQGDgAs[!% #gP_DLE3|Xj{I0!ĝ^ :%H@2Q x 2 GiyO a%w q3;74fuwLP F"몣"嶣":"F"y.SLFKS!X\ lXU)H A} 0I7<l4fΓ 3[/y0Ipqw_~L~qw5EeG6IbV}uK~'®2u__ -!U㇏CJ$Y}j+?DٌĿ>7~:,2cNBt !,_ra{7ȿ$?|lGiEG'.=M_{{sƒg}dߦsW_Tol7r}/iS.<:o럱{°@7Kwd9񏉣F ›w@WNIYih<ѝamB`rxP2t۠7pk}^OSgz-8{k('lYrI~5-x:Ո .k&30- V%d_ӱ0 m:F9K$}P]25CV:_Bۚ޳kwco 8z ں1%ͫk=C!6-%Ԧiآ6Kxw'J[A-+hxڲzeU"F/c!Gy!e 'Z٧:!tMfދd-,1ޟoY(L&7'o~_ t4|}oARWPi ZI {bz;1ϷTB<؃Ӵ4ds.|fyLQf[ag{~Kݝsk9'q MqgSM&}mP0љM2Ӆư65]l"=WEhַmNn}G?7᪣Ǜ= h ]<ughbWdQҥTh`uc_EBeXW!*b),+h~%퐟}?ڙ٨[Ӌߤz[Wz{5/B6r dw)b^@iKi(צ2ha [4εīX\sw0V:7C5*\EԹie`e;Rґ&sy] xF$1 q;o|g Qy C*쟟ZݚӖh |-ڴƦ8O%Lw_$x͹ fhPT|GaIGX/6=5ngڡUUTabr_ `˘$N< $oj$ړ?ι.!YOrdÆL5LҴQȩNeiNcY"rB1Bd{w 9t L0֗,oA 싄[9_R"–{_4@Z"£)akoR4 p>hPvĩW2eLFD) zR@C Ʈu3 w7=׉iךV@la~ǺMXo`*b[WWjLʰIiVG )Pe🳥4M)X!hI9Et53r]IgbͰJ&FBpA5ChW3)(avT$ u4Lô=մA!Z+ݣ*"݁vw} @ @z{hJooیkNWP+ rW1o>Ȅ<Y܏W]Yu(B=bYj~Xk\ft /[k[_e4)֭bގsNƓb.0)v[~B$}2n ?Bֽ9_RД\1HהAZ`@K @tefv;.yL#WUӜ{Z%4=GqO垦Q*_\{>Ru'J}vESa QmhLj].PoO=U:z}|1/fJ+0u| d5H MBV턜"\)B8mS7L'&z ` WLhs;Ӎ7<ԂG|?M-q*BI$,vԽ\m>T IYʲ0B1PėЈ/%S}"DɗP6[veiIi{)0G#(+nBDW݄ 0L-Uu7Ra ]G&>͞T2ŸUD Mq=o9~\W\[C0A^`Z*P"OFe#U%4E,GeWQu۠:{ۭ uP# ŻRD;+G W5c9AP@%V }(n~ բ]L^rU*~ dk=CT5WVYt[Jm# ,Uw~DEJA d0KRTb1jd$%qB-:Q?nTE\V+8iCΌBvA󚢮PJuV7)=Ե Y2Qy1a $ÙCp6>Hcd|X >ZEXFS|q&<i+W fCP*+KNOQҜ fTz%4h9g?,> K\cV s5џY"/t}NGQע$Oq&ڽ-Pÿh]$MV~b^hę[XЋWHΤ-YY'S3BV~{J]k;]hDZ @ KehdptR sK0ee=0}CXvt]2=I-72D!^p{Q6`Y)҃G#ݖL(n^'yOn줱#ŵ'#G?*1tq&J#aq)}\q<*pjʚV-)*8XXӬ&pjujq,\Q7) 8B|a( q?K!!NL ķ锉EP "mC d,Eھ'wKi!m !Y.ջdi̅P5Z]x"?+xu镣)%C;OȫRv5|?kF?"M%)0awԱH~@Ωs=Naz%bP4,d޷"ݓlV5\()8lvק.p ʀr hx*={"iLB$ͫ HAԦOKE5S[$o[$H6)f8*gקŌBoHjI3Ƀ(xA-/B10,%_3V_^rV@~نVfG?O^W R408aji}ƒ,^ӥrP,we3[i΍)s \kd"aY$,fI 6\ΐżtZbG=L΀,>~8͝yE)Ϭ1cWQ4/EUnOI f);N2a'[ seRӒ0ݧJd h&ƛ7H-hd;"o]7x҆zt?gGX8HBV~radL +LȄ8ۂ(GnEYxvo'oD3QZ^eߴDFU5g ܜɒ7gj_ %t*:qHؗRXzFgj坕!eڼ.]D.]Y,SÐxSw h i+#p <^ZNՏ>:*oi w5Lem9d Q{h׌hDbs,0- M[4Ա(~{@~:;Eץ*t\{k˂HVGV#K:ī[@{gЉnH"BTtt_$GOJkӰ&}}UTDI:z#ٔYSW jQf/j3jڨ IDwBSq \t<~** wr cPȮO!fԬi 嚸tL?kI(Tr4~ Z_\u_&۫%XEÌ ,))~] d׵uikum9`:j.;0~]Nۑpjjr!j'QP΢^(]brʾܯ ԅ^(ݗJVzukH!.`RSU%dXk HWU뮽?_.MT8XWrTR+SKW&I[],{ DŽԁL@yt[2o_ATW8h]6y80/v:l?u>X=7tO߾Ntg,ąƽ/t;N tXmKb#Kx:5 kC,W'gBK}Bߊ%N=zB$r'j M({}i"8.o,*\0EZ "\:>fkcqްٹP AhӅfv^&ϒl;+\ԴTD> /H4Mu%/©+ lآeo1^?bf]G?@@EuPDS=Pv({17G̥Nm@1MxPlAe:4=@4LڧKUAOY[ДP W&@a ٪V@(~-ÏvBH+*i~U6B!{iR_pVkmmZ&mbKmz=$3=N4UPwFl'rڛlؖ5z|t]/:)B~`B~jH 1A~+b}Ë*UŘ;03]hi`~ekGXEB`4P$A;?.p {q6w$2nZpsڒaےc:>ɞ>Zo9熬GP''; k!TւVn t҂W:oVO9w7;[vEmۖpPA7=Ǐ`tY畚QxTӼ'7vRF2Y| -vvP鴺nYPK ӀᴨZC7ԆhؔM]9`JRVh$*M1{n` 3wUXQfOzv#0{ H=%/n׬I'i3p[7>?[rjY\6=4&kp *pMj.@5`j*%נX`7w#S!mZqqhqN~ '>jAiT]H;LZ0jI_(iw(J=hmQ?%tJtv'O.V Jo-dߧ(zr(يƶ'w:G>d_eQވ'NE1E>` ZY yK|e {[YC[Nhoі,c gH=ڄpZ/Lx!tN hI!Y?dDRgv2 @Ep@.MFJoq 8\U Yeҵ(^ БbEn)rW2qi:O`}և8jݑa #Ӻ3C퀆P 0-Lѷ2w~%Y%QUP@pF7«v2h~s].U 8`קd`^6+WY[ MFT7CPs~ e5ДհGY { CY o5%@AEu([xi Um*Bѡ\ѡ0@10 qhZ_s?MHiH 7k 4#!dDу҆pa蟮.^ |'T62Ym_?WJ DRJԝ WE:?Sf4դn;jR0xKPh+b *$ R0zR  k((;.۷ PfTjv醖Zv_{` S!vfv]憶\IT~8nBfi`M-pNgd Dݡ2_2^9AqPsηaIkWFłģWe}BNjNxmjt1! L?ĉ'6^ϒA64D!P25qA|$7D[?,j9$E5 ȮH6flaj,@R,C,LS;:(mK3C_QAYZ+&^!xw(=u: C݀-w}J@{& (fjU\BS<;pΧTYPP5/!eUIsr"oJޖR=*GUE[OwV ?>z:jMC"Z*_2A_q0n,OsJ+>5*5}GzO_g̩Y4p/~Beehv~;G8>Х .6Μ!NL%; 6fBRE 2Yg W8dp=KΫ 4* }F9HkhsC$'#0eF!<{sՌ`Ou)osO\Q X>uQbjb^T&Y^eHv, 5;1 TH(*xvO쮹#+_`;_/0O·A/kWE̔&p5ݜhly[tT˧-%+{{s|1=-2 Rdx4,W?  G6 D ${=2ЕccW*a Tc1eq֜c,%'Cu٥S=fVl]0t$4E5+ IxϙPNku|H8"ہ5ݎD~i Ow ky-Ju;(?&VwH4MFIfji !YZ&xӀ}UTdFH4`||tQ-L!oW,/$+]XV==Bt+d([. Q(:QL"8*x'>LQ XZZrw+tNu%Fٴ`'^T )lyx̲tQX1n2J,ۡyBc,ւ+8Z/}x$=VV”(0d5AwXhupb`z}MF @o|A:r񊮰DW)M4EWG)_Pˑ %si"q ҬQF8U!j>kƦd!#.ЏnJw*uH=+|yDJpa\x/t#ـ(ZiWD$Oo뒖ߡz Hj2B"hٖ4fңM|C>-䍬ÒK !pIt{Lh™&/cf1\=uP[ /kyW@_ H$kI%"IJ|dzJKBXa [»۽T i!t^0!ySw#2@ٔs<a3DFhBz8nJ @n SlLo`ovaۛCQSjaYmjOWX s\ 0l!['d N`rO Yu B%EK,ރP j-"eI~&} y B]={ZPGoo N24{rťzjM=)5ڎv|J,SfϖRzjG=%p?)z\KEE@=TT^N.0z:T3"ڎպ+ӕt= 4rBϔHlȏ4+'N$Xſ:T,HE] !Ai(%'9¢4+()p5LW>,O_d3Dypa\f*keks#ӗ ;f۰Wʾ\) JkM3R\)iS:So%I@-hx=i30:Ԑ+k~O󕥟(ô$Jr2΄kγ++tmGb-9ʧl"T>I{哥Rʧ'Ɋ:'KӤ>UT||ǫʧSI[ {jM6CϚ ԭ GSm.ue[j*K۫:_LIw'*r㨜 _S[h:P겴'O{7VSUc4GhEsP]pTVO]LVKrۜgV aY'lʆN~N[Bf)З\xs&|WєTCG!w3km{ kKv'έZuPG@3?jDIGT84+TR*G,oyVq"W t˥1v$$Z-GƥrD?S_=yJ@z3!^xTB-}ZƐ}Er~L>aJјԫqxR#Z2(+֗S"]@Q[̲iha X]N'iΔ!X-z[`k=g[⦿OS=^oƵQdT]_^¹w`!吅H^w!WZhy,pӯl}6;?B$-xVTkzCM lyCl̾o2WNWטڙ_cE~ /)f3 ~憳 J'y.6qR`!띶+|+˙~gw7G`R&ހo bۊXFKׄq8-\kٖrLPCGC.$Gtn\Hz1o0.q鍄ymm>ڳS"YȠRz[k#ke*5U !(Fo`JwrDfAjW 6v ԏبF4E_G7$ z_+h·<f'0AU#H$vQ^RU|f~83 qC$&|Fwdb91R5l9fZѿ` MuQE+ nƇ\v= x"R1] a yPZ׊;MqmQŮO?[m@EjPU}ACٖ noFSA;pЌWs.㖽)APJv<Ȕ$8&VIҪ>)"8Hbc0 :wsN1fzzޓ"|>cJAOD+(U&e4iGq1Ӥ lI'18M u]*zzE6 pЙU4UG3 UzUJ΀\a)Z'Xnk"s2.ȋdC5j5}Gh: VFE ٽ@ [`hmt۪y]br2RU̪ Gچdfg™Y8On8 JnFS;pŁfJ=")|rJTF`Z lSpJ+eBomT0 cK;N5}!u؉b7ɍT֧/s깔3W tmn֦ht dd]B$F*@Iцi!;y2D [_zB%ZËj5,61_с\i-mf(KT &*1M P kr5gٴN40a.Y;`x?m I8r:1^<^5&c#_Խ^X'{:-k@&{{s9OQ, .Fktܦ=]'ja?oZ'"j(;6CIl-nvC* jM[ j{IbAX#RM8x~ds źof 쾀{vt#G:Tņ[TVUl0T!Tvղ9tļrCjZRQ=Ħe I dCR9k[9OmI?l˚yIt?uSrOଢO"7ӂXolN&^dw愮N,:/܌\l|g?N{MJ[6z_>ǩ{_VH&%Ah-) &Ha =ڳ W;) ]U礼Hf"9-Dҫ; U,9vᣈYo''u/ןЬ)_%LZ٩ I?&)}ԏ[r'GLe7*y&ﰊ/s=$ [Z ZȵhVmhJ$!0tHƊfGM}TϤ]SKvj#Cb+ RX]bBb'q˩eȐRuI3-)3.eK:_Ƿr8gӫT3z VT6+/U UW>,Rހ|x *ފJ *>%r\5",zQzV<ԡ6TT.U<8TK8UpιXZ_a9k}9a2Qi=A7mkYȳ%)> iқ<o҃϶ͩ]C;@/Ȣp` /2݌"uaGSښ&FR{-H8Ţ! Vh`{tmw2S R;d O\w$lՙ84lAH 2\[/\\ϊjm,h6nt4&&&ˍ1A e/ nu.avxhq7";V>,y~ˇ-}s4k38DZD.(ևyk1,W@SEqT]:mPzrE.^;J]2"hfQ{j _55"H,tH1Y";M3e˛ϕ7*oނʛܴ}sTybjf WIw#7MyyɬT8-ep * ]8yqt=¹ l|}}˨p=mZ#ۡ,I$'zٙK֤jN_,8ת`JGS;p6Bo]#.Tۮ<ˈR5R܈;,#j("1!ȲQ4CҡxLd̙tIV:}'ӜIɮB3bR؁5ݬ8lgk([ ڰ ƺ~h4]| .Kdž` HF`)"q?/v>v'դuY3e/f w) ٷsO\:-RBؤœ4*9⟨L2-[ޖQ4,ofK}ѾODf?p,e.UЪ}a̭L- N}B )}D"Cu{_ǷL)288=8z4ytMU03krH9H9)vsIUh* v;e^)Pa^ճ/ʼ@RK]5)|R'\Srl)R]8cqt=W^)R&st,zX~$#H9 6)G3)XőrqI96H9Dj$o?"؆H9(Oea|Eʱ|T !05Z)`m?AfYrK/Z lKjj kL(G{%؛H>2A5 qX.0{)iSwn\'V6nHukw7~&񕮶.u%yg:b:z^%H5)8h,GhGΦܕZI#L00_xL3$meQ  tYq+XڶU 5R,2*|F,Tت+*3֌و9םb0)*L*zbt7@3/n MтXIΡj%)kEı=+|}H׮ݏcL[=v:&˖$hԼgJ6;xa<^" 57۱oJG)JZ]14CAnp`ERʑ2K,kLr.6r?qQ,ԭ-Yoz{J^[Z"Hp̾!U'~Z֡Pj gj5v4&{\\_R^lk!tuW:3J\6TroOlRwIKk f~OI8cT龀 ] sn~X͚<NTys%(x.@hu;ι?+6 4Uʟ/σ3HQ\%Dj^WpFŪv8b݁Xb=ONe&bm9_Mj RUhDF$R7T T WRYuoz# Ż1>inTD6{g@럃O]{Ӟ*D3oh;k|9\,H224Lo*kzeO+gam[aԱ XPLh)};#3*7>#Bҩ%9\TKS9[kh/xP6'd2liu6'xe#:duv>[\ѩpzGڷu4[ %YjOݛ4kԏG[ƱW%{RTs8h|qq z>z3L&\ zc$O1YYۖu H6!#x DL1k?* CI9hZ:4mrH%ۗJ:N-B\vjgٺr'r=P5rкޥ:ahX"m72T {b6lvBs8 VWj?$GSf-j xll=.(<f5{[-pИl3L);^_N <&3~U&'Pe1CgkH;h~/fel_ _[vo(c˜5?l*W wQŁ'@SpT>z8h9Aߔ贡@2ϙLm%%{[1P%!Ӽ1J]7=i"8k`J%+5Qܻ:?!ÊnMmQ}s2؈ Xg ,)xaBX z*=pz ݴĂ?'.4'{l,e[I$L/ 7%;[7bAT*I1}[$N'fv2&O U;M3*Ӗ[-+T(IiXHiPnCSpΨFn8fq|]2Hi&CP^g'yV&ހv Z ,ϵ*hJSn+,0QNG06 ($ohBYſ*)[l~(Ⳕr tx!h=ǡh|;q^In8DN@ֱ܌l!zfRKZidh|Vf;Zb|͐lY3zDgXQ" –nCc vn-n•!$ܚlM0՟pzp4Փ`lgs0e5Jn@.&{}ɘ.<=Vq4EG3~/_,`ENTesC?W'dSo)z]8gګ7.ɩR{pl8  JӨ;iԩ>t2Wh9}t?wݰM]G왊hee(OTlt]maqXƘ-c џ% =!}  ;2cjQ8Y.͌i 4}i/Cl.^HXߚf(7K{s@kuPTkTk=E)[_T0,S})*/k(`$9M}oɌh9Z:d#B߻@O};ǁ5?T,MeqOB}9* Љ8*Ŭ(u" 8*)]8gȦ8*7T"vȶ8>Z"n}6FpTT˔rT{fvBs8 V6~g TMqXn9,5GMAI,͞~ oϵb\)k7=S7鍴~Vv@W%F56wAy׿WᙃRm(彙m|MtgX8bہ`z~h~/fNaWnXCہ1:p8{Rg?#Yz7e}BمsFfM]oQ]kqZ_ `(;?k +kI@(f4@G11Mbc]Di,Wh06beYS {g@)H(!!B4Ep4LZg++rC=Zu`C)a- E$/ɴPw1i>\KK5c ıgJR#)FE2ak-H^[3\tЏA, 5gs`\d0OHa 1|hc ) 4E G 3[\fPAA|)>41_Kc%Ij>hPc]|4)8.&4χ O~Z}Ch]R[*t8z ٻ/2@hV` ^9gZWs5lOehA~ lZl=lԲv]8eX|, 4U־ 献TYڎLJtQnla׎뒦zx^kUh}*lc4+*۷u[UKWs @Kw #֨KV6k:U$$<#a:%(w_} }t-:.[ǖ;EYReq] MEiTVܞBɯD$w04&Yl>*62%"8 bLM7!D !;FruBd+S#"]ar6'{TRBXKEFStfhg\##p4Ù{)ulK՘%yrA1R5T M9.n꧋Aw=%i>%C$]lVxgS>[j 3rݨL]8[5`b'*ݹ/*ۆv"dTUքG׳Qt@|}/kwLdz8}!i׊y֟ī 0'MXq{?{sU+֌jvZ=B`4TXTôLQ&[*]7y[өt{RC AR h*Fl3T 5-HӷIY&=أ@Udt [N[{ Qw;Ń=?~0:=> t9lJ \k2aOo0y^n>r4Uǂ2e<" )sɓ\=NN}R]{mh*'oo]S9yM8*'oqt<'Oο<ݐ#<}NlȠg5Tf4jG1 3['{;dߊv}P+N#"\7l+Q dOp-!)3#/ F&~,Oڅq ]k7̀VL pgYmje-Au|Y%N@؆ִQx-݇\ Jkc] pY-r^!*app Jiݭ T-L~-5BLSc-Y,p4}KoRVվ}edظ㄰ dBr捞hLBs!ϐ?gtYc?F =MݯWCw/~ɂ/\lQI'QIi}Q U4%t2}"a?Q(Z 1YP/e@U;DZOC s*T^g^Y$M.%ou=2}?N^ PW)%paMxgNpNsBxogGCSja\[bJ㔅h.d o.?]!Qu!z i9m@c_J]-⭤mkHClϖ>JGvþѮ8l8%.8ۛhMf~42Յ^xT!SB3'ucA]ӌY"RLɴ Mp_"d-iǠEVF/tK_;Kj(IN_hj(4R5Mhiic]iRU&H0{`1vdNs񆞐!uV}=. l4.De+aŊ8ö$Ϯjc)T0:@%}-vO,>yp6T4k4IӑL.dјJ#2Z~t/~%LAm'U;pTaqt=@i*R[-mlXvyB-ѽ O \'us(IR}V)G)V;&ZO_6hqC"זP&:nDמ G)X=S4QA]L>nzϏ|u |~dC.} ydoG°+-pPΜzr' j?LI-H8ł1OyON|f4݁5ݙK SChN<+`SlD >DSm%ebN;\W~q쿸)3ɍ@fo}p5KxdeK~9g݇T=GS1b0Njd )ã؄UP怫*wo^GǥAHN͜ a կ-^!N_\}ِ$(?qe0q|K4dADh`R_pq`3uسJ+qHf:g_ׇ$o$d7Fvh䑗Ψ) 8-mFЕ-KuY[zOS[[gmy*ڲ/Nh'Pcu#@Tajʨ-E)<}-Jrpl.Eև\r\DO#gJ<"Tu0\-M~Oi-t =yP@Z5cV'HqyO2qi$d Mi:*+G i?&LV4LgQtmLjg Dch=F, ?)Փ)H Φ)P.ꌍXSNW+2z:dt钪/҆ Ɛ,7JjR5wU~+PŽjk.V mR`IOq*,'ٱ=&D==4^ݒ) n& :Rex*Nӄ%!Z582EV)YW7u$))[Cjuv@]JbyjBSڱ*bu@OY;hJtHt1 զ&D Epu{~X>v1 6kVwz5~SܘqLiBՐ(UDsk냞>dgs9t6h$FRkiє&1gq+ċj^T8x$2,fDPFCwSz@Qx! F4Bf|1G4mpi ;@W:Hٿ Ƭ(˲E`9B$9ڂ6[BH3rV'ni%}gM[YpW@;^(x_r1uSO]w7~&oBLޫ76@eɶ3k^00Itl' +wDQ>/ߩ+B@6.sКbnS0zۇWVwݬb?4ݬe%<Jx oY^JUlOj/=HGtYىʩ.e#܄# % lcQ8 YNBQs 4=UdZF)y9YH1Cge$+7\y4~.Whb:ʀTZ0XI :PjJa) 8Ӧl\4T(oXRҜޢ"*?oIˤA$9)-Y1Z}HFHT]̽;y[>TE2@:Bt?9| '{ŋũ;͞pM@m0U#W{PزKh[wd?j}}s0v&*N0AqDrW'W2iwqA+M Z\jӜRMϻ:UדpvTh0%mN[N)•m)ItH]}\~Q84rVOV2ecr :^4eSw[&^hyy"D ׉y琼>$u~Y  Q@CV6?2*FɄ&k4ѕQJ+BOwL h{ ^k$i]Щ9C!fYPV +RRy(}ޑ@KǗa#\9>m(U_v -@=UjU}nܕJÓ<6 v AyD虄XppT'\ :M[]{W&.(J" dpHB2U8$%xlÔqUF:VSʨmQLF<"^F-A\VYV˦̖R)f7HU[R=Xϗ "#3fP 4et0B@? "ܻ6bѪlцlQMenS٢0*[t T-lQYեEvdE[o˙듛#~hi]ߢ f .sA!5< vS |$)YsPWD.boAHoADO7~lcU"M9۾P9էX]O=D nH5L\f1_$rNh@n0qi發_|w<$czm:iu GlV#7:BϹ `29edꢹɬ>UL̖Ɨ1T,+whv`h2 )K)B=oFE=Up}5ceUNTNjq8tdT9mV\N{Z{ND .BU֝ehaTm#95m-H҃.UkX.\#axEz7/SmQ5{|p X;K|̞.dPgX]=SO 3,j% ^6ahJ;)!2ܢ% qQHS,ѯnry퇨ʁeCuYگ{>N8v}pls`K?ypB, g޹JS=0]\8[~~O'~2]&կIkWWkԗ?GwFo!}ٚYt"},?^ 0//ܘ8!]9o=)lO|) !*qV0HHH\$G+a$8&'5*~5aLZ;NYc`A4ɣFUOgyAqkP^ VרqA[UM^Q[ИjI!Y)\߁ bMpвɆ[K%LT[KO\$z/^؍S ,ILPL_I}.h\% WlR֨ğ/zgvӊikl8 V`%L( ǩ^zEzY8kB (܋_GJ aMwI6ύ_q2UƄC.aIZ  / 2&3q*"mR܊mR4G"$&S?J)cu۫=;12DgC2R??p>gE"<$w ;* !B灮{ϡCy$q.(f]X;’mp{NB1q\ْ{t\̟}/y%bAʠ`>Hg JWkg:V&%BO&߮>{O(O’>ӿ0뫘L|Mݟ Ls1xүotLGo,;f(dKky>E>=iUҕ̗dJCn<60nZizBPNlɊ|>aj׼j;,!4;[-)#dXDLH,9 4Q0F Y1pU!WƔ< u\n؍MRއݖB.$@u$ZdP2Ƶ3b>5 #p k`ۯ 6j !3fH]2f0m_Ec$u?|΃ λ &-R[ ;B&r0A{bjmZSfkEĽO4*vs^S S?:4>;`j ^kH NV D:|"Bem?^?` lkl`ncp kw82E~a_ueohdn!puv/E$֭j*)S+B:?B|΁ ` -jI,d|T8h}pk `ki(/OjLG0ͣ)j"_=:,a$ˏ.Es N?26djy|MQfHt-mnaɫC A6 ~3:և8U[#L'w`SS'"t>seX$O4gagXYD:M7,Md-́jXzA^S8pF_п'X~f<}*nJ -FhK $YDa: P{j+wn+m8%F~@MA_K17+IRl;g=daA&gL+7NW3C7TC 03R\7(l9fi,LWS4j\b޽Lv 7Y?NRYX3우q6 Մ8'`g`CWvhÇzyUѯ.eUA_~:@_Ѝ(noJEӲڏ(/N)vsMʹ\~|3$T2 +QwC@fsVۈq!p{<[z &_GX{ox.d>|1]g4R* nfh!ZS7~竊'*G0jD=2 N')51"̜( WI2vcow0z?[TdD|ؾ]z%Wf}kV2'k>XGNE޵XGېAsMŪo4)yЩZ"4$=6Nq7B0id;ĕ K#u ,kX&>E imaLlŻOqM2o=SDg5S[hF5s@цphsC _`Q" *±_TaA&2C͜hDq1+V%"j/kL~QgrA4lu)W[a7~Ľ&p6z{j̑gyc qSәr FG7^c48$exR.3o͋z m6w^ cQFtrdEhe\YGtm3(v ^Fzc|rA'/$ > e:p@sd@+%Z[:aZ 7LGޱpu0m!]g}ow@:RNt/N|{y <}!1/A[U_i=j'Ʈ>?XB|dzallՐNuhHZ|p)Zt-(Waem)T%iBO2g\?2ZΕUΊP/C2{3ѵ8psPקn[ZާudW0 ,h1qC?V:"8!׀@`ĖBhPD[E16+8VY`ow7U*h G] m"1WEL* c Z-C/ZZb`çMHԌ_gJx|^ix|$Yf],E޳пd_Mo@8K+w CzČ_ˋ(a^!G{HHc0SP0LS~D K]f'LX=W {"M.[f9L^IA JyyV ΫJPOH',yʢ3iYji$~Vjy#Bɠ_ΙGBϼ, g&oWF8BY9s#i QjY"{]EaeWlxڮ#I*k펷F+me"5O骓=T"[+^J%`'8R9-=*Q&leZhJ>,Imї%Pv:S  n0H~C~4hR%\G뚃F́'s&*!I㥗ތшq8'`)T=FO?eG;;jQE(o~’of;?¢<+?IR!uNG RНFf9_pzsclUwXuJtyl|5:C~G%RtuIr_;`|~̒2OY-([yX>xxO.} {R#&N:#&N:CIG^&m^f7 5n)- F2I2I@^H`‹]ZO'iLfz:N4>d E`|8N"!ϾVfuLɣ R'P)922-Јi,awߎ}lb/qW!:|HQRqh~4~kfʧLsV7`n f| {wbSc&O6ۭ dN."~;Hयbsr6,@?|з( OwGyy)o($x0l Z :,\:='_t pV{pҘ2k9ª$,Ba75xt-uxfs/xJ }ۄՠhJo6X 6(RLy?wbmFKמ0vÛ݋ӱz?vi4w\.T/x v&!M[Iuk[NlMnO3`~E<ܳS-F'`VѴQx-݇pi*2@T>iCH MyTciR3%+ޕVj Z-جCϜ&Y^5gY^^M/^ \̈́_lsd6 !6! [*楥1#[:݁ X3`x_"^@pݐj[H6^eҸO>;1IX5&ٕX2麾!avĆ LϦ$R5/^E̤ɫ9 pjv&Nn:5MN@n:5PUѩ1aةY695Nn7;5-N~yFnqj[[թ8nwj}CZowj imé15I٩rj S#kN `ͩ;5ǩ1`pjS?|SB95× S38xXVݐޟu?DC @7?u@CP~jbGװ ~h`=Z4!mCpF?`[!!m~t![~ر?DZ@!x5?Vy"C$Xe>ʔ%>z09 m8 5ƣPSdlI 9y!ģfhi20!3L///Y4]t=4 ,}x3ptMGL! bS*Y!Zv~q"Oy #e̸p֞+Pc,0xh1{Le[ %.RMt-yxh;2}ƶZ݉Py%G 1.Hp8"': }Q" e ;}V0ZH?gS,^3oI 2bJBW%S,^ĕ&Rzm`YP %b>Q"rYsouG@ s $1X$sZPI4::!LR uW8s7YѝOܹ[Jx:};dz XLmAy(f^MIQfW[aDWSh_ &TgM &N1%KEs6V<"刋h\!kDn̰bB01}@Ůցј9IW~ = b6I9?x$~!Q' z5b8v01@ LpdmXs{OQ̣PPP+C[cKzxvʀ!5||[G9@i> K%Va-0@Y85CC"8QуV{Oas2kI#E2 BZDќa$҂%NˡpK1?-SYK6C@"F810^Y4Iʚ[@A#Yi <ܡ} aVJ*5Bc1;G)N s{V:$6;Փ,ӌ>ZƼh< %#،'@ ZJA/y HGH8\:نQe8?8 ΐ Dٯ@`tNi=dPn2@H* F6T-tsaSZ#yBN50[S*X]Y͘'Ϩ82  S’Ug\s!@,EL䏂 I!$@-Yp(n`@<"0IL&(ț| L>gE 0S5>$KiP*g!>@Y|Q?{#;„8Vgx񻴵\$!!*CE!.drD .LK5ȃdG,@XBbxP<-%y){0Fϊ |v36n)|x6du&Q̡z#K90a c=W1=7![ĕ(t_Ic@x$iBMLLῥQ (^Y<]ɭ !x;!h-^XC0A*rL2|)]R ؗ$8tCy;<  M0 1e0"V3[ӬRT`Re3^`qY(8PC9b F4~ Xi*iVH 06P + Η5Z&O9Z.|bMqMSi~R^' tZ쐀ƀ@EXP3أ&58Z@0ծVr<+*O`lY{ I%8IkW8ͪL7764aʂI29Rh=_)5ż<3S1#n@/LH3xՓw:,\:ۛf;Ns,;oƷ3I/ap߬YdM87E_=ڕ6;l=9I?һ>I'6:|ա[i=NPY5㖋XބUWMhbKרtċ2LfZ3z$q?YEUOg&bt.,/B P^7q CNp[/NGz `᎕&QN _A%[Xݲ3u-{7ȄN6Z*a&Z=cO+q0 J=^/K/ײy 읗09qVPkmp!r/ҊcҲpeZZPe3yJfm%43u-M-Y@Ä JU3h~=m/Ë"UgAvzOd`N;p/>@xrs7Zͣ@XV "$pXlF R-8fauj !-Ǔ)l7[ 9g#Dd9oS X"?6OK7bIY%A:!: ꎪ*osTaoLV"~_͡n۷uڤmRQt |W_e}1A${H36y1؏c)%ooT]d/2͂ɑN͵W1n}akG͒X1@].D180^gIr Qf7fۄefaA(3ȼY#u!$8W%GvqYCV%p!2(6RePLJRN뭙΢#*??& +"S@\ :oǷYMV1 z Sz؃*.Kmx7cbDSv'9 Eʠ`#eU٫@_ C1d c3Ŀ:NXEzUTg_ i^47ֽ1*Du6A0&dNmuQ^RASwڔcԊT$X"츨8ZAEhq W!IVsNTȇ>>LDZn[s}n+C9*nQv_߿M>5DZ櫧% Ѫ"4~6 ]B&ms7cwg O´3!WމY^TM+(3yirMk⏝YjP+ *A(Q94g[oV?S,> oDYyVM6|̫cq/I";˓aC//Ab+Ўݏeyd__ńuq'`Yxږ& "G,RgWYWsٵOD5L[`ʴ*K {Kj|_uU"Ja)2׼j;,!yiv lc5`xJ)$uBQUJq#:&0> h8 h awpc2,*,ΫCA,؟NV=T"#6~.7ZÔ@鸯Ot<`gQIq2{,Ap.R?ּAF"Bi:.*7Yuj&pFClU3fЭ2fQEcQu"}UzUv HWweW?pq؍ˁ#ׇP 84E LSp4E5YAN98; 5P`g[ŏ6أy(c5\)#0/xy+ fBB=-(畕]ٮ-S^ؠ"/tnCn:8Q 6Ӣ?$Y",XoS;l :01$ќb9]KIf)$Ct Ds&òص]xaFʵ3~ZǑSmz0F;ؼhJn? 4*ܰOWzLo0cRlJ]<$ bMQ~#xB,Md( vl")_dFVjؗe?_da0`-o |/W4MwA%N(=!M0-Ȉ?xEIV6z?OPk̖^-_4mP jUz=9 Iu&3_OmY!;b0>_\$zCA__7%V4,I &iv]#Jo拀05;Ybb擄W0S͌*@?ٶh{Dh#ygrAq ف]<%xPˍ0QA=o/$E hh%`}nk{?X |vMmԕՐL6q$a-pǃE: s6a i%67 /_+ljcH:"86@۴P[pS\_B%6@MklQP41m@ck  " h`% dC$i#Kۤ@V|7ۊ>8 hk`sYn7":އ sԩ~. v<S4cIWa>9hK aw6lM rӠ۵-0lufk7 v{z#hqx<F}9+nX 3~3?qǿUg"dc1BMٰoƓgƳolF|:1 |?lļYsaW{DV^sbR;cϫ?ǷֳA`2tj|f?&_`4\;͡_ꣽ'{'*(7+IJ ά.AÂ97/N|y N]~ǙL)n7SJQoB:WWOeN<V d?CI#t 9z_TI}@&WΨ lzWN8y'>6&yNu^s'E)!ԹO9Ԯ2#{gnI!s?{6 4COÕ`d˪Go .?(%yJ^ w½$[Ij$Iw!^{K~/nBf<:S»ӟׁMɀǷOI(_ʚOt=Z!^4_1qB]ߣs K7y[Qȫ5>[CIo\% jš!3 !|@~3G͹|JHeHQs-Vζ=¬,}}#.-{[ߢ$y)46 xpg5X@} 9o7>(2^O$ 愅$̺3Y.Q \̘.NLPԱ_\q[ b2umc#͂8R29-n0aY5ej26ٮɔ.V '7a7nE0V@@\Lp%8J]n?j}jy ${~C5(o J =g=a\4`.1.> pֹ#HN= l/3'g߁uiΚ険3u ni,n#L6 Dӝ #Jx 3 َF ?e [{FcޙzT=FOW xpco4oJ֐%/A͍$]%\.{+M/nY %]P~>3TY5U搛p*+yZ?\[9'l OziPtgy)̓&ySA3YG#|/.~ݙKw Ld$pax=TsĮ&LFb ֭8g^ %޾7z: +_g2\rbɍ%ᙉ!]qEmyŭNse> !S1S|{o?˾9.&qK挿G4%$##Nt<ixQvō늴>+>',,Wq˵t 9z0 yydрq_\o[5X&O ;YIz)K.3d :G5\D 1or T^UcU3%2HVN_ަ!Ig}p0ׂ>FqWH^9 qSgHi>azO>Y0.?w9$mUpH{G=\ii'` L 8}}PZq{4z9Ke[3w@SK/Ҳn^QgAal-Vl qMr퓕]EwL~ 7uT#EC7 >!% xN i_noHo+:fA ɰH\w]{M,G$aٸЏeS\V"$57Fka_K0쉛^ ދ89Ϻ 9jpy|p#vl-7yv  yyd9%y{Ywzi4w\ϣ.'lfo`[n?S:a& M.Juk!5'g?eu,tjy!qRҧ{=O ɿT~ qHȪC|aB7Έ>&綢G:]bxX^/@8IA{ϦꞚt,T2gF~DUxgF[H#Bk^o SnʃEtPKzكAeU? X31R v%2Լ n슅\2T)г%e/L翲U7f|m+m[ bnJG\WP0c(t![,YoˢOb|>g؄؅yno|%y;RNl^1E^e-.;P`Xݢl\0" (9XVZSF`"eӁH˃:`0ІRz&ƒy;OYB: -/Ơ ;1-И㫯DQ{.Sq]` n0pJa& _k}K 6&; ;yLiCt*??5mhܴc{1[`Jjx5_GŗUn=/D7<[4[͞4fsO]f WWWݜOW_=MROSP{n`'x,uЇu3EbeD,c]lhبqzLLR]vr3v)ߏ:Ez-<}x,oet}8ZHդ[?~ y q y-tn\yC֮Pgu z xm6]yV``'-n˕%x |-rl[[mi+o} v ~\yf+oCڢ~mH+; iZ^yux+o X]yK֯5ͻϕ+eǕ)0ZeWކS̎+o }ݗјXW;{x }=^y2ȕwa9mCqǕ-{>}6qp(J?E|,[>}*AL?ew|n.8K\4JO'.C̛z1 ~p2D> ,S3S5;ܩ~~;'Z_Od eO6_nCgB_ Y?> ?zι_Ø?mK͟/ܑ}ݧ}^0so2͡[g{zߢ$y{&$[p?O* WVfZI56Tڒf춍$L隭~"@2A@m֥#p?~N^̪Xm(X˟o ao*r}ȱB%}),5 z5%h)6ٖ4\D1,*gIWs |] J/Ly~? i{ؖ!g8Evl/e}H4ۺ?* 1qYK=(ٮ1.c{Wv%}GZ曈 9J<V=/d.dC\ll@5ګYx*X/cZ1kQ'i'su] i5W:k/ϕh`9`[}p;=[?矮6k=z<)L4z&66ЙB]>TEWՎW:wP]l <5 V\m<ģ6"so(EN=ܶIL6~6ccNZ;o..~Eq.0]˃*߮ahnZLXtG: PoB/nART,ׇ!8 w>kyM/WDݞe#;V;^&3XO˫M; VAki=Bzρ`_GgLOu;DsoL3!oƤzWziigSk ByD?pii0"ؾ>^} BB ],kR~G]ֵu2Gf`7Ƣ&@蛢34/]`W lY.v1t6-^s ȫF`9tZC\&,S𳨻}v6=Zݬ#+x#Gf1qHftV"F,ie[oZQZqO7jUsvtAW@V=hͪ_ #s}\O[@Q ֐f/B<| ^Z|+T3t6)G`-F4az8$F+E CQ45ILꮓc[URhZvݷ:訦HH%PRiͽsp3(36Clt;ApcH6mV:8;[á+I`! 'DZw1cڣ#ʌ ǵi"] D!$ v,;h{ӝO|aR$k$)MZ׃2|v /4ƕΊ\UYC`ELB6Ӵ> 7_~EKD DIc&϶DX&"Dt@/d[ *Lm`bgZy"06a?rrӅ{kL&iurqm+ǤH(~zl \uwbDPP.k;*"y59E?4CfÙZP5\'>l*uL*"[aT&aXBU~tδ-.3 {HIRi &/~w4XQ/{T ]9f< U,9 눈!$Edۤ(5υ~޴M4Yd#3Y.i,rmH6:J;8dr˶C΀)ZcLU;[dW[m4Ky2Ø+Mf/_ZNζF@ v/ڮ暆LÍ;4MOwOh+gf_ޝ}=:;pv6ˣi\NPf?nQ^NcHȦѩ2|LaXTCHXpxC1L~GK]Ho }.˱F(ݤ\i3;k?՝֧#tU9/rϊCαdB{P]4c(BCϕ[goSRh:?a~?YNϱsSF}%Y1GzNN,Ae k2ZXC$ I&@bt4- #~m{7֞&2CRo>Pnxc?( bӸn~]>%^H wI}e~!Inh0+i=ZjzZ暹P-?[~р)}*<F֐V%X-?X`KJDI;qH;| $XF`I_Se` Db3\,ʜ,UKCnžLW2 J mÉ;@{:ra"Sf@%FHG+%.omͷ,4Hm7AOV͞ cu|UNdJ-o)ۢz~ee/^:|ٟUAVOy9"e؄MƫQ_81GZᾉb2@obN8^;vb(ǒ*(d 6ʘOXt\^Ƚ+e+{)5Lj91$"}(IjF=#ӑŹSU] X;tq%.55KV@4"2Ⱥ[AzX[aٹI3ǔ8gt:XU_\;B*9\+K*`pv08 u$ܪ }O.؞1B#[8yb Ucی"zJ*J]0(4%e%DϬ5(, w<C5@ %m& lArY`t}ty^ӳiH,0ݲi鐞Y \UXok|F&3d=*lG1LlO J۔,'l3|Zu7hWJJ%uMcMjZ@ p qߧ1/w?1(GՒ&!GDuh]L5cZyYU ڞ5"x:ALG-P$Ԕj tl2(-nģMiXE+ J9 L\~uK@[C.vUN&8]T<ўP36P !;!]$EpT:f;޼O sw<9wʯՠНB4 MT4=X~{O iTELBXO+@֢Bh+i9k|8 <'y0rJiͿ-\]?|y<}H9FCd^N9fEo>?>V{ _]m !>Mq9@~k9n iVEN> P\xH]f88oF躦Zet/[H~Őd٪Ciئ8n(T5<P^j ݨP7P-#?g _ 5&lL["``;w")\͑OfAZ0]ۍ^669S{Hmak`LW@\Ƙjlۗ#xo`X&~HR_s}$w Z4rٮgcuxMyp g}cdL!CJhhyB~YjbmMX5y ĉlg@k=rBg"_8N4͖x#œ"Ch̞kj5wDQhu͊$\EAȐi葛/m((Y|fr5P]۰g@a:2,l4M;'C4ƫRDŽAg ѨPi_M^2گfՄK-9 vY`X C<,YM6H q:>o6;b >B!Ww$x<)OOxzrЫ1*'C!;PAK5Gjh*9.UùBfМ-&ƲN3ywק:RZ8:!u=C$^wcSSZyЫ"ZG2Z~N2,},byWIz֤.0(@zQL9qzܴ+^gky朩°>i]*4R$UXyU)P `vE'IB(joAiE- RvW@ZxOຎ ;.6֎'j9~,[h^*մC ]MH4~B#4)g/(ۯM ot 6p/]4P%l= `#ÀXNrF0;v|~e&2>?Υyy#~Du (hK:Ff!V/:< :[Pc&`lC~q+|r[t(2l4$QhmdByL?x'?[>zl i3 uuEX).^[H:l OCQt!s-A.Qg4:/Ung X=V:YiGbʢwf?E[*0сuL}Y|'?<ঙsAd84ZQliL8=viasN wƭVpJnFBXYW#U'dQu7&kEPoAb*Tgx2.BuK2 .z'R|;`"ryE:oE:HRNUfҖˮ 1 A$+^:a;*K~橧]q}hΦ 5}39eX%}OXzXnTBKI<B/Rͤ H`{r*E2Н7zZTNb_?{S N=`u5?CgQ* @56DmfRn61Ԥ;I w5OjLH?"ey'{jWQ*QfV_ͪ+RvjPzs O꠷3uWن&@, k`=oط[ 혤?[*MYvdx c Zz"u`9[i*8v9s}ȳ THK3aW+?L*߁ycį0Fio}h+e2qyw^tz TFuJodv-s(@Drzi7*`@xlƗ#P`xmz%+m دAl;Fܡbh`(m~I;g|͘QwY& zؓn0Lk|4t]<E ȝvMcC@ˋLtR ʫYUˮ}Z 峇H= 3H2(vjin&57)*:+K: Lf9nC*&Zk L1OSԸ3QtHoQATuEcT Ld4Bnw r DHy&ly 3:Q'ҋ@-0sNEeB8V(_RDf%Z'RTK3F2 7ЄQS rlc=@:ܲQB#疠rY|!^ K=QQx1kbMJ*mwó6&@Qa0 f*xTcaE^ |)hRd>%Ug2/q_Paȧَ@nC!SV@ŀ,  V݄ѿjrSu\$ SO*\ !cq8Y-jW}y,Bf|òPi{aHPzWAF߳DBzX41ZTI.*kH6AbUtAQo2,&&Eי嚆8?t|>2HޣyS? "wqZdg[D)w`x*LƩHE,R`R +- m@rηn^v;yf˂zHD9dbf(EXǞ~ߤk9>8NPGAQ(i!Ð4IM C o!Qtsd>CHF41T|\Ϡ e 6cbP~UVefW~4Xgbc|"D&WlXS/Lu^>dVJmM?4 (#CʺD6vcX\Baw4%e%ɄݪϬ5\&U L[1mB I[س7A,;+YTk 9}Wɖr?2ţq(mCvzpn le J6A_޶YYլc>0\9JKdM.+\Y2Mf0M% 2$ufQN}t rME¦H4WMM&lӝǶx,kp* zQ $OE4 (AQ|Sy_<{1/AP2c聰(Bd x)5!E"O4]Z ii8e%L?27߿5>TomWW[M_kj(O܌fn)cokz^NgFoDAWj}֯Ճe}7wLd|~|kgCXq Yۨ%6`l4AiZ.ݛyLdi.$@Oȏf'󼸏i..cE7.P#:ؙ. X Dn}M_Rٕ%Ǟ.ty\A3jY±h"wsQ:XSwPX*X Qmng7ds_Hy{xʞe_W,X]s/q.$0刼E$e6HӰCJ{ C.kc= c -I'H ]` a\[iQEݞ)ؐE!N.P蠦;}Xq9VAK]䭻ZFDwhfz fT<Bxcz"\n 烊C]L^9*T[tL Wꏾ|rj~.D)_8},?[>JNִ 5?vfCW NO#V.?>Y`5-׵OvBlrH3h2LYI-'_#|_`a掓j5OI6"#>9L_o R3}+p\d/o3M$m IDir Q(zJ0hq:LG!ZBK3&BI3h],-ڴrI_j 7$pG8Zsl@$g]98՘WhfhB!LS,iy^X*|EXYi1<7yJ8'9 .²X'ͲeBnr)|Án? <4`Py*\0?N$]AD\}FDC"]'! ]'6S%xC.`^,gXo $qeL a0"3@j~q¬!lJAug8N/-sIUtSmX.^0{d2/@Iݥk-%Ug@ H%ns( YCZKZi-X%}w{{fWgE74@aC}kQMڞ 1-ćr3m!CE@zݶ] Dcdaæxym Q<bֲ;nO 8-LL=-[s)s|OS꠻b/Z4L /,GQcw>ˣi~ ~N{,l5ϋ{PwN>*?4{\ p͎h{6i1+f=dj9Կ#hy-y9fR,,ob46 FM+B%*iCxk`IS;_p WzUJ|f7 FQҀJe2-xj%F']!W?6s9Ĭ "3X14vdc7oo:8{{6éWv׏61>X,p@} vz`j/@eD0;˴_i?elfjug:c٪U:s4M DVQI8&26czW4)%s5(A7|LW<@QhMv6_XM:$Ʈ+.V =/ò,hL1&ό(+N܁`E;8V݁*ޭy3{HWɛu_agTzOl7դɗ g@1(UO.(۞q=>aeLo%ejMw{\!3l:/q#-H3lM1|8Y/} .T,T86_"QHtR#ό/ǵHv'߯˧[LY.2xXvmrW =\GdSr@#)&Đ"xF4gt?bN1%v0~:UU gTH_aDT1̫WbdYZ;$[/ٴp|~.E$3@|FqA(N5j`g4ђe쾼׫8U"_/-ܳ{~ J; Ž<^>SVNxcY9cGnR iR۳1x ]K奤W]IoR^'/> 'гZrG%J"+[iʔoj\RׄhXM$":Mes4=D],?U`AoT{@bA 0e ̺ę6?%<)ęDE8 BrKOK%GA#)%:H\%:\k^qL9qy6w  .4H3LZ&ƈ5,&kb` n`Y>XhG[3(yLmUDHbYuPVʆy0PA2AoxPeFJ*;ʋa[\M8?@ܰ,S'ݶ6$_&ˆTM22$oe.%\-N8 FP=1/3!TZ `۔vnO:I?ao!9FM e! 76a=$2/D|M _Ȣ0B5J{ų1ý|x&֧A:"AO; n,ו?:[j:,9 G(T"\9&H| :ڹo&~)D߉dqm`"/-2$YQK lplmYO&_&ug̕/2jj CQ(UQ/ Ę jyPfXK\@W:^lߒ|=c. 5TE A!{tK #lov+r.b1Ϡ3Ľ?H&gzk:ٽ:_히47%*\ibњj^z6 >v3pw÷}#t]3 8(7Ј!t2{0rwl~eٱ2TO $>%:ѝtVs(5Q6_Ԁwe$ V5e2/Ta|XE=wvB=^{*X"ZL 0Ьf`﷾vhDzZ^MZި=TwkjΝV *[:[Y2ZmHg:cCuL(IX]6ri:Ck&&Ӈfv3|):/d/`G,M*v,(XKThvY x-ͽCPSϯe4=.$\6$ױY(E*TY! ;zv1͗@$< sQm{c*l{ݺ@*e-d`H \) M[ ҹ 2 6`ٟnp~FHm'tpuqV˧w BƆ/ȴ8NUC( A9 R :ӑEHÓ>!p愔En[{w2/>%Qr㹌)B`Őϓ:0]WSv*Ծ)NQ|:,^Gi;H7ho*I|䒮7IVXGK֒Uoe 7ps@kVYLʂC\WW6)ѳjh-[=d&$'ǻEѸ2}?(+ M[&gShrÀh6ysZZx$^S˫)e h0hGmg?/+%*ڃ(-^9d2.i#05 W'k j/zisq%ͻCsّQ݀N@ޠQh «xjNAfA luFٲrܢ䬩e}cZ0i(| l 2#@!y: y_ϮVJA_A< Íse;bHh$[ fy42ivtE?{:jގu;;~ODyD̷crS.iu䀬(QgXGi֭x,GPN #vtW2A$RC3_׏UGXQk֣ho!h=n=K13--F[/"g3)YBmhiִ< *ȱ)5MчQMSl{EA÷^g;aYomk{B4#) %l(͢&smK>6aP`5Sb0b &eWl0rm KDz,HQNŴ? XzE2,[$*(? j"tP!Қ\%]yĉ|d{Go+|~u}.\:,7m2t"}~dl6t"cp}z}\ HfT;/V~q6 Owf/[ʋXbDtF3ݑ%͡c%eCU^ S Qu07(S7fh+3|;OkuZMU˻~Bh zh (rE8 ]Aku{WuVב;Ԃ)*gCyp)O3AtDL0s)e\-پސvzfAa®;]U:l;+ʺ7TjmC쿑`:P2;oCu/| ]M*,AP4txT11e&ppǓ+mˑÛS$lqC͗X {g-e1"BV׋L#% T)m)PҔ(KZnGخli`S38|HxC+^ϾIvDDVq$)pD_3)vcDAUnǒjӸ4nV~6|qW<(9:+$Y[Y_N "HF F@`1'r!W~݈U/Ze 2v pѓ%)_W|N}O7 z"w.>ŹiL>oz2W 3@q˵[.i\nIu mchLC:`N-?",X&N[ub-n}2AۨbMƚEr=d{HЊ^{3L&!h]qCn݋]5^ĸj{TXMr]q^M\}Q亾\ % QށHݩEsگΤ*0&+O SLD8't HYKxV4+QXwP ~8g[Z8;m' i]SI];^H=JRW?ı|te dXފ: D ڔ ބ$ޘIj+7s2 U4mfl_ۤ.^'᭐Vr~')xN_ ̢i @<SYaZ^hV/'ōz9)O.Fwp}0u.?20򁈯l[0$<<Ӿ `@۞ 8E_-|bE~KK zP2c-CQ:WdBtEQʝF;|馳}r%6\vېG:8ZF4#N`j4 &Ğmpo p({"M}l[+ | И>}" 9D90<@(`=#NFF8s*({iA}UxNїU4J(;;ZYGgU1眎L4:;+btYguiA2tF;~DˈMW2rS]UZN(y&}$1+v3w-ola}!Bz'+!2mBQ|*xZn(Ք=!,w3w޶j5H(1㎰a}Mg":Z:S3G!wtw~ѵk{2;W- q{9*6l3ziAh7PHϰ:4=:6VUfȲ֖җRSVQ֖ oKMQ@9tm4hr’^ԖVP't]T*b!\m:ėgGMU-$,nqS&6ԢlS+C@9):o5[^/5&Nq@.Rs9j]b M|nN/!RΒHPEFm_VzJ D2+ڗ=I{\ỿ@Z˳]mW;"iJ wZ=c-IZK*` ,/BfXU\Z6 =)ZasC5kM$Jr0-y3wʼgIۦ2D,YzǂoPm P]KUL g&Gjۨ}Ǫ}T_L9 ?Z$4dpTՐ%r``jhi][CʞXn&'5^Zqͭ$=\Ȋ=)H(^DzI]( !"Y$T+E9D?|&Yص]{o1+v M2b+z_r'f!}a#q?ؚJvgԘW5UW%|!'yS.|7~ A7ľϢ?r]dSVu6XdvBD8,xz$C_Nձ;H޲|f#ySs$Z )X{<+%M1%=Y5 6moUJ5ʸ\BtH6~D,>}%$B@!C /RI}1-,tt0 7t.itaE" eç|zEdro݋Ku,4*Ҁ/j&G} O d-7ygT6FWU0J9ȳ۫Yf ^Z:+4[S хe؅ޅt1>p"1,LN+4슎sJ.]nm>KXe$|ϼ!/;]nz88+p.(JIY\ŚNi 8:VqG_OnE);: @t;)%VaK,1Cz`7l4"D{odX@˦uC{_O+R" X#F |joH;C=d>6^k5`wnɤ;u,0dfV?'Rc}*Mgn݇:$Xr'rn*&g{^z`!,%,4B9*bg]m(7Z9݊XeHԿFf=@fC˾WVt |ƉQ [OYw [ ZwLk2n kMo ;FW {jl]rLJGq CF" dLX,*ZU5mn maᰜ iM>'hv65!>P](lؿCTA$d=t@# 3b--lpPׂE}pHE7 ,;[:{`aKD=yLl=Dʵcb!KCNO/Ţ[sK-3nAqDeze SJ8M6X#QZ'3,Rn$[CkRcBVAV&T1)yqg]\ƛ`O?o?.10fC?K<tTrPAy EœK*bD9I6y~"SuO֋'>j$KRwTn։#抷P4tL&+=xJcB^-LtLO">5ޢW"_&E&!).nSyx X6 ="'"|X|Bh< SoWucb?*Ǯ3%cNs~d+3HAdџsٮ3Pm?g;u䟰 E"wZ}>2N+LK.jv,l4[b="zFRYw+G+FϛPӍ F:,709%|R@>1 =5rG'gr1_Q 7pAo^a#d'*lZɂX> {VҙwTb0|kldg^Vzz0xxC 'm,^`߬)F&l-L}킨=Aؘۗ@QLBwq"r;73-z~JX s3|>װ3,85'jo-g8kk_~j$<=Ñh HM{,^hx?𚡉*a}bM.4V.4Z ƞY1"~"|޲M4+K{[џ?zݜa?OzgG=3ǣQq5 q{&5>91w̨[HiΌE@̧xH?2ݭ#`Ѿ>}ǁE8`dZ|[tcA.(^[C&xWl[B"3˄zV02_9-O񛚛F1@` & K?_B0^ $uN]~rN̈;/̰Lv5t.Rp' jj=qɳ,iX7(qgܴl&Դ{/+zVXf2If?-"iw]:W>Ĺ s"[MVwbSϊ@4Slwcjt|0Y㵓>oNR%PTv%}1%+ϬjنFKZ<6DTZVeR=o[7M@8"\ߛuٟ:cLB3զ6WIyԟ窳1d_͉X(|/jWNa]~{SGeL&AE+_ŷ$-9{6M֧x/4==(9`Øˎڲ1n9{A#YKMƼLYHW"z]q}:~_f3 oG; #sQn!>Sߣ~;l~=N tPzԺPr η)4˴20MBYSG,J_ʝ:w"k N.͝d]ȭO*K进˸ϿN&I:jR Y"φFyQм]Y..)/I.Gi6 3.+Bsl`B[YWSDqX >rpn|@KC%}Tj沓>-PP2〶*}2hQ7MGU7;"k5YQշ4^,UjiZGzՁDdk*bȾ&}0. pU]A7t)̳W@rdɣ@l[ashH\V> ؁6 ʭ&_A1 tWvՍ<}G$Q{ Ja{婦-N)n+Xn!J>)9|QrxE0KgU;wa]O6J Y#&)p8#_PՉ:|= `bS.v8 fS -lB=T? 5=h@ى84hIvFcVmCy:@[E6 c +72ǫ/P`8 B(A5pma$mDe.xZn͛YCꒄ<hm' V@Nt(_#Tcr]mTG5Aì}͌*{?BIclLfeIIGF՝X7@DS60- _GnĎ+g r oM;wA4U*P s"(L5_^Rj ,4vTnBv dQ\1F H:لPahnB 1wH? 6;qǂpiowLJb~ؙ̼83*BPO`B ۚy+$ݼmzKSٙoPp$ymARV (c!D` bY 5XP`CX=!9(cmdyR-9PTyP+{Lׂ-;~;fϑ {rL<`5iMU?~ Ovy[kv~-1N}@s'XSYvX5{ۗ/}yR?%J4ҍ'C!#8\/ӡsl:NAy@?"kVpQT/j@"SmbsUALԡ}(1rO2m0c^Ek[o߼:LtzK؈B+xDᢃEQ$~"m#4@]omy`h1ջu1@lg+0\1 ]Ov.2 w.PGE83c!M{02%##y$# e0;_?~[>nj{*@`Mv(A$ >X^P=AGZ2"rO4c1" ["x*KU }Q͢|^oIfGS3cB:t]P)..\4:R(>@zd#Q(F `rͼť%fEd2 mEcZ؉? d#CŸy1c1.3M\c\{jRQEɐ@25s ubf«:4+o~urff1 D,޳Ի/?@ ٚu5w&wZ=[m(~H(16"ڃt5OW|gf/p,SECs֕2=[c_GoX&?[^0GUehlU4ڜ M 5T4XN+ b}r Emv){^{#\mG=oWi|}Ϯ:%;=Ud'Kp t /Q)$=jQ 5$MUn3@Tok%/l_ `|hgz^ n5V]Y.[ٹ5]E\ZΟ^.|ge`-?ċ1P,17/׳ʇ$+g7ٴXdyΰ$[߷m7y'ki0s}(DmЀKdU`/Ǥ(nD?) >Nm 5dd,:`k_~|/RG̤Gb;1cPןY45^i5 Nu6)YO;wdoy60zd삧݇Oetum%Uxm]_ 80\T͜Xc<_*a#.ΆZzC7=c߰/$o,)bӧ%FNhr:n/~sP*)hC-I-HlQL@ A %ABwMҤ0ۏO"`ԅŽ<[0v}o%LYW@wwE?7H<7lSv=_ld ` sitVk>*:M%E,ԊwH, {iY+{xs|[U۶Lo_aG'wΊGu1Q1Gca @,8%3'2VSϯx8"XB^.0]4h34_PJ6Q=03/fn95R)_ j(<4m@*FO?\y}-K|s-Mߪeիqt얏̀Qml}-*Ǒd/,cnv1Ct 3*-eT~F Y!E6?&E^&2(uIO`{4ƙ<:[.%Df`JHg; AuC@oytk;|\BtO:-f$kH5dE<'LV4,_*m_Ol c:K(n0mThlㇵ=]Ciyi,.@wjMl5xNc)],( |Z&S`"d|X6!c{PҫzLP]QMpu, !N#=_=WxO^P$b~Nq}*ݺ__mBًbv9dIg:0f?74|>3BmnGGGb$!cPk@C&U,-IFQ\n p" LPs`Si?6l9%L;M`Ι 60TE',|ٹ<_Dg/ @H)~G`/v=]l " @l־jiaUH^Z>@5w..㭟)~ ,cJ൳w,?#yd_^N-FnNbv,`іt#bo#$Zq!&@V bri8. |uMYϫ-!NtwXh̸"qԮTlW˭` 9TCY2YzG,CIVVo;D".@3cd7X-Cɒw*]sTm7,mSB=$x@%|"j:SخFE?oq34fa5PE 4G.P%? bx}ʒ.͏o7yVI'@# `‰Qrc>!U61סOȧv' \h|Z ߎz4Îqar#DffP剠 dd?rM0ldJđC%T,Uz%+Vm+#;]geVNәYФzOr`T)Y5MB;ê6@P~Ѽi0c4_!jy'zXfa1^;&L;Z&P2R|LA _r.lۢKB0`դ5 ~w#IΑ`s] g'WB݃HYO* A ;^/9 4yD^X*Z1@ntD Ӗz7Q :BDdY*mXC\$ӆK1a `F&x_&e {`2M#Ė33jDLЫA%:'BsKN6Ƈ%\3@OŽ m)[}~WZ3-,$Ռkaj>XN}օǁּ eBQ5UW8הKm4IMC U㍎^XD^7fhwּ\Xη@\qBRp|=n]o RHG;ӬhC }p>M8qpC>C6!!&qgh 86J8 0V3dgz_5<3 ws\~.?s\~.?s\~.?*davix-R_0_5_0/dist/abi/abi_dumps/davix_0.3.1-gcc43-i686-redhat-linux.abi.tar.gz000066400000000000000000003745001257152637300264470ustar00rootroot00000000000000_Sԝ[o8|~X N`ɉ;NNNw~SD8.x9h:\IP'ӧ/ͿON?6(elPq7;-H ZzWC[pUO_~&?}:[fIBőc<c+_(55ag_>Zx?__Waӗc s_c&?OZS7c&BF/Z9B u*T#TPTݿP',=Szw(ˤ"r.8Q2;=oh,EJwF EL?S[wt3:sЅy)ʩ`㲌B7 ()i?{d`~NE5L/[?m^Ol=UU9C3`Q~DHՆAzSy,ϫ}2\VZaQ8qi*As,IYSq1){4 pۀ\glB=/~\F$W=DT,IIsA%UzzjdվKƕgAey~/b^r 222׳~(7GnKԝBebf!uZv7]my24n(!W0/ 7Y_`NL2pz+J1XO*?lqp/nҝűIذq34|i[_PGr:J.n-S?)l lF9 wM7e즭]kBvkBv닂"Nyt1V^z/aǃey,+h{BWušټF Sr7l֐FkHZVۜg͒C;%Ϋ5-V+"LF)7?ޚ.U㽇n*M`i7@"Y!B(`W9h*o~_pC,eF}RY7P]d]Q)TMYk1B=)'m> ԋl))mRZ)v/bvo) xsȑTag|R)U)Ƚ!7#UcNTRΨ$&_Ume^El]DT*wGUQ=p:kg"nuIc'3tAyzZfIfIυ5Sf -K_+#O@rzK癹7)UT(T]N6re3#s.f\ukRc>P|4WuBPHm/#G)\ǙZ͂V |sn`ߜ`v J.|EcayGsN)nnB{L18ID >wD z0!6P"η;q3Ҟ(wDmOѾ1}ED0ZD!߁QDDtNȭADD##9lE۲ mۆxyvoC eD&='j״^Εy|TTN5P{jl:ՀR;gĉis)$,; >p)):Uz0=>r"C.XdGo;8:u{Q;UO87wv4^} uy˽հC`uӷ~k/ J ^ 7F(Qo'z!گv;sJTTX^U[.>ɃO8(QP(sȼ5p"Jl桇ؾ$c0')?*[N𑩿O7?]: B|"I Zm: \2jvb ^HE,-&|jSVԈA*eAf(yd3@1!.\i6CCeB%yfd&XF%%m"FU8AUDrh% $pnu398C+ Ȫ%,P{f R(s>KԐ@!F43 ((ށuP:ZX *^L\V̦YBfS*@K(PPBk.)}8jr"DJD 5Μ: PGz Ո@>$9iFnz 8Sݽu Bq#0Կ@`\7fp>>t4w"'CDlJl)A9|+86Qh=̨ 5Ԡ\hjYd [:] OMl)fw9}T(`J 7(i]?[ q@AlC6 Y<ƭ`ȂɬCؐ :qvtss+-"EZc  Xd#$R\o k,5bYh҇N @ GqϬEqYk*2 8R#nXiR^3C=PYx:ǩEvkAԞ b2P[[B \s(q=cdffL[ȓ@љ#WW|5bڡ nW2Xk0649Ocl7 })49ە nA,Vu=mnhn$nDnK[&v$ D) FOA` tb`Kh3zm?> 5 ҄ h#>n%LhC& ͷ_ws<2- 6LPGY+H~//Ijx͝820֑`chȸp\e+y*ń `^KqDbW8=+LFY*aI22aߩ0pL"ƙTl:8r=fOiN ˼'XTH`cpZ-㜆;T}2 2QݶyBMFf;ښ\~DMJ}h"E%-hsX([̫(ͣ٭ okvĘ eSsm`MCBͻUjPFtS7#@ꮯ`nbe&Ld+LQRh{DĹfl>y"A,rhʣ/8WS>e")?SgĮQMqƣ"M}+Pǘ,1y.qezXΙA9h.Y j~\M ReHF ]_!c8( 3fÈɈ%LdKDq8J-QHh}j1CiL`«+ fa*aE0H@MN Wep36;m35Y5GݬUҀҁ=ux(ǂx0GGpAʢB*0Ͻb+I4Oӗ>r#ǔ@#*XV ))PU jlEP%l.Ym)VXS('"._%B \U"T#?ѮT(aَvT(-_"JFptTj7j|fƁ *%PB 7KIb&$hWBӌ''9X= RnHn9R,HpL$Gty^2Sz}8SW,;b 7^@7VйT=Utmx 4Tsk`ozx"R`U9 3+%=D zǰT6Hrh$XP+Ih^;> L <\MELX"ZFP,afMh$0DNWSOd)liwKEvG 'L33PI5`J#`8ɸ@ E*89cg2&:h!314=ɌHp)%,)ձL!G ̑kE!Sbz;Bޚ*׿H!FK\DS$I`}%|Ը= KE-iZ7 4M۴jWȼ_ݒ.9~m8-vbݐLc^K,\Vj/U$K$ᄉk 9~i 2X!a+$\i87y@IDN%BKD'4'RB>U!;`p ~/*,Z ,v!b [v4TYBȸYӜ4S7j򷕌0 '//ܘۧhJl, 3cVsi" Scf S jf-O2 Q8=%tmVY|3G?mrGFv6Vi5"{k-:F dqC DRB8VLw-s p8 9w+)^O<ya*v+TI.}KKr{GiXe^_|(u +Kڕ$Zxh 715Pa@Z:Jʹe+ŷ2 0Ik!p._$r{TU!a,7'~N}e .vTBYڇȶSJ`[2H7qԏLBAL{iz, !"q͈OALk4HKY 7DNYK؇$%ZJBHU͙\d&S%7UHI \VEJ؏D  4%%FAP^d%,I5]0l25MP!/bo؋JLL.8t3*ȂDZR+gB dp0},$,g J8cqQm$f6=2W:zbZ/©Czs&έ' =jL! Y2IZN,#998`>=ΏW-fѸ| @Ky `+ғ$/oB*%!/6tfx@y f ",Α"R\yE}xzҚX|M^:Q0'-xޚF>}&ՀmKSܭk:j`~;aPhBTЅ'K23 r,#J7mˌ@q{) lA])@9]p@"6GFGV &E g'bj(Ѽ7hx cK2aP|6x;WfaW p$H Q5.(* ]i6 1ӵ6MDFn ҩf,V0XX5UmeHAQ)S#*h21 Lx KO4ܞ r2u ܷ8)l!E"Sݟ )f FIqiPM;8ـ4 #Xt-9 %1S['jV7UC®z!C O*|@sBmiW0"A0Ks0@gsOa[ANPX@(!\f\7VxN@X'1ѝFwH$l 11DW>RQAP"t)&~xT FhʌY-.V p@r&0[ aM;ӈ1z)|0X $`("\("~TN#Ԉ`ʡPÖSv%jRK, 41/oVAd œkuZ࡮ 0X`o,/bR(4M61?=:^$ulL$TPfH؝^Z xot6O"LjZf,6e0_f L+ I0!ABGa.V;zA[`4ύLc8q9vbhTeFWQq\ pFg![=)jsrPCbR]6H+2I0/cyI`9b J Q6} \@蛛0H )Q0:I(`(?ºBUt2i d?r,hC3D3 &@B/o+]k @[F,&I5.X"C7btP2q!yӹL2e\%kj$ .Qp0\pb 24i^ ,h`"&HdHQ@7N7`Wz8[%B%-F Y q>lä 48Zv03q GpZ93T+0m(-{p%ɁLiV#: p=m(p%ܘC'󧶉 pd`5Bxzx*3.`Bm}R@P%e`[UJh+FGg"XpQ~&0s (ӗ!*t1Q, y+Gr<k4e (B^bli,o~i0^7|V%vyj2B2D@ w#.LJBC wc`I{pLXc* 6\Z@S,8慴nh*՗0~en(}̧̱@5]`] ju¡xl J]PEX -J)v9 bԋ`ƹ8T̊sFyS K$TݺUFCb(L5mTFTӠ}k%*+'9[,H|!aڷ]*$=|OPB.߰q@9fׇ kK.EP0*+ b HFЂ}qsVfWE BYM3=?r+uLbX㉋4;~D,xH<qZhTMr,@MŪ&! Q?{hkz3INS}{?LI2{P V9) V?[+ڝ? ԵoSqmvw:YW'I3㔀QBkB՜arcLpaBfx=+ -s<0LEN͑&t9R{ zh=pV(=_Ia Z~1W|{-"$?ppz6Q⅋%$Rb% %! WʒBv -!"k@S0cx˷pSq)$U)QE<@ySf 4PS4LKFBӐIХ(+'68ʕQNd5gv eG#kl(nQ |ױ>rf6K2n2PSpHFC2dD5$1_~Y BV2$% hY2JK*a'wET:lWɣXl)~D;v@*{&E_$1cA.lv- xs: F_+ /M쀂 hG_Dlcmł&e=`w+52S k\bVD90\Q/b&InFK`*U8F]^l@*JYA$f*F U\FHqiŖY̅Rds=pQUA͡ HAvĐ'ԠMLG6y i2JE4!@auq,Le Ǚ;] ,50]8ZFS)Ȫ!jf"bca \d4tʅ$ CCb`/f-!S\anp5E44C$PqwC%,\T+q1 :2 Mh QC6ʪ*t 9ϐȡDԌbЭj`1 !k8*{e%C-T^W0 'غWh_l&ԾCȞ$njV^l%!n곘qy :ff;!Fh k,(C}MZ 9JW2R2 PnheX&E*H3 AZd*E[|EY3M:U zJ06H{7pR))Yt#p7bYI^ɝDZO!pau5#Uzj` zB)Cn)% 8t;aU Ta+fu YCK jx4}BlcvMH L&!er!<\$jː 59$ϡ?څET+Hv`%`DI2UYbjB3G$_?kB1dIgPv.b t1 '͑|HɋE4y0T#R*%e4HDZ@WCg{u3rI $Lb_}Q 㡲PG f8¦8*يX~`Bg@NH'X#? -\tCJ1-&ʫ^cHb纫`36Ub\p6x t"η5fi >C]@X!0>p`4,s`0 ,0O`jdDzZ] uvJG-mwp݆DP-38 I Vt͠~hf`*$l@tzsT>uQmC%fIl)fLX!mFscJ 6A dH%Rg[ qОڙ}")g^v50qb&ED RK*ӓ̐rKq{F`ǝA:%,JAa͠P_ZoִtNL(ƌ -m"b-hZ$  UYatG>$)íP-LʡԐ.l%fm"Ͽ鞇 #,2@ h@LJ( m2Z񱳨9QLS;f ؁1IpL8 ̉,ӚP=uN+CB 965{JfP5/(D3it@j@YPha I7+z×Udp:WsEqYF `'eao xVxZp@|wT5bX}5,qb2 oZ~~u[T2"9¦9d!`Z^]nerhq(S\傶?rBZV~~[vhb7bkRAv_%%c̱C[Hҭw(23P; ( e `fB3Hy\$ȽMa/.CMAz3tGH(f;kỲ}09^UIo!݅ Sfd9G'C sxIP(R+ݧ2`?f )s1LDM(hp{ 7C|b,85]̀~:' :OL$6$ёTPΓxq13(Qx)RZ:&P7c|C'UͱfQEƘ+9/@dREAHu=V]Vi&J!= TAyQѪ*68ɶc& KcKѰX$y!J^0&)J(垯U|Uš򠀀vghV$B:<@SC8: zm9G 1g3b!7 'qϜq,gXӐ{MǦ pxkL>ƞL'ʞX,(! ?C)I4ǴrL4- s-mKAv<}H{Gd6hRYC"x`3o#*te8^w]gg^#"E@K,?X iYodSu{5cb$SN`1@jRDvO7plq;";O"Hl V´vQ-p LAٔI7&05N$*&fAHb!N@[)n19?esߵ] Y7)" #9?"ЋC/fUKیnU j*&p}̃:i„ Ѕ-yE j&+p@-%C <2d!hK,0m Q♹(E H$qUC*$q 8gq Ҹo7H`I?}䞾aO 00%b 2igH$vqG ..7,z~ؖ!AB Lr(f>BP`aXT ME$`H*`P98aɁPcAr2[pn .`asBTD #Ty"4T13@wi ؜ހA 3P9ZfX[47]A>j৘. iDB51p 3d lD܀AAC5G 2<3(,| T^0Ԁ0_=\Y I ȇH/!A" r,d3$dōșsw,iK%G7=ȑpk[*ĩIru Ҹj9ZaV* cXA W5! zA<i+xWL2uSdq"BN<`a}c"@0|ތ17S  oNx>,t%43˜HJyCcL!H b 5=+ 7CeX?`ް_ "51_ q K# $Wc9A++ ޛ>! .*؜ȚW"`t3#o+{(oxYs ,>0E4:,ہ >7m;OpȖSixh/q~p~8Ht8E/w~a谚( MkYEׇ$| H?zS=K@ x#Bߴ-3*eaH3TI/L$D7LtQcd(-IHm'369aKU><-(E:_&G::tQBfA_ D J1ӗKA W*eɓv-DN|`Nrx\Rt957ruJQ \ĶH1נ3=%4X%]+@RQyE:fT(*ؑޑl=%q9^d#~@mطRO44TKO̗Y|#;R]먽ԡahq[&B.h-ٲs5[ݵAY]{ ^MBڽ+fn`xZcCfgy {AήFS yMT^.So#*qDc.9d!8_ K(lGW#ij$4Ml%wVPt5xHƳ⌢n:qB\~o8$UœFD$ĢMC Ex)آ*&Q^(|QE,(%Tibf(~nDD6.OOJpUE4~ l?m7)U!ݳcWkزy %V{-p^,}ܟݼ0Iu~?bF$i(*uXjL锅| '1 9X" 1 ߌǟ pY5F:?x|}^ x  )o'ǧk@}IlU x0yKb@Ch[Сs/tϏi+" W302u]Q)BF1 bal4oNlkHdc Ab ޕ}%pD%o@Dj0%ә;*gYi)M16!XB @ _2R ˯ O0AːIDQyGE:hq;F^0DNfl=ʒDL#ftLUF4D0Czq&؎mȋ,Ɏѱ.$=6cw zXD$FS!b|ILdWoGx䕃@ @I]&d8֧4܇O h6Mdͽ1~4)&p?%ņPnH\\^37T ygA:K O:&eͥ d%̖"$8uxD20P!"a4H8ct"G[-:yJO4R܌DÚYΊfʕ&vItH!T/'s^ s2 ْ"Vd!t)Ks]2NDAK%EK>My2E6$I(\zP!炄t#/ED$,)D )79bz![Ѝ~<'Zei_q%Gu8dpIrkIʹP} 6j,+Yױ\r WnC Es̑ WTS_:5}m#1qOK@,i; KhIF;&3m:5>0m5>0mv $ҨH]P.6'bn.^ɜ@KS2p23'sڃ*if5J؈WE/N b'2,&Kul ?K''J{|t GF&'+XmW t|O\Z#Q=b?jpN2|G"ADAsxɂ@0$__ANf߂7"4XJb1"SΑzsk2dpiCJiz촟NҮ\!\ݗ"[I 18RGIe"e2X(C'gAJMniaF4Rp ϒP. <OW! 3pC?b 0tCC ljhXYt@yCqlH˼,"*<<;FOz$GsJ@_AQAW#DDYHKefAk!("g#YM Ґl7 nxw wh(Lқ[(^ᖁZa*ZCCR^Y!uqÍ)c2xP # h *zFl*+/'K6Hj K$ôzuxزGIO'szF{Eޛ6^QYh>YBn$:M7WTRLq ]`? Is.rӄ`U*vB3e3W$v>2p҂[5ES5AJ j4~nFs p!" BYV_7IrnJkHC$ۡa47_E3I dKBI1,1lE%Dc[o29NGiz~%燋$=̙ޛ>9mӎ;z'z2b`isS/L՝fdC98B?&tL_!ko06qlZsl{3\v4iB-l7uri+T^jqKclCo;BLmʃ4qͰ ;sp~{M[n) N3䟜ǼQ8T˃8N+1)T_84zqнZ wńz~ iQ=ل{91wov{EF,5;!b`ɉk4IOE ~1dX3|yG˹DR,{+]Cg/ɿ0o! .F? DBNN {1ǻxj|x4gRK:mXV-Iۋjmi+>3ΚM|bE{ m|2 *bQAE-&ԙN|Pk u|н5DD<px. v[ay4:72 š.)ӊY옮NC<)5EV7t 97Mvvgk?~X>.GW>$d^'`TslH=һH_ [I~h?|5gix2Xk"-⛑q|Wo5iMXf snǏ˧/;#b`&n<+Q#@ G(AL&Ƌٛ>zO-u]7dm6#H&cQhnw5-n< `𢵤Z:`jCv܈ꫧ6k(ʟe1y{ՙ\gxhd-rХnnOe=6-8RWKVCc$7~0cnOtY="Mh{\0}n[ߛpjӨ(B'Vfvz?kfq..3_ yZΊXC=Gɏ':>]) k| dV'ui)rղl'&IqX:ߕ+h*ؿ]V ïkjГS'lkЮm ڿA+AvdRJ[5$X#[O-MzZ7Ikq[p =FoEc ߣkVOƨ{̫RS'@NZ @FgZ6cSwSY QTҶۂʈur؂vU96s<ݤȢ&e A8o+-YsGg5Oa5m8aLAe:l$jl wE[:C.x퇮?VH3;H CzĿ1r{1r=܌O Yh<4*I#"I%:> Y[#j&h Ƀg@ԝ!9-=9J XwSm(H?:HWBQ)~ѣES:YϦ) hzg#ul :n3O|{$-)ͽ#;1oE۬EHf?L>Q1%y·qW)Md=]ijWFYϏ Q[kޒ1o.eSRx*&f;X*yR x:e]2W$}\s(p "Ve"$U&^4wGߣ-'\ŵ˲. .oƝOHF.h?%QHS})>Ҹ`iP 4"wA: b]%qO`YzxA{xA~{xA{nbچeFq?;4܃HM D`QdΘtʒ^4"o; EL^ehhb_>f.޹w4iGlDiօJzk ~ݙ"B{/pRTH+/ۊ'I= ܂ijbEUwRuaÄ=QbrSӍ4lf9 5_Cs?Lώ|bRjn;mND5 R$OR$OR$OR$ORm$%'`u?;gYCwenLTT_{{_2b~~ӥMA0ϥC{(9Ľ |`;.  CyUQ͗S/v b阆x4 +4ڙ#8j~Pa i 3^Ņ  7}͋ CM8 ϗPY#CsYQ0}l7 TnCNo).Rר=ԋ,]ۨ9Ӝ9݋Jau}TDe^Yj v|/j!Vx?m7vF!޾(oq!~+Ckܩœ:6F.OG$mh 6x W uKŢ_bQ˫aհXjY,5,::b=E-ŢyX-pZ,u,uTf1}x=:0o|4&U1T;:k; /L~L)6]x#Ӊ;iĥv\i֎>G\d44fB3s)S5xՑ˽^TwoKElN[6wW i~բ &gC~7ݺ%w BbʔdX~BXW]:NflG❿cG2&_ 9q-k׌"cG$o eYh. $T\u|Ok#M0kl"Fw~Oi,N FJ56R±Rjl4c&ߌTܱY?Xr;q ݖll|1$8<=zl<@Hx֏ Rl+B0f^"8xƒkhNo5SDavlCkA/5-f۷o  )+5:mܟ$1OO,'/6_ς N)MT̼>lE,3@ Xi0-0'.AQ7`D|)4g&sSgHlp=Y<7LvL+hiP=(s9+@*#K 4^)!em߾١2J`R 9ޖ,W܁#ۿdۗ5L~%?4@L>+'Ҷ\q;9c,4\'d-Ќ"gZ͟>F^ڣ&g(m}Ps5,kro;z7vxK+ &֪zHOoI47&7o"*;?/,hfmpukNxF'[vM^5-T뒔{8-8 kC>Za-wݖzmw[zzϻn~ۢ_'`vO3ǺR8v79/# Ϋu,^uBhdlT@8%yq'cgB-9~p7+,A;#A3܁j!8$$w|GJ#{TM W.p #k¥3) ,#`֥%3ؘv;>S7/]~W]1?HC'QG/n|:.)IYJh7d58q`CF@$0M7ΎT|@$Gŧ*>C P T|z@v_eȹ\/qD6HB+I`}=G|+36-U5\a͢y꟭XD8EDETߨ}PHG "MO=Dt4?8I$][|hALbnAAE^kN MD$Dg쭃Ed.;ԡ{ DjpB)h/Sv|}I䆓"*Jӂ|8>@ڢ d)Wѧ'jgVgvP~o4sN1M bO27}O&+щo zdnGvJAфLԝۣF:i)M8U4xi216o8s 9 8 ի=NC4F#Y!sQLX! j4߀J;*k[A| *QAJk҂ .i`ownLRc 4xui}$YwC'uױl6KClL]ߌŘ^zHvbF C#[fpe ,/?t ],K07Y,/]rۙ92 `N) Y{,H<% D% 2|%|Y=?4nlˑup/Uhhy3GW. DP(Z[e!Ym65763YHo9E Eoy{4})޸?0z[-eF Dc( {}_0,Ӛh3CQ^Fow5Q]""ϿKDl::1_2{:|UU_9_:|UGJ/1J[cqUeOuUiqUz,*WTW\^b\WTJꊫVX\*=qU+JI*_qŖc8 (_hL?g=&5`·UR溛E>&OsÈ7XnGl]Bo?] HV]z,C6&N* 全h?E=?)M=?zWITIOY=}W1`6,ͩR- +32X! ѽ2 d-R"4 Mo?zX>zw #{d"hN)XwyC.pb;hYZt`B:\5#ˬa أf݊W&T;w*2{g<|5><+]䙼vhI$gJyGs?]J|A<i jPlwxjZˆbn~/d噋ף0uu11;4DJc Bm vht CQog4d /q}R*ER *~Ԑ;Z¯R*ER *sI2%(PVv"ڢhM2޽]ڎ)iAH8Mk)^$9١+ 74{dS'k+TȜ+]~GD/I޾hw!ݝ]Ght5ϡ9DKauu͡95sjPа[ʩD(f=]n]]D4 {X;G4*$4CBB3z>݊_,$q !]5d\Z `lx% fDI$q[t)b#4Kt8Ţr̜(nn;s.ĨE!m# z鳉trjSgaV܎YS 9,{͹2-jBTM`%mX@[t, { sk{Qz[22,khcgYkH+;ZKYg4bYβΨ6wiogYkee-{ ;:;6;˶fg٢β- .fgYk%,xQ;:+;K (,۲@β;: ,k[Y2;rN4By& ['RV,x!#p9cCb^w^wiͣ_[z֯ɛRkO }9ã!֯=\wiͣYZb&ms,iBӊӸk<=W۱grYؗe,seη2ǽ,seN|Y^9XL{u {"nn?!OnT]&yKaT?m I'yY!8N9Lm$:X3םyY9tfJ"Jw6eݿlp%Rng(O0Ic5"CyЉuCDm)n  ܈ǼDk&d}A Ž [dٲjۖGLj巔>bRKA>h/p$O0AWS&YűqanD>L>L>L>և30f0&0~0~0f~0$~ċ~CD^*-e(K#qAo[bSIHbK'Zsa(Cq{'Zsi=J@DހԴWhi:7Q{o1-ֹp_iw1Әn?l5i3i;N|wMmutl4$j/-QrAFǖuĖ [rZwly̚K4V0u{Rbv) jqF(9Hu1D1k.l|hZ."Qr̚K4VMaj01Yy=XVV(ꂎ2wb`h1Z=+mm`0kXUfMkVڡ%X+v(U(OnTHHϐH5THu TאHɆ,Xȃ*Y3Ȱ燋Q%rH֟$|9[vZrZ:i;h+7u<'^lpwa5=Z[pV{J_/:t01]oө_̝/~hԃ4\?t v"=TȘj펜7<i;? @Ό&eZgVմ9g>{ͤ N\_32j'ډ!bȨ2j+ڊ!bȨ2j/ڋ!cȨ2j5tǐ2CF-ĐQ 1dF CF-ĐhGV (t={ dkpCE:Ca"]  it}|04=ᐐX8H\ }ֺ0e! Yt|Yo H B>Rºpp?֛&cI ޤXoF7i#֛Mډ&zvbIKޤXoZ7MtzDs7MtzݱDwg,?ֳZ6b=Xj#ֳZvb=Xj'ֳZb=XY:c=Kkgi,ͱ;ֳtzXc=[gmzvFgzv;Ng-zvk3ֳuzXٚc=[wglݱ1b=FڈXk%czX뱖b=RZXXiXXcXo?֛Mۈmz6bi+޴XoN7m'֛M[zSTg7M5zSͱTw7Muzs\7[mz6by޼XoN7o'֛[-zbXo3֛kcXo;֛cCD3a+5zzVwX晰c#tFwL֙ۈ9r+ 2dczf6i5j4~}}}k!FX[޷Vbozډ}k)RXXXXXXXXXc=WmznFzn;N-znk3suzX빚c=Ww\ݱB-zbEޢXoFh%[-ډzbEKޢXo3[ZcXo9[cX3D|Zgz%lXStFw ]>n#;t.]/d.X\>Kǧ54.)XoDX/cX/n#֋ۈ6bX/n'֋ۉvbX/n)֋[b^3֋zX/źcXwR^?Kzi ^Fmzi+^NziK^R:cTgjRͱ^9KuzX/^zcb6b6b6bVbvbvbvbזbזbbWޫXUk9{^uzcXo?[V-z6bUުXoJj'[ډV-zbUkJg뭴z+ͱJstz+X_puFO.hC20>9Qlx͌_FcCWilot O6NG7ކi!㫋M⑮/ӵX;gqv%7}y{B=gaL[ _Amw~g~Nkͱ\_FńѸczZ㾈\Laǚ]ĂhԹ I؋?^~d?}O׀yH3ѿ?aclHVQ4}V7Lߘof1*McUDc~ma"Sm2Q * ͸fwg\l__#•RuQZ*}iR-TߐL IT-!I:t0Y`^LRd;TTcbf@N5{1msZ.ARϥqAIsidY=AI.[>Mn( ){)F^>O5yt4Q5~_j5f_j5~_5f_j5)3ca+!Mh Nö{vt[:_{Pmֽmۦ-i`yP߰% -mS6mI#Z--^:idF v]M0uq6QF6yF6s6L4M Nfh!46ҷGhlE:74fynh\kDf&Shl^gN{R_Lt% @AvyF:S u:\DtI-A[xFnj?:U(ɨA:tt;j, Pt2d6pQwOE]GKZNx1P'm'M5x2w^c^ k'a|LGu;ܹK=غLڻT=>o屈-a7펜7<i;?/ȁo;kMΞ;ثi:g>{ͤ|ofR1Caz+:T'RNf鸝aPsZ8r"WT^e #P8-QrH%!Şzujg-zkg`Q|XxBP_"Ѯ.yhY[x4$çνYmW IigZ?=`nZR“NG*-虏2@\r4SdI&{GW熽Z,oEBk<!X_9yǚ4eAkzT4QT dp?1S4\fKLmQxAtnP?Bw9n+?BSw{Q]N$mcNuZk ji-p&N/syJYjgPgMMyGStDTzZDS|T}KT)v y4UK'j XɣZ6>6Q4zrOi[|$.|sHN]6hm<| UPC=/|s%TB\J)PK):ʡ|)Ps.|s%TDoP{NYC0(#$"`9"A)3_-|"Q$72$F4շğh2 ǛDŧ->A.+\8M1uY(6L62͹` ?\~hR+x'r-L< ƴ B/?)lBJcbfNjXCcOh7/ 3caDp9I0,[2«o,l|N}3]fBhGR.$ S"&a Ys/ۿowzrg|;cxn|+-_'1 X_W3}Wp}0<_FuZ ~n<q,krmOh4v=.vi|sn:I=DUossNZk^LbCڪ Y~ o%3aa-l^eކ͊5ZX|UZ8D+z[{Bx+&^9W۷/Ϝ}S/v4}/j>;d@UҶ{ m;S}{[ގ;xflkg1a`3"vlh5oY<,[bsw-Yy}~KV^9ߖ<2e慍M7z8hz6FѼmnC_@֑1? х6!kZ1o<Һj z }-w {#= zv *݊5eY7YP.Է\MRV+v}5Ⱦ^d_%PqFM͸ a}tQVHm! 44@jj.ϳSa=J joe#gvb,pcڜjdߵge>I&P~ Xĩɣ&s7MMxjHzuG@ ;.<Xϲ(`=|szZgOmLڦ83|^+FKc%Աd^;F]bO5 IA4CGHrM!FiI[E44$9Ґ+;52?)IpЈK0Ws,;B\xK. w DqYe.E2J/Q2^@#<̙y[FYbk5g!5rt$\.M(i7l1Zq%‚N/m7Ʉjmk ū&e&D+j+5Pu<<b͕)Xu2G"s?Rk$e EjS2 )ԡFR.(@# ИtIRR@)|4?Sg L)|3k/Se L |خ:c$sA} иs}ދ`':͞GT_$>QĻ#*% 1]'sQ:-zTS{Răʥ$")MCsMn>L,]}BnouwpOיyfZZoD{6~,4,=_ʨ47߃RҟV߼BN}gMKjj ->շ9 Z[.`Sp&\NlYfDonrPdmOx *4Rh Ϟt癯s!ܷJH.t]F8Z;6*pj;0?T\~7>Ciͅ{l^:2~s^sF榍"b=EĚ[65wlkn("ܯQD]XsFf"bͽEĚ[55wjkn("ܧQDMXsF q\ӧC2Sۥ<.<郥NPwQL 9 C (C (C q}@CC`8Їty@fiJXܼ?aGn̜v뙧 1܎vCnݠa= X4) ) Wwv`>WJ}vci sDI YyvX 0  n@E XNnPi/6n6nЩV5kSg5T6F Q`#v!]!sC _vzO5nnPߘnô3v]KىnPvzL~PAyK|DA}2nnPn&vLDv1 ]Qs'mR!``&7٭n͡;@bYܻ37.C}R ]N?Z'Q#G/u~Czd.@BВuTKTvvvvҵvkkM-r -♆hCzZ@w\>8N2Ao/0N2AO/8!p^8l^ho,6Zm~њ8~iVdG1 ig2 3'$SigZ3C3Z|{l#yFM%3i-Nf/D>5g ӶCE5aD)8{ \rb"$3ןsHpcJ2ugچ9C:p f2d4|X:aY(Lx`"% ˊD/ ̶YG NMK:#4G*/NX:X`}bF+ x],`/2, GH;C8Oי.}sf(Y\ݳko?u.oAFrX']3@L{657W%\*byP`>a^pk>/3v&|L,|+ckL2 y}' !!߸F1 6 ~7Bwsf8 ? Ñg6Vy,tP&ɹ:$hz"ی_s 7=_-B0Q+|оA\W0s$WXkz/GeؗD<7k>,|3g ǻ1LhPbA{6If#/vbE([@w>1]l9L'bLםK6 ~:^b%Az6g;vq&V̦Edӵ~&f+X!NQCjfƼD$ {fa7m"RM!e}$opWbDbw]2.~"yL9!ξN$"7E7. {5%b扇B8!d]182d}Ɔ\&X0N^"M 2&wu{o_j2bX~8qld?݌|7Yx&j5ǖzF&%4 nCB#u;qef4C[O)+MW:w1M$oI>ionA,$O̴+Q M\ w_qC^q("UFhtO8e- |g)Y|+?",~0,[OLEG"Щpwg=WHr{| ،. `$44aG,6ׅ p}]8qF &,ģGl"EŮ V[>~O]?7V "B'2Yg zSfĦph @ߠS$e2, $^h'OvTCEl&*cHyDKMHcgsFIqf1wbl()+  TXNO6IxGM9ÉxL٦{q]y(BE7lx ~X>q8OsзXdi'6"dS2ℌO%#8gɯHiN cD؋%^ W{DS()_@.u_ˢ,f+ x>94wΘswfc[.@';^b}V ]:tb~$+f"&`oɮd掋9''T0#ǎm2Qmog@޺=Jj?lIg<:R+W[ ۧp1]o?P%_):M\Azd*ÅQ!9an)P$(en 'uCFAM 4bs9Cճݐ~GR-MGB?ew WvЍ}f*">5T[-lvz,wLsJl`F/JJ E,C*!4Т)Ky_c?lmB׵~Kh“k?B'f~}D ?7aq_LOQ88Og' ;T]dw^B3JR꧜x%]>Y~mz'xHLuJE'inN{K:Zݾ=[o 4w[|!"stmNQk(V(sfcf:ϘsYk1IQ_^GY~FNwy<y/pHP?(*o!CeI^U,weeZqv#LԂrvV|A݂ nv_>5u I5g:"3HAݬ65eMu*Hb|7@6׮ YФ(9~*:*4z%Β{y*\:r[pI:E_חl)o"Y| P+9Zű n8(9𧽒X oB/4 dtM^S 6plvElG4¹< CQ ~W>NPF r}B/γk!|QO,߳{DՒz8M%O&TSNJQެS-6CE*?!ߖI]G ŧ,K+m< ךK͗H Pk/pH:"%Lr8n$";.wB-8JQ.ջ"sxj+* 2k TG7î*kD3v ۹0 xvl] L4-M  gC~}`LKodJ$GHrKI~T3mC\)$#-o |Dixьf97$ I1F~I׫ lEHB^ XBgY#wE0ؚ<Zf4c!K}q\ AgyB+4DD457DPЕ],J P<752,؂+xT 'sg\/ӄz׶# (WBF%#@iwk!&*9,m$W X X$zgdU=V_E y.?sJL^Rg؄)I߹gTBWE'dHb!#]vu?G= ܄XR '2o7'd2s;W̚/KEM3uCW pz+D -~aXj ;fqd\x(p GqTqK(ɉ4lA+,UyDBE ®_l 4ϲXEc9$# !v?i9ɾ'"V4'!͑Iv!>m!Ѫ/ SnoI"(QQO`KT, ԯhJdU^QFSMݾ:\"[*=4$}w C1@1хEGz|H\XfjF5k%X#OL;K ޣ$$lE;:%)ٕA݋(t >+@ tO2R cHT%3Z`#p LhIJK"iId:- LQU;u&gMk?hi>8M˖PlD7d4npmcvJ_r c>X FIx]:x@AL' }]Ox/*8c:܋ d 0%9\ˈ(UP L3>>~^D@ɐxM /ˡzZaٝ#X"ó3s-K/a% y/1x%tSI\oo2gأWQNf4mIBa|r&?I)қ""UϦi+)gwP؟ =C~wߑ>>1<w5d\ Knk88E)JꁙĨwp~Jr%FԿE )T&3d7?vR#FQϠw%Qx.[ oKyHS|yGq1~?(S/  '=}ͱ  >R dh'%'rh{9t^,7~ W0WB))*shqWk= ~_Id AY<ļY\}Uq5I\kbk ,$wllvyVZS956iP b8ӟX;dal.ɖ+R*hIILF4GM^d-g!(j;_Prd dZChZ@q8E1IbL<>T:\=dOfJ3!ȟ"稴`p%O%=7~JkD >$JȣкoGTGj%,i:F]׽ uD+E t%px4L]Sy( $o|E]t_= %"̓3q+s/=":zkT[:?'z7u([[PQDO9R4x_%Jq7I@I?%%r qxTdoˑ3! ̊B0H+4${vVS==D|I+a$"c`wH:)cؚnά*E꽑-AkQ9BU`ͱ{ [ lEyx]aHnxL7,)oPpWJ z@ k[fhӸWWY1[T? +);=BwQz]y;+rʆi_$d6:ޮ/ld%5K~_WEX=DIfC$;fnumH8/_>?|B^ 8`h㒚ZWHںɌE. *]Țno.Ek NKrq8cTY"j"vX%HXaOx`BDp2+}Zlq/1%F@gG; 7u"r 4t\yK zu"j2m/* #$ho}_$}ih/;OdI|9 bM^5w{w`ڐKsd;eڻm3iv6fXh{b4HZsկ!Әom?AȢ3M*a\V*MP_b A)nD l!W?"Ţ(&A܇@8̅?#A6#Lȑ}TU%ԧEShW8XDD4/Hס( C?"WI/dZ~N,tнrVI=A۬c?_v ǕNkz_;cp3X}H>̐bPXGJҷvBţ̀w :jx91^VD 73^SFOP,@＀kz 0 *$SDVh[M[AqǐMWZB(4GM)?υɤn'UΕlSslKF[x yGYEho4 bHEE/F5R{}O^W#Tn' Y t<$fX%έH!mjt52Q_3-oZs X%%ʛBN2MBo1TS`+Xم2[yf|!R^2O͕-kJ,lk\w}@cR{e%"ԤQ2:yvm )6$޿}~KJPEn(*px)JE@!R+`gyLB,Eiz8]IE|x0j"yk$LeLKD3 bߞ=rC|Jy(6P{y'Ig$"ރiK89WFQSɛJO&kj$fVfDXӮg[DZF" ';{+H:T!6 <'3*r7lZfֆMsH5O3'3ACV]`0:CuQߵ-k\״w]2{+ߵY ״NlZ gg,yxF6vb ٌ{^ˢ/?J0_XzjfWvz$t&qG21l5p=z69UqI.d ٚx; ʃ޳I255/&on+|<8,䡗ͩNVN8}ލlnbU] Uy{YYMv_hNqzouLD#DŽ0࡟|ȱ>ޡgxI:|3G~/O .N_I^߇fJ -D!WJxWc>LwZL||>v&[I->U I\^?gz#dILf"b M2ݠ#[ddyLfdlho2`2*dy2gˆ8cZ]g3|!j>$P9 ;кMyq軏<#␂֊ txr]sb+ %:YקPMx/D=[93^<`YBܖ^дL'&2"B(;~@4h偽R@af@8G8:m_ĒK2B$|3C>0iOE21F1wGPMwHtp_&ϸH%#|b&a%l:K3fEl2fLo)Box& Q3/qbZ3MUC^,g4/Ti 8=QwV?P>|\wLd, C\ I͉y¶2rќg[ yaɁObVcfs43" l|S+4f,DAe"TEί>ђى,ƿD7-Ő8F39)ǫ!ݪ`=3ki|*xAt]*G͉|W~M@NYsRz_CgEi2)&}C'-ېtS\Vy|Bct]s~7Cn>80-qjۢ6OP&-!bM貿b˷kiڳ93]Fa5^J᫗|b4;&_AfͅC?37T7?M'9{v&,&&J#.x<x;Cgxf~\EUt ˏ,u`iۡ=Co盨%cyQd6QzcktNZT^*G a`ex#&C_)A>~bfQ" s=ٷ^>9rX%&WbI)ǵsEosgQ'~5Kh#R!sR)KHp=g|2NBBڔGK(?8g^X&5Fr~yW}z0 pM:qkݴ XV΂LhMիA8y*G?i A߽7c"}O>>xCȘ w^dF1|a)-X,nQVxfP O~[齦%f<k2,EٌxgFqgL<4I ?9!=qmx4tзDAy7gC< 9.Ǧu@DK^ (%+bۣ%>CP; QiYfL;toq"δZ)5ǒ1k((}S@#Qk\3o0Y>>Yc| 7f 0l~ r% 4+1]J0,~,բ&fE!_!5*>nH^cSB'; *RB90mE!a_c5%a$\0ۃM:<GK#Fhyws/&\z,rm+|d(>F3mmRM~-碤}٧<~ӝ*×DjߞH?R:Ĺ4a [.kpʨp Or  xg@g(iv/Eᘹ4񉤡*0Ȣn2t< ow]M]3q)*6 KnCf1@-,_(>aomj/D7 _\$Yr')Ne>pFCOl/IĄ&Rz5[onS6!"pg)w~56 /}!,a"7`]ᓡeF\-ysr|T G?jn͜߷k"BN@誋4Dtk n /q&D%U _dMEU< K"7szx}GKGqO.Nu??|ċ.T^toϦwϟ/_>s߿]}S?M7NqƄnﻃ^a?Mدof F_><|yx~FƗ_[> 7?΍1q__Zt7{wn3e>-?M~_1oFѯ opsۻt?w]u$wF?z?5icvM_޿?G7kZ3qii Xf];gޖ>͛#iJ](pϫcOK#O+ty_o;~ЄЧm6|_|'.]oKߏ{f7G~6T?e䩚zMO aI.1z͏O>}hԲџF_HG#>ڞ5~ nN皘ऩ*)&~So:ݛ ds?g_W}iab˝jbtm5\ݻn/һqmPzZLy9&x;@o~oCӭzFcw}dӇÃv8 ;ϏoF/o@}Z<|eh>!ig?goiSRWiiv?NWc.IjS9O}`ϟ6ƞ_~u32ҟ@crJu?Kcf'bS<J_ +=g1c&?fDN$YvNb?9Ou_+s8Ai['e 3q`N~7uSZD_#</6r>qx|2\/F8|+D՘yvSB8s8gފzbs |!^/BQ?_rl=Թ)wA`=~dVm 7#zHz&ps|_~fv)N 0#>9nFfh.viF[ӝC&M؃m:+;PD,b8B;9מv.ŌY?o$٧ _Evr ߓ}VQxk7߆3u,<)*sE߾5L,yZ:oo|ol< gh2*p~w¸y̗AC?]xuZ?xo<3OU%F@$ޞrlX/* n3G7}L댞6{\wBgTƽqn+ܵ}OB]{qxl[ nr}]5vެKȭYBR f Gc_ ~a{ Q r4ż ЮAAkpW Av]B }ӹW< XWNgbqz)&U{8y ,4.P@лS6vf='hx(7.\un#sX9vw!E^Wܷ^u Pho:ATta*vglf{u*nVT˪!&[r$_|Gҗ}Y]S,hz,SFvSZKmS_+ָ=h۞N-K/|p{&aZi&z@gYYwam؞p.E0cb; Fyc랠Yq69 Jِ}_QuCHDq7Uzn;/* ,xCnPӇ>u,S8NwN-UB;ĭEeѻC8p;q+Nk=^yptߚ4<:=]4Tto<E P%Ǖ1b( ufVٚҚk!=xTjFs՝~ tm;~K~xgm> kC|(V8 nt+96%g=hRjUCG]&, ~7ca.Kݻ+t]kɳYSL߹X |6=h+]WŃߚe(t:_R~Iߵ_GQy1:5~7ޮ[VYےdԱ _ۦ-jB&0 lQax0hW UGiy0<嗧i*n=.Ið35ˢֳf[zvt= WM-zvܯ?ګW~xx*Om}9(×-Tנu SS]P2 O ڋ́ n.C ;Ӛgyʷ:KhoX!|4[[.o1vޭSKUPĈ1ZQ侯{/7᧭{p`M{aro΍h{6pɷeYM(-7/P"gPHvԫV5W3Ӻ^i/l.zB--zt'B3y? ;B\۹>,sw > ?I>,S#A:]M/UCݶC-.[+*~@ᗏׯ '$_łs~/h~kX ccιHPHms􋓜ĤJNd=Ul0ؤ{qad\&5-^M&T#{}cIDۍj~=~h%mmVs]N,ڢfaUCA>/.eJO)VHdNTHѮqEJ u[m 6*#/Wg;:l7EVa܏Bn2S }Qhv7Jwp ?Dc#Sw@G#ӯZ(ξg܂JJvRa_|4lwm4 ? i>eK㣪aY]΄UivFyt3^׳l]EAOi(hv=s=+_Ɗvgܣ}eUT"XY R1R qw7 } 9*  qpB;h^parzCHyRW ο.]hV^LU`ƅwD8nY)?%mh;aS;oݏཕ“ծŲzD,|cTJ7 _u8|T"Sgͺ .5l^תy_K-ͽ}_4wؚas,5뭜H qw96ۉif麪iZ۠ӚUx_$e YvRɚO7 je Jy}E=}-FQi+H9ޤZQ:m;(y %͇zuC-kw;hTz9yYAͲfl6 &`kåwuиُ{gJW/(~t+;Ûǜ:̽[ssȧ8=CAt]-c35 {'`C] \ T€u:|a|e~B,U\fYFi=֮7S N|D&xs=z)7*WWLU=;gx㒥=8T=D, 4{{ k7.}5mv/wo 7ԯx xotZgK@)!^V\: ^_@Z5[C 5?^^xZR͇gӧ*gCuf]o;7{%?6n^Ռ( 1Qz?fǐw;uGO7׳:F،:3pxZ11VȧNhoxw|úWgW+]Z<>SiX @䥡tmg~pk W*](_O/ϏBb(bOh08&ҙ{ݭwR**Pi:SKIF/mF{!U&x+|ǚ9&!m@eV>0`l M _Tj4]O*Kă?ֱ(X^#yP D^'/ezL(Db崼bV^Ƥz9 im۽S͚VP*\VWXNIq]΁uܢQV$Lu4(VIspm>r\i]kx3T҃mɃ}QShj\7FyK~}XMV2ZV+`d}F(*TRv*9s*9͌Kj+uW\G{p0~un& +dp?{nMNG(o7֯[ *Rz]i@[#0ԿULXb;NhO~A[/4AnB3;J_{Ne3=48?'NOgvts9g R|)-3LUZ_"uZT4ZT EuEuWբV"OT4:$qS暞hiV*/EC 7J%h,5,>IcimJNj_ڠ]>ao= jq1u)I]Oe3E:/QRcŋ`UīppQt. #U AXo{JU %ٮkہSTYw[FOv5rЮzo`L8_[/bYYe7 ~A% >ޞU-Ns[m*WMt©.Lb&̓ܓg3|aKݤwnK `oT˘l]m$$̤GѮ`oChD7 8YdxuNu0Jeln%zxX8aӊ_BR,ґ{ 1/굄ŹEs{uн0!ꅬ݉:)dsZ#1[?`ȯJhW%#8pqkU UpX}34 ;ItVcʋpOBV;gīQI+ ed|ݫD\ޗ DoV4BֿK6 ;5Hca_5>n +Q0)5~Y P]UhFmp A( -.\'b=pþrHM]NmP%\ (f?  @hV ۽oIhF nϵ؃h4Fգ]\N3s6Wz;ij{hm|Wn)[ϰ z[k=G3_wzUg)rGwtz*vYV:dX"]R.fŸRѿLw*WF# e1 ͻCnx8ivdӡ֮__h݉٥5 aΏUK#}PCdTuR,T/YI]Ѯj^q9cj']}SwZ*H 'DjN~hE<~֮FfDzFfx #>R 5 XĂqH_5RLW^/;z:+ԝ7cnzˮk|=#l/2RuJ1UZqԽ׻vwy]=ɌK_wy8׻~+\]^cKJCXXsxbٵ\ C &?qIƿJuμ_}&ƭ[>9hS2%)_? u!)Rb ^d8v{\խ'2>,ÀE+C9mo75^ ESzˆln@ ᶓ(Ȑa%uW[֪Hۃv̕>fF5ŀq(`(TwA_-NVwZ'yeϕO\;'&AfȪCX~dD4r%x+ez+M^r:X$Aps^p_,4_tչ` /WaE8ZǀaQugsax$i9V;'y7ҶH+ EbuISVlTLԛW(_]4xuT/.'zQՇ G$S!34qm0̣.aPΗArԤIƆ |!&Q$a4&D(KA 9_D2!Ò@>%=u,.89`IzヌC{G*]:[4XJHfڜ'Wk@\?l*,̝(`ؐ(Ԓ^˪9 7֣/,k G,TÙ@ծe7#gYU( wŲ >YF% YIq#9Nk`JI^,[deX@?:)حd}ع2`M?.npM s\߉ nK"'o5t$!D5<#G!.RIh-Lus $ B)p{ IxQYƀxc'SfIS{y2z3^{ؕVK%/&`hTK1,Cf4WȡˍAP][^ ?mU 06%lMo&HeʧZ"E6Į$ڨJ;sKY3Bp%2hۼI ӱ-Sf˔M[?{-&H&KK˛  nrP+פb+C>_E-W6nՆH'[mHE1jC{KgP: Ն' 7n8# ȣK7Qߩ&4vӛ:_IyMx,"#:+clN)6 4?ޒ-⢢uX)b49a7l ʫ*\Qk`e41])i퉵ṬLNDGADxD0Y[@ _橄z4K"gHGiIV=KIySz[*p\^l ~jwK/YDVwC\3chO] ?GSբRj 7,{KedI^J`3 GZ^?QEe+ꖻVu]L8*v2I^v7u4U40q^o Z|_SYԀ,LdwP:y<|L"4 X]k\^CF4s,k {~8݈nl$L5J'iu,,I%%ȵW.=*dH&DriHQ}L:\p}!=9m*נJJflǜJq~߾|=’K+7IQSQY .69ۃLY3y Xօ{cI~Qz$Hv(aub`Eϻ af束 o?O,,yx)jcD @uqe8*{\,Vq#dʷQĔ# S&eGrdzܧ\isy S3!0ܥ!B<ͺnoG9VP] /ɥ_=6^|cW/> }M1&I!\~5*G da?ɗ2xy3}- |~>LDt턉;K8tAyLu~ghϘ:gѴq*unEú}K}xnA4XY]uBZ5%ٙ^VlJǬ!iN9bzm>>tZ apC'v`u\ɖWqʫL+MhwUnocA+Q9MEj=:6M h'+"Mp=Q.kp#R8oGFgxO//}% ӹJy?1kQO˧y^=|$*B"@͙ŎbqЭ_,4rTYK1EMF G7̓0@S@&0͝ԋ.߂FFt4YKM K\#+75cT QA6ԭ|siEksima4Nw-\4hp 3u]1~,dv&a<"/i&9`F5.;ud5Jn{|><"wrD̀-rdܧb8Ka.9R<\.e߶SKXmI%D˕A)ppD0ld6f'Ldm oK GղUuy[@ܞBXΕUۦӎ¶X~Rb۔nī>l/xxsulDUty2BePd<>uom),OE3Cʓ=t^:Gtoa Z"f! nhѥq^ ?Z-Thks7jz4) iG$B!Mwf82y ؕ4]+J|S)9yBZ3fP,lG^帯bir^cĂڑ!РbS芄ȶHr&UuF ٓIϻ:p懒`Y~6n|CTp^Hĝ0qGeci D_Q7|ih 6!MJzxht8aI9 {5Y( ^Qtۨcisi a"cyjAIfae4oaMuf,\fQ n,}έ0+]|CRL`rUoi_t7KFgnӐF?-o1|2C [.m5V;H_웬Jl!(Kg3UM&Ncg2],ɜ:#Yu`9& a]'ZM{SCCc!,2́y$qGg?U+3=܁RB %2m>lHSZUR(ؼDQn)\Uz"BqQvPU @OAIviⴜ PH4Y@qVTK Pl/Ā7_Z)Ayry5JJ(a#5;hG6Woo]E(ST=l"n ϚP"bd߉&an R@qڜn ka:"+%XۮcT:Tj/^OYP N .MZc8$DzG\+, Ud$'%l8@֡}SJ-MqkP>& 9B$U溜F")mza&Dm)~<*Bڢe~5w|M/vd"d",Z- aA†-[2*fĝ,\.]È*C$8|96+bEd'i,rZDr'm@$G}r96OeR@@75?OB'kVa篨*EJ>cHbL3dI~?F*g+GH!lM70eFZvkVկqUp b8&Ӓ %qxGXHw3BH,XB7b6Sǯ{h—2g/e̳Va(ܑ~PÕkMwxQuΪ\#W2,MBșH8WBᏥI(I9 eciܶ1)ZTŹO Uzƭ=tleA*㋨=,e,LؕIPLHCe3p&O'FYxy>c8|GC:v!-$ OtU'UGO ?G<77U.tXCs} ؑF MLV JpT1b]IP,\sP|3MX7j؃gov̓hYLt6),o643o;K*>Pkߛ`m T L38@i-ǒ[$̂2DJh3r$Kplx)!7[irS #Y&1,b=Q^u䌚/Ռ}-wJA\2}֥mkmS^ K'џUg&R*I w_j&KgOQ`fHGӎ\w_l\0*i8+(m-ޚ},M ȑ{ns/+krdE~Y"_ryc:'d4sscBM\ 7TE\QkSk3"_;6 ,ڑo2Ybvr ZzOA.Hʠdz-\K-`)P{X .il~+Ob9gs<\Mn'StRQ1 /K8cZZ`  gri{ṕ-! Qb||*}xU S?'~ʃ D j>%Yx.h.TC}ۃh3 nh4ס퉹k̀ćM;l`RrcmHK冬oHؐ |H#óu:EH\£)s$0 0#%Ё_>0׹eɗKH3r$<|EPCSQwWmWJّlKih^bϏ?ϝP`5rl y>MispSZIؾ0@T\}4~)Q8 hX@,pq*|fw A8@iA6ӝQNhԅ ="7Gph:i<kKIұC<.gA(AbcG_BDy5iz6tcM5|Knx)vl)FISO =)a]QK NeA+/^2Lk {(Evk;/ݞe4>BG9]tAl[ cow/ߐaD:$Yl0EI&uS ( LR %*^͛?"f+' c PNpc.Mp4ed ]z3k8QS%hl9tE,Qžq1^؟9jǭѦzesx:gAr݁)zI̺szX"a+ g򫩸k¥lN&rM&BAʟS7X$@ _(Ch Ie`4+ f-Agq4a 4ȝT$#GH[f}{$X.$d9I{3A]jg?3 Bx9P_T&) -s3A)0ӈ%],%M%Gw[? @M 0b-@+ O39zsܪ{ٷyf=fk?$ܿL"si2~F0,"h 8E߶Y5`h-> sglZVN#:*B \E<.)4YCXh /S!zxMhw壺@lrJEv/ 6,G@=l6C4 q7mwn8 h/oU 9-8j+|x trݲ,(9]n5ƲWJd3)ti~&vJ6:ìnPƀ!L*^ydP&aS1EMR~8 Y/QCNaAրpv*+$b/d*ɰ4 /Wr!\T4=J.Z~ua$Q2CmEmE͇6uLeSS@iwHNpʨ(OʉO;IPo#q;B8 TFqMwz.'6 ߅z 0*Ed   ω-52}NFr8Bs5)ɛ |}L lǼdrC@ Ԡ u2l۷`orVvS5hs²r?c<ͨoF}?hv/}倞ę 6WvpDSݵG5 M׷yQ| };}ANvik nKRZF4ޫ$XN /bn]q}47Ш~<ÙB+4FQ`Eɴ;—9߅4]䕢`!'#*JmZ3סnB ɐKCȅ3[\8r\8C.:De ]]{o߂*\@~uWz>-a1.0DXDa mNND]D.Fv"0 ى#;Tzm U!:j[N؏ǝQU!x/?ܪ7[G?内4.E Lp ƚfބV+ Po~[5f]VJ|#_:^C;s_>-͠<́wWWЦPLZ'yeABYd%4d9 Ȭ Kl';}9%?a* RP :&w+F/LL$2rQt3US>L˶Y[ޡE4Nyf.yP5j˧000l& R[>-BMLA@ {s#XtwW*-ts P~ hEj*0\'Q8MH' 65Jvl=.).wm +mͽf#KcO|@pjCZb?< 0/=B!:D)tnǁh !ZxNd l-& IV~ٖ fmU4f[={0,GRe,{0ba"0 ['U包M6Tufdnrw@Sv*?/A2fO1`_/Y-/b/JMwl.Jfh=X\ mu\'VT՜>/OgF.=Z {eyUWrf~sž%m1I' ¡=l\D\dûJ6_Z]eήIvUrq(0oLFA.xuH^*ysaW]U!v ȫl:T#V>H[E>K' Lcq"8_^w {\cW b6lx٨Rr?0(1d:J7LV,n8(+ 2f/ %%4a(Շ[{$k w @mh=kcar | aM9O n&4ޒdE KlÉJ9Q%;;2"2:gIx*v?,h/6Ppm !,_vﰸ~ g3,}2*K~C i H.{’F1? F2z{ ¨Wi[FNG|?{%RnԛY u=KϥɌ9 īp%_ۂ&;5E\{ϩ#G1 k t ˥Id9SA/4 $Y r :0|zJ"[ %I /mNJ0fìeL?5޷Rŝ? D57yގX J+vP.jkM-rĭ6"MS/-8g4ȋmRU /. řļI9e%AļԔ1/܉qT.A/.'zYloTw)6D4Jȗ3r|3y)K|`nco)n8a"M! J`3r&r:+鎪$v=P -&J]6gX ){/#Y3X8zY o,PNI r$Ȫ<$ 3&:Q0D5"M`'{gO`pe1tp'"Qˇ`]|z5۞ݓ?3&{DzaK*|MD鉽A;㇣ ("dm?ɼઝ9Ss_sGop?Wю}/\s CHXī{eP\_%30:)U"v$I6vSC`QrC0u>*>~J>\ "aؼͰ I /5d7f ^ JB]b?9\7}|eABoku\4Q.T} pXDB#\$etttS7Gr ?& Ȣ7GS‘18S7]Wה<ߣ K:^ncR8/)n4Uz/Oʬq9|[%ij K\1FP%)D.MB#{|8by48ד2b,P&Y NˑpN,1R:_ M8\KmXdDgW$4YxN,I6Y3&S$ǻ+I4~?ne$: 5 ErI긜|C|&3#h];jɢDYK(o{(Jn(l6뤋ĢD?/2$&ș d:LM5p;0Ur -  Ƕ8yiCӌ.n6GsxdQ&sQpH2]|eڜԱ]2͍,&{('^'̶P'aʛ@Y'xJ<-Gb;C .\'h﨧e :C1:I.8?8e4Y'xN6Y's^l3/~BɗR'\nl8:A;V`^8 W &T#0W Y&Dl]h%[='։M.30(-"oςM5nBSQBT^S6ncE\nmKgL&Ui".K5%-GThp՛u|Y\?l3s[zm+NpwǽfǒK{Q3euہ vpGT.3 (93dXjPP0E١"`ꨘ/5dcBұ1SPyaD21lR.eq3i!%|k~]]55H#p|Γ6Dܚ+g)" OպmD{5/s؈'R&M3d=,`ڼRe$ȥI3r$FyQqQUyys55y;"w WWon`G7@,Po&7ɑ1~Ew:%F8ܗt p- .iZh$F!0ʣyH{ -Z $1U#SLـ*M`=砫=s pLQ8ls1(/Å4(\Oe"t4IDqFF+_^.;{0‚-aau ШE F|Q9a&Fh/KkjƟK]mqT ^J{/"Y(޸͜x>~6ޑ8DFDLdD_S^`gKஶ!I+/6E^$&{sMߖ, M lhK;ԈQWh{$б۴B {} ){\ .3$F6 6A`A2_^g7&qv4K8I 0q` g5H^BXKƞyq^C:UZm06ND\jǛLzar"'$^Zp,x/j8n:rVul(isքsdV0buɟ#Q3WMdwacm~sEMziHF`Ib+= |E1]GɣƯ<z,.g"EsۆNsiL-6tui I9jCg~R|ц<WoL^-t{`x .P2y&ɑL^1~WɋG2yWqf'<&/ W *mPe)^ӷ` /tfF^8Ջnxs$}lOxJf$v ^ZxZ*~x!=B!Aɸu#Jp 2DAp-!(6i76FKuO_ã#duh4K4.O3]Khe,$֭&.ș̭jacĔ V]lZ􂳼B!qnc3)ђZ3GbFy,r-D{c=D2wAlQxD{V^PzlX03TD ̧I r$$<8MrI-ݼ /W$fF68{tt_v _/IXؗG,*Lhߖhf8xdM%$ΥIR3rB/IL$o?H$$jϰr^YfSAY/f5 ׹gۗy*IK[P80/-֪bJ惰ZomME,>nOېP^=xt[xZT@4h p xW*nZoN(N5~)T[{LqvPoF FG$99<_}Qx$e M';!*y)-iMxN-;*($RY$\:#G.uA-pXd!$R'E.[qIU:iH"nt(pOIeȰYy2\KS"QX_.N=טpه2\Y˕K\gL 2k&c/aR6HMX+B7IL9 f w ?2vXqUmƂPΗxj$Ʋ`󰸉t: S$l 6#q.*7~SL%gjOտؼy0lwMqo sS*rNbjFmq2[( OPlϫ>$H# 1797=i&.(M.-2u҆XO [ˮi;s~swMDO*5\ ]o6d)ӆ҆鼀 ~N1>vKV_og?3Щَ [JSt-5mĩ8YD&L(Gt6t4UWy?X.q&?D$ɐ~I9 $op'yQ;eTri{FDv/ H/Ϙf#G]Kv(_MGԵ{ t9; S$ ej%H:2S#3aM~.Ko H_ZY[ȧ =&AL(AGt6t45Sl%|]G@ȞtT{FװE c]aA[ :}s Vaoًx"wU17n9 *VIgH3:;7 xr FgB-G4?#GC~nSxoxyGwmY sv(I99B9H%ʁGN+?4~7nu52`h|v8_x:`>+oQMKK.dB.A7?u6b[iri⌜ d5ő4YMqN3t38iy6-GVSzq{u\5pcgo{DloѳR'h"+u8VRg@5Ji E.xC kƲw[v,hd9Mi/L rnj`pAv@r;IKvgr.U|Q 2Yns Ir;C}?DRnS8svG/s~srci dݑuJ\xd5ݸRngZ\)9w*MGK,+rU6džV _q_אS6:l̟4 I8T|M Y!-|%QZw=Kguk(PcTXTdū$X Zm[d"d"AJ5WOUpjo_\no=U?4K8AF:nԋ(|wk> :ʵ=zkU\B 8Q&v%N.eq";#P^g 0T<>BBlY1P1#{Q\1mLZ&G/⧵//m-O9>s3\` @tV$%"Cb1Sđ,{2!jqûWžBkX!&\kbb4^e`EUĎe7M7xg3 $<^qɥ3rdyfy?>uQmYs*\cTg~3I4C|.9QYy$MVg#3cYыrt&9Sq W3;LͿLCz8*l]|q u7i&Hyjl"RY͵W6|20?f0$,$`~"aE7"^ GQ1BГ֦Y|e6/P]iHM͍8\;x2׸hʌ *gϢ:cJ$ެA5$Y#D׀ʆ7vo:Zi >19e3h,RƷ\x,O.q-̓,;&7;&{8j #V{n7k}Qv_j4W-֊43f WQصCAإ=b*-|kʅ W{ {si>eX&0&#ƺb/hیzԾ R3{Ytm.9Xm^AڨSdm996< ڨ96<_mkr]K,>Z)A]qY 8BA ^SፎW|!qUpcAksm)Mz&O%$M"șLM"I4RiFWܲaDW)fI⸤h!/ԭ4{>#g2Dԥ2T+ER_.jrv@:u#?Iًl\K3rҸfH!f VZ>Y*º_ʅƃ*B]PPP7y3Pr$T<;Kb U4 UdPʗPESRS*3jg41uRU,IX`sf++fg1Si`,'0ʤ)L~zpG'+spcAk ZK`I@sr$<$O Do3 K;@ #B "4{7-S/ ZHб B+shc*_I. 2҂u( 992m2# $ )i" rVd }A] 2<IYу/d| ){w{spcAJhAU!Ar%7#{Rk΃4 &UleqVMg? {fJ n̲1AWM u|ηukz\RHb׷}M+ r7aӊeI1H?@e>%MFɑQnQfe>'QFOIeL]rzQf[CeFmߛ(󘚡DUkkp06g2UMB5LM XVm^B иdR%<;,T,_ +!(,̴16 ,=8yy܋Z>u%#@+D'?po*H y%_ -jPqƓf{6)?6uմ|N^ׁ[ ,I^H%C>9z5~ `@[Gs5PQmQ(/;%l2W I^۪| \}Z3"B(l u,$XYÛho!M:ȟi6} ֫pKC&ΐ:oB iXB;M˒nO!5>}Q*tPE%b ,А?E|{ŋx٬0ҠHwWj=dCDm6U ]&zw$!#$H;Xvok;V;ri}}FD_wD_H}}JD_3aZD_zk[j0i5YFtzR .Isxcs ݅qP!_AhvvJCE!˻/kMgPi;)3;a"<:/t2wnU&4]= #Y ˥jf[Js&3 ^3椲|XMne=bK֯RazdZ V^*?l<jZA?Gkȧ׹NUcۀ=\>d;{9Z7ޚ\6/qr)T$Ǭ#Ǯ0`=mS +@[(26al ғ?Qt펅 (2];onn.Ӎ{E?]Bxt`q04fkU@Jށ&yfq*IE P|`C{U\~A|*۔5)PկqtնRP}/Sg48%*-ijXJal]7ѡjR\u!p 1jvO U_fyp~GƸ=fy9>sS<Y*l@?xۨS͉JW .xD[&Y8?lh{<=4 Dٮǝdv) v'1=*IăO\E{D=@ntff=ݿS#~uܩ_$)ɾ_bM޳|b/b e߯Kҭ0]T{/ۂGe߯Re߯B.F:!v=_ d-E6eoU_ L F$F LEw ז:hPx∀QWaU.O`CN|Qc?x]*a'kd"^1m@6z[]3}rǔX%$ KkIk.Pф( aXU ǰRq]4@GJ3'(:"i&rQ+b&B3e * Hb?f:Hq:60öK%MsrDp'VAt&--&N򳏗]v b$?9LTBEZtʁ*;n 2|brz&B2ß\7fxqc+L2÷HD2SGp@ivu7.K>Zέ>Εtwu.Ͱ͉P%dC5ekZ,| 9DjWyk@V=V氒]bAR$$2 R^0~uwb@$״ u^"Sø] ζ*Q0٪]lUpCFU{~\,~]CB d~N2~䄿7.1UX`;wFC7Qmh?30QR5iI'\M>؉[6b$5vI^BRcH҃SScSntEQn7 Ldfm0_.N-¤_p4/ <@bv( <m<5ڐ0Y9cOו#7nP@@ ɷ[oB퀡GfdO;@= Ȓ= ȞS= ?i@1O= L VrOϛժ6Ϭ^7ps0]qp~6m8(1PD2 >^8P-}gee ,c3 z(#B%&H OC6K8AXY&% 1lPʅV&; ؠ'>Nhg>̕˳G7SXS!4uA7Upˢ 8LF7v&{#N}h Ĥۖ1Hㅚt,,q45ZҦI+NLc]\nd_ӟ֗A.ٗAt_4Hte_Z_~ }L&$2䃸ԑɾ վ Leh#2& qGц 8 _-WE?o$pя+ܾ 1DDHuybP{[p⿫츏󷧻x BFks{*lI(nTs'iG$'B`Ǝ("Bd'KyOK}ۗyJcC<ԥpq%A@xO+k Z 2L_yY|3׼\nl嵿~[}u=!xWr@s$Dn9} ׯ񳂿a񮕒LWE-Kd,wdž#J2RI&^{a^ͳ$S7)U}7SN'jPګZ.h FUY9>/J}-iy[_>ie VA| x,Y\ǫrG= -DRl[%6vOU?{v2 j'Ad7O7Om6E T`Ѷ9k.o?֛@ ;wr޶:[|{~ѿt}tjE, q_m۷1 ;Y܎{wBElFܳ*OUh..t'˿˷~|$ U. !>\tr8pѩQFA . E;:sZ IG^c(xp{5 8s˷ݪZōbl#  V~є ߔ~mXx&Yla;b`Ed p$3j>d/x ب:\ 3M8D6KnnpH[ pm~ehPԇߜleb4d_%^AׅʭpZg oҕ8^[Lg0plRTx75*&4oһWoXeQC덹'7֐P3=;'r'Dn(^̬,mE>ؔh8"" g)1R[`@-Uu?=/o] t$ sWEm_+YRXx Lu4x=TT*2be)ЮT!ϠV YlJTSs _7,\"YJA.YuF>mVͧ~;-SrٕaTӼvo)NT%?׏@Zjq;Ȍ&7 )mnz;3H,$ ¬Se&h]::TAKv+d@{];=ƥeOW(yU Tx"U jmI0}C?ãmXP*A6xr쿹ۿtVK?aC&lQh|W71 ]̓9h&m"rSIвUH ~7w7I$b N=[{3SӧuGLK6jRj\w~JE7eqi~Dl4! h뺡]uXC].aPX yx/"uhmi1.F9#Bw>jr1E]ItJ>ФZ}j!5eoJxхڰG) SE5hKSU/sztz.!?;9j>-DiWl!s;5{-AvKi#ik+" ?Uo{DS.3Ɖo4=o@/PzX&'K 3{ hGIf7FUJ=Ee|ȁ8 7iFx(zx KƲ{GcV%7\+ĥȄm߼neȍr[Xp'h*B *.%7?)hPļ|V W0O=x{{i:mm3gQs_6: %g8x r,mAE-FjqWZL> Z'oq7}/KiS QDA>v02r<pv=~_<nn'[^K~j~Qqb+aX٣ p0[3b!D1 3 U i?=*食Ko%7d! ݺ+>JLD5bbEEW- 9I*o_QA{6rSd9nM Wo<ρSb)o?ݖo;;QFjNm@)umAT^48 :*8s[6ù4{ͨwD;±ApS֪c^+uNUfol؊8kgr.*co%pfGC#ФfXyCøϣF5nQ-gsٱiFyyȐ;%+}y,GӽWoY@WD{Et$KWG) {i:of#㢂/a oGJɵAn=Wt=ߤt hq6oQgn4Sd{\qo4Ofۺy|_AԭScmt3uvD1ˆ<U%]k7 Ew5Z7G/ AZ]z~t|THϳ.V<m2"[t+Dyv9f sz8K8H!Y* +pǧ!ib. %{\o׃w,lQd9ga[8aoc'a} QknUiSZ^nJJ3۪n104EGS2Dګ9 S(~y/#{ {wak ox+z5BemtVLN~gW"0YAE/P+m~}_z ~c:zsBJ{~rmnE+EJ{}E&= r<@$WEҭ8gy 6P\:9vO񓃈 BwCې"wEۘBvG`"vI`Xe"]뷼|~=nY-WGQ׎e+X&^26~;|ڐ6ſe$MgfAFٰP(${ԣ_"7Db3].ca=&{wە)n&bLk? 2?\(#pe,]KKТ 2Sݢ|/// ĸJMMnا&NlT^9|bs6hkw$k5l-nhJl-nAԨ l 1p6H &iqt.t(źh`7J1o}/Jo<|M0Ѽh^y:w=VLD=݇ӽ~ڨot>M&3b~׹- 1m4 =M\ }ЎSxO*9umTS~;>OH20ZOFmVڤX!FM&mXj#ޢ{wVgxU}׽Fgϥu؞7M}fF^<#t}&7ś{o|q" +ܴ oFq¸!˳_::ͣKdv1: ,v ;d_oìGذh;8d>yd-u/XVmmڶ"DT'#Lׅ`2 ͒M(XV*8$M`~6˫ն9UG 5E/wwpwfȿ[t-cq= j{ybAMmݳ@nxo_m}tWOŤ{&[\CFl%I-%əo;+~byI}h\J+RwSPo^א5n a=ɚ,/WZy?9kiua~sYOavg&o;8ox_>~ #޼7d~~.dgN^޼| hkw"s#Hx4tͬbۇ*2 |e=@@7״VgE)3E{42i5^~R-! ]B ,쇲DBYgiŇ毻'Cv.y1nn???_b)\7fOy6]7ћg*HS FX#q7? ,CANlYL\n*#g{%(*6]U%i'- _Gf!t姏(sv}l \'O ->($\2/Amc^PVm1"E_9@$-$ڲ~UC\y4WDlsm7S73W7"f 5D@MDmj\wը_`i>1ȯO֊i|z"n1讚tM b:}3gӖQuTW괊KC ~7W@*mf>F.{]TۊKܷ 27h~Oӗ8nO2Ye{/~#Cnt> 71uyIwVШT?J#,"7a@fjX G_ԼbT{ƶ n0K˒E.j1=c$X+O9EJR#n"5s){-&H%&ً $۟>D4{xl;BL]m`LyDZL(:&N\z8m,|Jf;g'AN4Örh q 2khiFf3#E=i[4K6y[Eq䯼0.Ʒ_4U3.r;bhy)q'eCϓmydrFϓ]:*|d5o/hd8Wك|4S{Cܡz޽osʙz?mdRr_83m)c#rmZF4"wy#a,}cm`LK7ZPg͋+{_m%d31ZĨn!Bk@%=?ƫ%9 ?oB/:o9ꓨX!*Nf\S-'Wz:j{P]VH <86 ]xyN0KM$6ƊXL=99yàaV9OF*CP4hvG㓗 gnn <ݗȿ$菚bGl#,fV-Y֛ѣA\߼ܐMCo(s&ypwi &[Ps60{>+c'eI݇vf#UhP' ^`<Qz~x~FQzo/͒ (O+k rkbZ3'{YCe387vn Ͻ= ~r0L&)Oqp1 ,&..RwjWcáu;)pt3ķ]77[w2^YLGp@w8_vy13Ǻ}-Oߔ3iј]ݛ㑋azeƥ-hE'3 h:GhINH4߾IJh?ybAn<~.8a=2PtD16yQg4s4CΒW ȉ*6^w!Ӵ9HRv2~ÜI7\ڱ>;r( |Ppn75׹w ,xb&?hyqg2U_(=Do7Ui%vBfH )\+1]bw%^ĹRvks; h[-DbK_~/x /ڣk+Jv[+śp57as[&"6c/',?T8ثѐ=Z{g"~*OcvJOohݲ%~͂h,[Sv뽫V״aǖGjdYmZ+XvoU$yp2EUd(- ee<ź4`Q%۩"V6{iaX[C5ޡTtygQ94k8d6rҬA6k@:'@m)՞|h8?qޱB9=(l r˿YGBm𩯯sK@}yhд=gf&vmmշ)[Db?H;+' jr6ZtVi_ƲNvϊ[>L[#Gv C7 >O*bN?iP~}}_@U #_|xusXȹ&r~)'@* R qgZChӄ|#m @:I&XzE(^]_hX_;-ZaAϰT͒Y)-o#G;n[ut&`D.:3 "D[^; Qc- $!S 8YkZW>L?{]5.Geǟ 6jM+u\ uVd SoGeC5}H]&~{_<2KvNHެ>ĩ6v32^aͲDTJCebg}-EnAo5CLߖ]γ6VIUVΦ+T՘ ilه%*1BKo{\&#b :B!o:z^r59!lo}P-&u,Qxܣcܛ#ol|;<>&Y25B-+|ˣ]v3|(Us/hMY;zaOiZm L,[ o=3ejfb92?pAWM5zsLfTY=šRܟzop5frd?45C1WÜd~^^JsʞyVxquw.0iOIn V98xӤ>A1#, $vpN|#Sy)d<º pi^?\m|7 Ѽgwa:|CQ&#x)8zoN4Qwa MМ_i.]EY\‴ 兯4+esIC_݆; Ԙd j*K2T!B DWO?S~ "vs<:>u?F²xB~evW/:n5!+N"]1,J} eC!\ -h+SD<еAcBacԼAs9PF_\&w0!BDyyWpEVoy qY@j =Q&&b(}wj1:KB)$l\ X8nSN@ls' S/TsQ9dG 1y*Y39%;yxy9UUߘS.zp^4/`z U!0 3@)ܯ1af隉k,v*t-giMO! 9 ,ҎS$n[Qq k^x5,u%FY[b [`цXa~F][%0BX.om`-N\ħK 7Kf/X!H+Nam5K 4_cEŅ Odq7!o2…&ji0VؖX(C&S+5e6fbn!hۢV"*([C}2+g b+nW YdqH= PI?KV5g rXV\U\]kYa 6˅%# 1FgD0{S6y2 dS&N0 RCܡvy D[8YP1 YPVP&=&zh *篈-ßf& 06z5㿪[f;X+wc1ۛE齅wh y7YZƄdI4w7(?{;R!=6ih#4pawX'3yIr]Qf2>Wa[d!etc/j&m!ֹKY&Ă=?-=`+Oq,%۷E Sx&=4"(7␱y+eJ_Gt&[`j{~{M䠷->eX^0cQCer 08 ގ` MpJ\Zj7샭0Vwĩps&YYSax'fO|p5X$=!o brFs(kC0YHEW١h&Cft詽+U Ҡr;U_E])YKRκ9x!G~*T< i4`ŠQ{|l'Q }/^VԒ14W2\q; F4~*77Y3pYć],c|&ʒ0Jooh*sy/($@׷%4nS˚󛁽;nҶxhXc)̕XFO$}t>t,ejLQEԖ?W ~ e?:i?U8/P=UR܁&d:a`<v/^y챜"ľ9Cf>E}`_"H c(ih{R:m.L Kԓաh:X!+D?G>ˊ5:<r}7Jf[l7Mrrs~9S[Ji\]#hKp)nhl0?'i_hbdΕ jh /fV+=?,G+ڌx l $MűeD ,fư! UJ$ŲYKRQxl]qp6 x^!d I&z dQDCd&tS2C@}Ja^]QfmE1]a|R81]M Tj*"aNMiYvYB' wy/gBiSBV,-g&uAJ5S]21?of}\GJc2/\S8[" e28|y*3 m9M6a.;Li\+9 (E!>V* ˆj5b!&#PY>{Ac'{5Y0{WTp/ ϊ6ʩN3?Ċ|h_ 9Ř0lL_p`T0$J"̪;6ιKꃫ6ҹE\a3wJ߳l}/ bd Qko<(n1fn6ĉ@$|s-Hb= yBzϖ AOЛydZjrp  Cc Cy8_&i ?VBm6L 0;էFcm2'KWs-)_J/ZMRR',E7%o̹#GA:i8gD]Veۢ\2}^VIZ0Ҵˌd^&ۉ+ #q6\\E{LF ۛ yLZ{M=FyyI[_:^Ѱ: tDj$fP8i&`&kp? yAqDQy[Tp($IOϹwMQt/{KR^&f'X g! bcA|L4ftuŦ E20dU!>w,$*foWq]peՅqWPxd0V]Fv:EemTE')XzY5iXԴ37rmGl}Y及xb%0ؔom8W^SwWUM wwCV}Ffu@B˓X!L@=wC|f ^ܰl/D *}O*UF.n)!m*3&hP%^Ș音t%ګ9}F{CI_3-"uNd֟9'?$PE<-avIx.1 %%X9g\7.útphuKs]5IIy̮?'~upB#VΊ\_[/:Z?tQnm턷x& 06HM f-T0k׮̺0vݕ+ |Juz`#6"T}Nj`܋9+OBN(.;{ky︮=Y.@{u f3;òvEt6UU;w +&6[ڜsKջXPjG Z-@<]14:q!T!JMe.phSV4;g=UӲY = .!*g]'M` KT_U/\-{ n'rQO5r] QV@k]a?,DgiCa W7 ,L>`LnxA.}\\fVnn\;OEk匠3u#\Y|e#LBU`k߬amJ-[Hv+[)TTsq%GcFTuu[&o23m錷 яVQ6O0!ZڔMd8ȋQ2ZkؔEZL2V5e9$)̡6RSTIJFr&g:r8D2ӜС|k1jBl"<~Z,^b €,0--s=DoJ9yo>Nh'?~(-1]Zhi 6{;.O]cn8ܺPWGYnǾA/H =V"tYY4& 9C?H-CdC + ޠ!KamH͙cJ %MH{ ₽~\axQPn)l]뎧3KђiSml9wM͐ 4L)K` OQB9>Gh'll {o"(骢m&6:4F/}Th\V%r}x(bU (s- 4XsnM{%e:Wv\48I]_lvQ'1TLL▸/0P=p^u4Zh>B^i+rped\T>f` Y޳m8Oi8t25);(ҕ5 eJkGȶ&( ͕5A]$ӠǕ%7-Ě*peQdqS7nP!h[Z!4u#0Rvh!a.zfdh S3 I2E/ۆ+2Rd5$rnaAai[/TZU=|Ys*۬%f0?I*E+[s6Y"K#We(g5I~V'3\X}e2~[/5toe9U t+HrigMѤBJc0SuqcSj@P D )gMm5+~ef23>H BO*cǗŖ7qe2i8kk{G12v˃RP[uu J0F:(Tse{#[_J%ZV3$m> V)1Dp!}}m2/J+ t,0[! " pp݇=w/tlȻ8WpmzyXUpp(W jW6C.EI‡GT46qkEH!j,¾XBKKcrvy yϽ?(d^ Ru]R" G덽ޖ'lYJ V2VkLoVw@BqXVSx1y+aBƼKϔsP1fL6yH`JN0*!ؖ*1G(Æfwp,1v}ZQl< W|E\ݠA눇1`M]וIa: z/EL&z} id19`. =PQ<.eUJjG ǸtV)~jN͏e ]51vM{b,y<ΊٽL` b,PE5jg]}igAN]Fq}2&jv* NlrRF Q?kP~v::w`klNu5:a6;9,aarٶ?CWs5>z~Oi`D BfIo xq;] X'eAh(}0lwRpŠ(]t3bzo8V!2]# &[^ bhǕRjpÊBTL?tv2`]B3 ̛PvQl:3Ru(W.u*|o//K 6 s5LyML!V;<=WWazx%}ϕ?q$IR $2fo_o:97--鄓Od MAv&ZfHyY T' )Qc$9ye}`1j]k{LUj[i9RUe0}& s8tDdRuK{l㯊 8 !k:98znOqZ2 &чy_[HϭJ,\H SXM_6S_7z0sX1ugQqe!7iUKvUZgtWMGʪlpMX~9l;VF!wZcrMr?5:V R"cG%]Vݩڢ͓ ZJݲ!%VSC8jM+B`V2RlCV@~5wpGN\1犿&2PGkhh)Nݿ03ېL2B@ z1M(pC+KERe>k!u7NDT#Rch!4(ŎEX1ht6!@SKSS:-{<Ѕ wQ4edݯ~M^0b;̗A  W\ַfۅfd-Bd*鎢ZznBS!h}CխT7X^CaP4A@{Ŷp+l6nC8EiBWLCT.dƚŕ*zLy['A0@D,NA-p/ ?bŠ']՝B1T@ulfo;)[΂~ HcoAHGqcǯEeOksݵ]>_OQlK̀NrJ˟Ÿ5\]=FReBW k*^#.<ߴZ1@DO3 c8pغ lY}YfA6Ho`;\z'>Х_L3_+lIڙϕu">%OX熥d٢(WݿۯYT+R"d}$k[ QkX-+Y,J0*|+>K=A{Ɵ^SAu8Xu/OcDM{X:%^YVt~]|C,?qDK }Q rp;-FMyGFQU58\?^j>f.G/fN+z=1'o9br;X8+jz#j%օ[-_}f`ho)՘25A?JA}Vhcnxan5V^V'Z\UiQ0@XUu}L RD) s#+dң>41LQ1} b_A2 NNєr]H]1*RcVF`*:1$,i밙pOa0 $U:ۦĶQqE=dq[}e.ptc `ű s|i-.0WH[!HYC'ú,n!djm[ S`]p\,XٍW)]_ 8UscsVpN fvFDЖ7#kfAm_t]!nF'FuX[Ggf+<Ϥ1,}URtзkK9#={.k?昌'Ƞd>x63Ti|&~LvLdg2I^u7"*C_ͥ!D镱+4SD6ZW-cY; "m\W0^u,{ zgKg07{,0x{T=TOWނjȉa ;%W'*;a<[j)Y^ Ao)A&ZIsmb'xdT :%6\E=,蓞B1 4+՝fj d²(V_ ~VRghؘZb `JcUp܎;_(?9? [z2l} Exn-QߡA%Ecu`%nM-,9( xN8dbSapI?voGΒC+JsMs-NR0P@rf!oa5ֶ%&75d+6`k#k$ 41")#UId ,Ib(@ h*.+1Crk)=ÀC>ꦡ¯Og9Ňɓ~g._9[o&6!3mmX.=q҇ρB SE&jۅ!m=uq>5JY}vp û ` vaCK%n:əidS}ɾ׭Be붏 t At*Ypu0Y@ ptPI]9&#h3u4˪~Ip}MS ;ruuO.0>ҝ,t]*JEWWuR}5Ϭb43~U9iL7:ʽ'Z+P`oSU(-f8e֝r!O&243`vuXYs =fUT@#6sK-37UC1n8aXkۋ=JAoJ]|P=DoJeexbY, Y40{ mRfu|GV-8$fV2+amZSڝE.eC[[F_ƻ?X,~۬7O`W>*eHk"g&?b($Iia=eZ&{zs$~SK Dî=B&<Łhz5G }l2)E'hYRnCxNl':6FK,{"37dpR2`;N e##Oc[RSoX |~Z:΁}w Cjjk2m`gkH?ވSůXnMiM>?oϜaђĦ?nMdá|=F(Rtpv"(QR |UډhK>~"4kj![6Q>DCyRD$oN}vI0TEoGַ5[|Vw* :HMQtDQz_k+p?"Y6QTW $ ә95&3 X_ |5a[Wcd'GemPu 2#wf8د:jeīdaM U|k4Q&)-Zk:f6kyW̄ N!:N`T)ۦꚠip:e B-8z`t^baa; ΨoX+kHH!Uy )=P't3f&7:ʙ3L Zu \uզ6wTZa7#q @n~peyN3fZd3:'UK śJ.Z8bj\4U[l)(%"=} >;>:he=]lwu)ck 4p^T3#]k:qaUs"BxkpBW媽v6Y[w2mdcZ]?j=GC00ݵ0m;W[pok[E@ we)ngעtɰ^JS^g+KFH9n#sASׇiHK*-XsPF }9S N4gՇ2UW㑱݂4Ucm>K,^īoSni(V Nv0AܞɚU ;`u=Ba)]u@b![x;&.%ؖ{PѱV )t"O.z-G4!d`EV*~MWqytOma('w;ZpDCEhiH܊ilDkCԺ`<$_0 {iZ|@{zѺ48&Any>FppG(\oU&}OO)<3n<1w>qjpn*ۣd0 C*$jb*&7Վ|}e.ƶAˀЌp=݅x2LĶY8$-k$-^mPK|n'N逞 ZUN3z>hk]7$f_D3=o_ߗ:It:M@W1YгMFWbb曂9s wsw ҇yA'W%=uJ4)dGğ"Rڅa*-O!d.koAtGֆ96s#_4:]hs#NaAb14h4,g \zM޾(V5S5pD =2vXM*dc-\]Xۂ}[zsdrO'Co >Z6ݖa$‚L 䫩;w"暈 ,֛5|V{}ޓ t4%OرjlՍFoYZ]'YMVyV;@&Zo'h Jn{;Yk3 ȋx6Cٙ|/ 1<=K3?ۤ,͒$f&C1XaٞpIJ(y-Kԫ+S-z>Ɵ۟0zg=YϬIX"%9 IF[(5TcJ=M[t((lwW[m|s76ú ]FhΧP?*#tѽ;"[u'?1mX@PL:a p[UUFO"T5S*1A~$ -Xk>+{3Vv%MWxge58`N3gNg癳Nt\'(lCl,MuFۼgϖ%?K"Zgś >RXhћ!1.{T08 G|rpnl{h94'2T׵Ɔ}_p9ybCUXlPo&KɃ$#Z%uPJ)?M83q!+FE~G7moWr@7숪'}Ԁ@69A"H4Ndq1@?0@F%iR.(Wc-eò)OF]|x[ VU9U0 CUwMQ4:Y% 3;ueVg3J71؃nd3, F=u(@hYNf;GDUcT">YʴȜbLЅrp!v[-&=s9st50ӍeZwu6Hiب@JO,*Ev$^I DmF'>S'TUY8&+ 'DuxUbr0MQ9q)vt_@7mCSaJ?tL?~*-XsP549~uaP`qwb.4CuAĩf~4ߑY{򠾉Q7i1}A{]G 9L pV,Lȧ௅OI⿡ G]X:J `"G:`&vFe@OXw o-˟:2.=ϧz-hp"@0J t谽xfTJ,y<2lΩ͔M^ Dx5 Y {(L@ fhb=L4oH|[Mg\{=UqDxIQ߮IGy`7l,^/<_fq93ۇS0hQ-S 5LwN`",0]>,#LX߆Am9^<4KE'<tA^fr4:{Mxamg)頋ܹݘ"sڹmc~ aoCWo 5Lb-0  A0 Z*qy a["ZSHm *RrF3oZ=&|T=p[CO;:&ʒ0JE=Z- Vx_M]$$6Vxm>gSjf-4`se+bptSU9fY,Cq-fp18&5vōGu.jOv7sr9 ms7>Um*:˨S}x2˟4Rs&~(LIv!d" ."W{x}K6lw~ W㠼y>ejC NGR>Oi~i3*]>mO[bf,eF\vNM}%jAKmØ,P:: LXe25✲3p1zQO^O' uljBGb91f_"m`WA|2OBgp O%cb]*ja|8H}7D,?ajwbGQwRf:ҥͨuF]6K`-F(+$s EgǚA^,6UZ+VZ 4{8Sy-XQ@̀E5%vg hpgK=)^5?fiv4`;)X3R% 2R0۱WG_\[F$UUb>l( wƯW"pxy@Fz:HS՜XT@W3zy 6.#HNbedOuQX""6@*B6ī`{vFTd3nC v9gu]]s/b>DAgգ0G4Sc}Al z!eh,uFN5Y肢ӌw9߄)]g0""mzjVyuכ_@etTî<Sejti\S5t<ضkA4f:B }-ػ⥲?VޒoqJn9li(Yz.d Ą}£?"\VNcpx>u0dl~1y--8xF˩>5kh~xeX`=(z."=w:8f(oWR'֋"ݿ$yC<kp*H{XC$iNvR?/o=qS>`E<::.O;\,ر5xN 5pXU0=,|"PBzKU~`jC$xk;(MCLv} 1N PN sNH'wc:=2"|WޚeN =ƛԏ&t=$fFc8L :~Fd{ rod9ao^YF4#0a0el 0l)#SaX>~fVGWSq 7AD5DY诺7/YqFa(ՁdR#7ʃY}DG NnG]UDW2#L)6)Stݫx"c/\jpXH.8.K@"w+ j Z 0|^ wH:&y7ĕ8+hRZ|pIN^+^h M(6V |޾m#[^:[BJ kfۜYļ1z_%~[?M_d8\ krXCX&¼mRl)LSr}^}Tr7-ЄiY%YBʞYeYҢg6[AJ^ )mqy8}2,xB CZk4J,IO(l'§a'r+4jr2 yoANr4 )٘/ǁ8"y[ x:i]VǏ 1oz|nYoҢ# 8ۢ 횁UzoD?j}Y}+q) E᰹L+ҕV6ta>hKawߟ+sq ,I| Ж01- OWq\yȎk`#˴,]n>/P^ /Ӳ{tM}UK.c -D]Wy'@,sF F ЛHqI2U AEgqՊ^Px#ǀ7nkZLJ1IxMK#;XJ8BQz'ȷ*;b~ 0C5U 4Zg:]8W2}߳^GWϙfEU8yVwBӆ:4HQ޻%RL3y~ (~Yi;lgbYza-uЎ0֕ҥVqי6;ZmMF([2o@]hu%y wB[&O-*c`p݄5)@:s/EfLNrVwAJjAܞ.*~^=bYlEC,)yLGJRDHQMQt rZ1t :V3P+Hj %ҡ6`ս+VQD~<"ckx 얏G;v80D IIg8߂*\*^2ҠXQ&i@e?'/ pbDZ-^G(f { w<EinnR.ď Tbd(:F.n1#uQ"z,.E2DVB>B.rJm{ς"U7x0t tmsN:^BLJA1 mUGy ~ygHm{[6 { [MH%Msї[4+xu:j=˰AUt^7_瞦4Md6  d@CO(ᤔ[L MW^U1+Q9 M-p:m_! 0o&|+j++ -G>!zsvT<&_Ф\؛D{hJ췯[:" [=9=Z84NgyA UCᠽdڛ&n2Mce%'_]=VȘmn;<3 =S+4靟 /$ "C5Ll(n2=r,yKUd"e?4QrN&lXSHPN z(~2լm34 "`g3,_p2Y&LDV!b$n> DjET/ AFv@KLhCخc/$blPvEg0bkt7L)nMe'd%6Mm/$R4<2,_18Qo|NX5 l`MEao }5zHO[mw?-fH'4AbƭНJ́Țmrb̩ca @T3_g1wJ}9^5q55uxW;p 59l.Sw0cZnxa!^߆3DN"8wX=e;*:mU{Hn!`!kpEE ?tkztw?V^gٵlDY_xș-Nz 3G6~fE~/3L(pvQ, L/'Sk>s"_Qxj|me)iLBy&0$x`Ay{jkh O5O*4 FPjid 98ٷ |",ƒ4[yBOŝW@?] Q up&uM795uRN5ns;N,WF;M' {[m:N2r0-$?0, .7igAe8K ~Dt]ǒjA>:;$+dfKa>:'ep٠? ֯Pwqx )2^r|YT\3ڐ4JxqY Zz=ٿq?Y3|l+_aWf>s^Y zbXkU܃xK%̴^E+[x =F6,?8*ݟ =YЌ"^hjuZyVvg[+]>)p{x%.GѪk ODW6gr\C,\1ҵ Rc}n70hp1ݭ&5 aكt6q3<4JE;~@UUN0x,iUeUZKL4zV:bAꇐqC!w᳚w⣇;|T#X\yyZʩw3sw;FK3)"GyMHhr 374T@7TOd~2c^989U5R+zMw9S6"wʸzZ&!GÈDbbh6)g@isg$qr-ClJ-i; 0(.89b-yOmF.W4"2L\`5{d{[p[ [yID[vqAޮe{_MIM`HǀD%Uw/srvU=(_r1Q`~v}los[La ߭; AMtݏX{7.V?woIxG0e_Q3aRQxqͱB/(.ڷn>WM'^}C5Fx>eOr*cwL^*ijNgi4LHc̰X:1q,Ig9q,2^C.ST.`1U:5ALӖ} 8[!}x' Q'&u&XuF,}:]s^~0qKB$G*Ӿ]rsSv9q: п si%HUL$aI߹8vS$غڬJу>1 CW6d_].H0 "[D0l{LoyJ pѳq7p :,P;3?&!dmh=j3ejv_r-nYQ>Dp?7e~JE5>J$T&S&sNق9+]F|J- "Z/*5̯!W",`UGtU1Xn>Nh Ր{t& 3` c_4\r̕ɆT)TnKx5I{h5;1ݣ$O_[]WQWmI5B%D0-0 Wq?h;rcտ.XqvTwUS3/G%^o*;`(f:#5i>SM<~ xCLڦ$d!~h?{9,tt#s]nn(5B0_AG5Al1kn>P5A]11 zE yG/h[XZZD0j;d.Z[ZA;*&ȉx]0lLj$Zv IԱ\dm)CI:~j@t5]e<6.>Qp@T_$f~"5]~p&HݎSGO"m)z{KS{_AjUɚWW!d:W/PT=bmWϚ!hE [FQH3vЉ%た7qD3P$\]a?k</cvw$r7+R@\*jkĺn=q,Xr%FEܢ'{R*^/8lx͹'7,Ht0 /n6xHYHP.7@8ֵ) huQAn^X<7bs]3tG͉^6)Z *nWj C0 U zZڞC{FI&:0٫rv褝2+N1v rR11 )7 7T})l7BktVmS@G7F1$i nz"g\nC:nUN]q)tRCn@eи hB1X+jlc"6o Z}Уi4°1NX(ހ_7~Q(#Q{꼡Ǣ|{Dcn]zYʴ`N`pM1Tb ض.*-Quv{ʟC-)G3$25%,.RB@^F/߬*dFzF~EdF7LMl'^@/>jX#R8AXLb68uM dϓ 0 t~HvL>75 lzB@nIlY.g( 'Gr i7!x:h!H}hZfǡfeh㏨nU,0l{k W3$ƭI֍G$,*MFCa})f/AT$/|pAIrN8 BD.H"DDdây"2{ Ԏ_ ,H(8DA)I2Y9o }8 K3QLA(ت+):b&qo.޾y}0Y׀R=t9!0OwZv˨0`+ͬOjD0QбFضG4Hyܦ`LP^d &.d'tw?`%H3sf.\BZpR@5&:;~/鮅˾Mg4ޱ $Dv7}˃H)dmSL(j"=Ԁ aaaiFI҆&rB(xăSƍEv!_.n ٰmbDɄ)6aMrEKyQI`jHѵE2).>cȚ@P|Ot3UD NJ鈃MJp#4!Ƥ+$~aq~~I&M4iҤI&M4iҤI&M4iҤI&M4iҤI&\$$davix-R_0_5_0/dist/abi/abi_dumps/davix_0.3.1-gcc43-x86_64-redhat-linux.abi.tar.gz000066400000000000000000003723171257152637300267150ustar00rootroot00000000000000S]s8+pUޭDɒ퇽ڌG7J&qݾ  Ek@J%ʖ6㪙׍h4T ΢19;3z|R~m>&OptyH Ќ4}RQO4`K<{onwy{85ͧoӫ[mz{wɻ?vvSpׄ(p1!ORU•/]ӗ ߘְ( PE;sV .''/ד+Sˡ7;Ns&Z|{? ?C?zW_>| @ %#~_[/џ|G퇫/]/?91 X"?7WL}l~Z-Qxf#4H+b@T.=gRXd:5²U2K#3Aw5(rzA^Ǘ('dHYDVN |D=D{2 "F@Cqq "DWdx:< B#Rz&}6q#֜Bqi=i'' @,yH8N}=f 4{d ks% )wEDU}҂*6R>2s{3t撔AFB-$#δj!*xDr2i#]Bg: (` {9*EJL;ͬCp@˅p4Pqπѥ-ਊ 2cCXLƁENB P1ҁ'Hđfхi#Y)\ 岎-unUm|Y@hLGm?qͰ+oDJ<`}ut[I"L,"4-a,ЃV3,mKh^|$Kɏ8אS#D>EHh`|&נ:85%N:>ʜcjELqMjTCxNhIa(`G$ɹXk˹Wx O.Co*UOᰎpTS)\ZE1OܻptJ]9.V '砅T  B;rs;໹14I$E68my'ʄPkFQ͂"s%">BTTG(N%>]?~[Hd(AaG@'4F$D%L&6"A|U[:XRo[9cOӳ.UaכjRz5INK9g>l%*c!v5J620,xdfնfKW9sPoTb-'ʯ@btӖJ"i_ iqE #Nܒ#ֲn=>aw@qtGE^ˍ8B:߲`h>|gCsyfҍJ'Sh#/#6d'ZH:)9֨ ,%p}W8+X-|N58hDD 3xc-U,Z l0sMHX6r)6fh;_b9Πmڐ;5θ3踑c~@9U-rEӤ4eIT9SYSauRGAӈh{rz],-$O4cf07Q &~4^(AMJ*Nes.<Ҥ|<S֘eI`sTB ӗvchX J4 (D`ȉ>0Y8J,'9MbYZ\nM-T( |Kd`&zI6,|2J4a5cìzf"HW/׬vĨQhX 2TRQsǗZW\wB8`Keb= ";P1\xY"{ ?)T ~$X`]VZh.b!3%̄J8ZPi l9VX- SʘrV`yLbHu4;nzaQ:@ZSٖ8VA#)ie-v/݈drkionaMlMm ^F,7vPF2-XF>s`O7o׸K8p8.b)%.%  M4mlDH.a,•d)R=ZSLjWpssUnpۢb6+=g܇txn.X)iAwa42-LF`+^~D [NBfӁ#ҝ<@1s4jĢ"MHTջN`%'KjmCYDALsu9`*s [.}[Ƕ9!Zb Ӱ"wN̝]zHw6͕q큦ڿY!6΋7v|j?c\mi,!"Mr\ˁ%46(g)V$JG^}6r;р 8O9ܓ v3ƒ%z4^Fs~J̐s3;BL~쎘 ׋P*d@ @crިYTo AĝWI .eƉaMs7# b;\h% yIʡ<3t. nwHd3q.%"rHVEZр#4 춡C/UȪ4bB7l`6[jn$u4#Ìі(Z#Fs<8ŲdBb#PۼHxg ƠV2N.mge*7T<917By.FJq̛Cu .r}t ki<߯7U\̖WLkؕEXqذ],u:n>bAq : Z[8@ [L@V$4WqN @c:t%`x,içw*X0##S%+%k\43NbSv`t 碩cL76v|ZtD_Ň5NmMtLCrSXU)|tniza>*mݳٿW-xg,+ƹ\TJIyxTHjTՁJX[a[vBnjrX_sc!c5$x2K ECv9'6% -`_4E r= d dn޿6c]_8_(Gꖗ-WrUEB%(ŵ@٭鮋llll,,7j*/b iJ@@u%o:FEK@,Ybݼ\5 藫Qczr#,|im%A%ωRCnl]\_4] /.`Qc T)`C@bٙGfށ! 8-t2K]9K%qWa>(si cPi8"JKɍw9ήFUCRB) ` }eo iHg"'&*÷̊bX O#<UmYn!*<U8>(pzċilϭq6ՙJ7xԎq^]NA#4'C,oɰhrgkDp"6rZ)؆) [$ NA^éݻ b^0&h*qTBKCCB<)L&\P'U`NEI\o.PA8hxOLy|l;_l]q6;Ji[ 2;!JjSgʕ8tB9Q \n8#U!anzx],[Ġg~+8es(85$l:v T*hJ{QϨܲ3Hb- BmPu;w& t)-i @6g6zzag.PSu!jr9lhGhV5Cu֍ҀUT?*VYB-LH-OMOm | Ng,!0*#`a- cC0%X{BEVJ/@p=P %,eTİWг'KDjk9~bxU?:J v:OyB:HKE(fo2 j{ocI\4sAc_CPn-o}fN}Lu_<# 5FEھQqۮ1,LpY,v_i\ Aɨ7@kP"iiSd&PU? :1 /р5M4v"FjX(%! *jMB=6\d; X <>^ o;46Rl8Dkdr Q"WSPr.v{*ɑU֔;{1rq %ҙP k[FT9HxAh *(8VX Fbҕ GdaN, $QR|N`G*+& , `AZ WƐc^18)399O\.9p @SHZ pcc m jU$(O$PPS\BwzTy_  qVpȾ65! = {MpGM+8E]˱w~ {^`/P59^{ Bx *q@Gŕk(aApJ$yDs;oTak?{GDvGH88`$`BHZ<؊;o4›r'IIyHDo0*pp0'iBv /3O!P+ aBI$I,96T=Ý`V R |5IhC`{sS1lTT \%0FM%G7@B<LMs/ͱ0r%Xx. ?[ө !'"h7 PP,֧e;+,dšdzp?JtT7QTD-Qa'%@BAAl`K%0)(6`V,qzGyj=o _xXHRLQj: %Ш2a@h$8o:4töUAs.̢ 8.uOvdT͎l`:h0*A-'{4&Y-Q nE% Fu:=?5?h4uFZ I8dkcߛ{7V8{"kL/ab-E:kN);.M)U]\YC?q kHȹR!-n_np! hpMB;$ 2IAIv ` W5Һlв uN\*!s8E`mvMgq<5T`P۠g9Ծ9.@ 'A8STDָ.8E Jǰ!Yl I$7l-Nr`:ݘ̱`<,Waԋ`C=1Ceij '~D$]\+ Z7q&OEԓsվ)q’#+-(^n,CݰSHHDsm9ߙÍRnpr-\Pėstr.aF 20+7A!oj06[g>{D"r}TP/p\z1uR*&ӑ4~G]`.? Hs !_qmCR7\X`BBXz ,+P7@֩K(V*DP$R 10KkJNYn*F+\1+ QJ qYc,ж8Aр_wcYۨ4V R0CWͅ5q"PE %<#dt ]#,??'Q]z6*(L:JB6&,XFgQyv im>ik\%PjnF!.Bz誫`Z.@%if_vf #fzE*79\Ěbd;Vsڭ1Hp˚BpRƫ=n L|!@o]%ETSQpq:L@̃tQ`X(pFaLlFoSܡP S+ Wi8CM% L?@)8`I(s|_8!skb{p~>4hI!T3dU)e8!%ڂ-1PX$~ѩz3R@c.*@*H{㑾X($XY!;&88j%W:(ȎQ8%ks4c N Q#;CE@1(-0}ؓ̑RuRR ecZqe0Hjw5bŰ( q "9 e-2.{%@ wvšS`XSȤujנ||]z2n(G"|X}L$=T|>0JgjX, W3^&|0WJ|Cqeh`PWMأ&F\W5 e8aZ8].W4ك 7{KŒ^"M~k d-B waSx 7d1X^xBǯa 5İfrh'qqȲ%ܦ+ԱGkSf.A2x:Js2RPB*9,3R 7Q$4+CmJ$V[ JK]M25,B62K}/@[phApH GZ0\#P*ZD!`9/<&BMpvMvMqv%< UnP/yō̈Ԇ86K! A g)z;sTK$أ%xQ2 %NSJ$x]ͫY@Uo{]j][t.c1U1hwS&Aj? 5.JWbaŨXx9  iNU90KPca î%^&1,,hWK >2)ФhZ` pW :z6ʗH8<̓p\6c}#'<?M `Nr,:>Zʱp'r'pVMv@VO9#CTTkG"wr M4B"õS) \2A MEA@ݟ,& 8fB8.Yexld6t+va Չ5P+LY񸱾`ɝQŒ9t e $oٳ'|PṮPJV/%b;X0 bQJM1)$0P]m _T`)^g'B8 8Pqƚ<\ˑOp\EBW @G$Av$AiXJ^M)py w :Q豟YNe'(jWce dX(e؏ õ;΀[ݬEalgtG~nǖ†].jC*fCmrH.@g9敇B P~~[oc{L 5&T/ۙq nD=!EXQ NPZy.0sZ$R4='tW~Qsq}swpq E+K呈ƺȣ%&FͰ8.Ld2;Z֨;8#YnNSh3Q`!E'K^ 9aaX;m7L7Q3CЋ +K@Q:) J'4{|ts6(Q΃ wjB_NJ<5( Pjk&0v\B:Lbiq#\\ >%4^@B&XHPMA;zPlv:&Yp3_cNCW/0'yiE2 lᤱ]C#8uO~._5a`"Ko+@hȧ! Y|er}wu9&qv پ*|!ZGT}pdzy)Q Ypb-``3 sd!B9a_B-fvYޥA3#wj 0P\O*- [ PF9dK*h )[v]gL9qpWzm£ E($ReK0Iߖ Au q`eZu!` 8Gh#{uHMGl#y\6JMCD~JAVNHV()pp 0 w9|i8Nd5jK,} &v[}L,Hp/ & b!K4)AH,XH ZX68p L//(TB$NCatG0 Sȱ`c©hh8^X.C^`Hˠ]3ihh,`\(Amú \Ua(P3 a[lvX-ݓ`lӣPv!\q(lG!#kJ4`*M*a''`Xz &_RCy'W83lɍ-qD *h8F=s 5'(bQDDds*p!j_ўS!S7rg.hXБH4|v<nAcV  1rA QYV [Cgϰ{ NK ؃^`<tVF*t(JT*̀&$h(i pF_x@?mfj1lڐ9F‹D"p:߅Ch8hS ~ TMf:f [4^ÞUxx# d5+Zd聝C f6CGYT 'lQ04^*-Uh؎.q.PAR  )7;j'q=q Klz2 ̀I(NEԑ__EMhS; \WyHc[Y K^K T?NA0p0nC8e:|>z?$6(cM>oAmoT;2m.))һPH>T"xQڪ{7`:|O)}^b•݋$3ۡ0b-;J#eG베t{wt[:(+G 54Nf1 zHXM0 j;].yP) yW头HY6К6e᰼UTh*yZ=. ;uH^2X+l!XR̳OTZc$)xVk|"K?8e'dP"9* iٕ;7L xIBڌHd?7H :3* qW=A}RPm'GN8(5>w\>QҠU.^W > kR/a;g{GOl 6H-PGב0}/}/Vg 5GЂiJ]>/W:'u x{,cjIn~/7$Ԅt~tعK~Bpڹ؅;WhKSK8: `aK4X[s8\[#Ƿěn×qm^Aڝx`zLdkqj턠 HPHJ<Эg+ iQPD48$`QTA!;ʱQB W >bWC:A.pEt`t [>ؒ|;UA.pwp\ F2:ȥq҃RHޒPVF\"rU."JBBP`{P6*QP*,TdhEv``+$` Q BBOB=$, VԲ[q>p.?"@ $TOI(Xi XH(T.\.f2 dHmmq`AfiI\ƍ5+j 2 F: gʦP*,\Ag @ 7,K?OiB88oOp@BBOB'֣R(HK5,hŜTgs4yp⣲4DB6;VXwI% x8fk׏phQ8$|⇨k4 Ĺ B5oJ'yO2 >Xm2Q.U"Ű-B0ma4 si j5j5;(JC}1rQ ;jZԶ 2h(P4!Dz@\i 0mOlcs9h0T~kBC5W,MDV&*,UP&l8B)$\QPR\ p.tW9\0r@Vt&bP($ TeU+ `EG3lZP ];+8Xs <`spa^c_Z T@X&€p5.s \]5,Db*P/4cFdȈA- jB6zO! m&4GH*4o96jQFu!jxfww w x x w w x x v w w x x w+Sy,ÁP6*,PA)gT>LxUS/̅AN֐aEQ@N4Dz} .8/űR%(@;5E"v lBlT\6 #\*L,b\;bŰ 8R/(9ޛDenWw6$\ن$ʹpپoaɉ"vtSijDs@vY*,W$ibCy`Dd465 {kF#znα%[$OgPvԁUpFUA9XPHObeY.`"a Y`d韤aL`᭏!On $K:FW6+I!_"@GkDoj;#>尰KP^bT&<Hw%9tC Dx')9j$Ϡ% )NJa0>_Į+3MAOt33c#$S#t\T{#0'[?=bOVP/HY\I64c7M%񂙐Qfi< 㪚L4K{u4'N]* lׅF$Nm'fVbm%fVbm%Vbm%fVv[ m%&VBv[c;=A,G绶١iF.VQ2392,NkpLg @0 Cud#/03h X`58pui$URHMZO4Ҭ82l42 /iX ي 1Y^TDr dW 0"=h 9y7gLV2$A`FuP =;I*^uܲ2+|ABG^kJ?IR8XWNDU\T`~bcr\'{@<:`j+o'FzHo1 !ȳ+I)Qh4tTަ`'YB,<A_adqk&n7x ̚Ь!\/b]._!_ġ_پ!3, ,&.NDLDJIK,rt@IDD\v^O&8j zJ8aflY+(3#xӹP! W&ҨtPБ0W6Z48kėEFl^Րzr߉Ϟ 8r ͛X8Kx8V s@1k)P_Wrh\207f&p;+*@rO @.?pS{$KDx%%OSǕ+'7B^Txh_8sII77o:BS'_7 JMCcbaD |-I 'γ9G=I@3$,uE~#c9OE: "p,N _:n3pщ@-?{%]/&@Ok;vf"UwZkJ7a4n~aH;69!@ndKR@B-lbK/:;v%y TCv{I"W{K/xcv,' &$x{JA<388O|%Vt=|T*X0V"NBێC%жD7HTxuBW6 &j8<߄@DeŒ5MU"Jg\y2&&JO j, Y>iŠ-IB宅Q"1iz**Q0cEܚ*OZ™D̔ID0op҇J@6WDˡƢqTN$Yy,1)-ш{\CV/3v1Ol Po\Κ*lWKqEq;Q16SGN'*TGk~(CLkjt?Q3F~+ӈ2,wE8fxĦ-`*8-]-HIoXoG_:| -68]ID5sQW-64CƤQʨKݓyO%TV$ԓ<,)~Rf춶XG$ej/Ra_"G1ojlkj:wJaX3,N&fX]/.pRiPdj 6+UUT-UFO!Q(3LȠ=1u@ ":l稬zmtnhMfzq3-Ik) ܖCWMƱgې]ck]JbHSѡbbI@%5:^9 vȲ Lu2E; q,Om9qMS }z?ԉ)%8PfCORFɌG _eҘc9~MAEӧA2Kgк,s%V#S\M^P"\}|L©CΣJ/6\4 Br?b4HF1C1]n(7J2+4羀ߙL3S)ZJv\aMnth!\W9u+~j2v #e f.G.F/E$NB$!eD81~s#? Y<'ܫ9k9&úCCSJ\sfﯩWײWױ\2r {+L܄sU rzaPFb>v{4yR Na2;Nz$d2sm\Ӏ%sEuM#\Sv=Zn'x,oRūs$ou~kL y2Z0PX8a}D>i&|yBZïi9(C%*owCҜwl Ze 4Nb1D\_@|k 39^u kRYsG]%NM=t,l CG%G(Kz\җophelU!T}-3=&&A*4HЯQ!#`lzRYgj<ھE8zt9Y:гMtarW;YJLj_FuĆWVg!E+ѰӥXGW├"ojs6!T_L,@beJ(L}ǷC0Z7h58~ǸоQ+CƾTgT@W`aN_4t ]A};3>tO)Qr":5*EslM eM_C7 %ۏ#̋w9], ]Cd2H;n^vpxI\U9X&Ef&Mm} 3 k^ƎW6_:W𢝥4 c%Q$aqMW$x.\49) _:<=cӹIb?ǻVMɇ9c%,;gs}ZH F~:^f6#W*$7٫ی^f$d @Yܾܳʿ^uRn!wo{H[AJގe=΍Vra%pOמ tc}{y\58s ;_a4Ȭ 睁I+,ga0]XWlŽv1|ɏFYbR 0~p"b]]1Φ29S- cmBk}Te;V:z|? JXj|PeQAIU&TZŽWcRϽ@9uY1n{'in?/΅&i>o.٤Uguس};RgyM {wo5ȼL3-&{ői{w;둾<*^|7Nkc`ƋzHnFF_=~/dZdc'2ºxEog`\ O'`zՈ6•=JF=k4򞓓AK]z͊9V;C_کu-E[-mkJIzxq-*VǾ^<=P%(7dwQu2P_;x={L^U&og}kti-1ϪK)nnOi=6-8R^xkY՟TmE#sg\KۢXv_cNFu/VFM{Zrӌ[ٲc?f2A0`ڊW2E0MY1P{Objϫ<5a;ڱSfh\*W;*T灛``dz]Nlj~]U Lfxq[#€v-hc l`:~(LX ^dWA.%_vH` dG\=A4mh݈6&?U-6"Ѿm 3 }2f`MٷEoyhՂD8a<3=ڦ:SҚ WNlG[ L:*fṬtN$J& fQB.y*מyHeoB*qQ8Y[|^fG4Hf4F:mGf륉1R95ondV-lz=)eMZMga؁X g;TIW3- ̽TzL|0/ V̭kPȢBdi#Ytڈ,:Dv"N;EȢNdi'YtZ,:E"NkEȢc4XXXXXXXXXXXXXXXXXXY,ZY,ZY,Y,Y,Y,Y,Y,Y,Y,Y,Y,ZY,ZY,ZY,ZY,ZY,ZY,,B3u#kˈv5Uj7E'WDV4_|JX5siAb?'=ѓwMkyrm4]5%m:k;RuE}즔*-֫sjr""Y}T3JgE"vVƈg}~ge}2ArV %ucY-6Vn8+ΊS_ ZQ/W3^b UT*#_j`SEjzo݁qcg[{uˀʇ׍`nv~|D]]P5 ~#^1 D-P+6Me0nnϞr5mwiw`-τ }CmwBK3E~L(. 4;{}{7V==Ηl+f Ck46WKF]YVciT㨯<~]X1)7-cO#ΡQ1V h D۟@?ܢScȂ,78*#ڀYXiYX12 `l z$I ?Fl+j:Ur"~xqNd:@aGZ"0#ቌ0#퍑 HOr3;޿nKk+ qA0"T]:իMۚyπԝ[Cy=.=u Xw(P?:JWB U)B;S:Yf)"ٸL=복\X^|}r/^˞Srv皍JsN,ZpUsD|'-Gc2L>.(onՂS+ '1)w07)wMNrÓrzR. ̄mK6'6}ɩ:^= 7adZaAnuY"vvkMisu2ӕOx%XnL~4$777\LCN4wr4ć 5>Vu_X=Y^Ygœ'N*cP}w?J0QŽ;}+NZ￝r3ь?f3.K͘i!cГ?9;6lm?͓?h3eDqfʶtlV)qc -u>U'1:fr^Z}BzOh]c -u̦}fW]=-'ŕӲ* NoOXM'U,)>jh ) Gf>A$ OW3>Oc3>Oo3\>O{3Ƕk9v3{瑆ɲ WXT"IPg͸Q^x'q8ϙ)e^]y&cH]qyL;p0CFXRY*~JwO4Mtb)ExE+xb'_,Ŗh˶IlO"( TEJ]gpY;li lJvb!+onVc(>_: JDSpV^ &I0OF¬?Y' daޟ,10Otzsqx^ cWp>ڰNZʾC.uSFR?BID !\G_tsSey3~-KI/l;_lI? ?Ci(yw*E凞N[PFCẶ޺@}dBm8Pf^ ?Η8P^#‹jiGF  -mWoCηr)ko2ztoDZ|;ߜ3U)l~0K%K9ʙչOR/ V+_NhWVxS6^Bv=i2+Z+ _a C;~*vuF;wm WJUKŢbQk`5XTY, ,&*b3E%ŢyX,Z6XTqX,xYj1>x>0o4&A?݌cTizN[q>Q;NkG u->M8Pj矊':Tgft lIudr'՝7+q{vN[6w1ŵvELGC0ݺ)w„bfJqEr9aJ,ϑ]: NRv̆wG#㝿cG3f_ ӓ=;+׾$(o [䗕ElqnnzaS(}x5dthtd{VoX kl,cc Xp Lr3VURY3wj?6t[ p H!sἕ֏,1g+flӭ ]"?˚T"xKrЮ%k}TNj;/[Suؠeި ~;Ξ~?E%{"JI'& {"0=ֽɋ+ g/`&bf^[AһvjA"JD4$OcP ݋gSQ%[r4Yv;f+隗 2{P8wV#mVFàF*m Sbs>;6X& ;˸$`,^`Ww r_._fxR67:/(Rpe@V+]ٙA' Գ}"|/Qc[K;Ii`~h 򜷅a^"6=sS5y~|v=USVLckv~/; f^mmx-T.cvh^采Pp fluRxoTXh 689|eԷև7F}{}k GhD(z28NVa$A6,훛rl27f7%vLx oT 2Yj0=X&7y~f;<ʒ5yU|aaNkh5nӬ\rk6:yOܲk ?xִPK)l8f=X њ|ymɯw[zmϯwOʯw[랺_׻-u ={d(E2w4l=cDL'h|8IN|g*Y (JER]Ž [lë/(kކpx?mEw(Ƙ\cLwcL11ӓ1g&s|[" ƚ`V~$˞w9<A";c*$ [%5kES+%ւ-SGQ/&0.ȼA`if{.ydv#DiNGޘ-~%G脅*R]@V>> 礞i5wQr^;(;8%A:EhZ@uty屵QE޴x)X Ba'XB`ᢺ9,aT3 paSjqw|,&~[]񒎿+!*ʨ#!,۩ߥS8# 󻖤>󧐒Z.иfh ͓g"M([MDAHI&;d$ DD&H0M7Ɏ(T|@ $PBŧ*!B*>=PO$/w2t.G-\Id3Q"W>r1#KBEpI6S>9T?[W8EBz"|h7*`SHL<y"1CbA I;3DKC jSֻV>@M3IB{ h<eL Z3hDgv|}Ir_rɈג\pʧXS3^ק BEvݭF1a~9gӤ$Ϙex4_ 3&+ЄYk;;ۦ`4!u'I=YkSLo¡M×хJ}ģ[DqXA9 8 mgmzqTQ`HqMgν9)&"`De5p7`i~'eqmgx*MhQ;)iq>{&1XV^ٳUQ;%aMzi}:,].KN!tުKV]겼U筺toG쭺ToŨOY6㭺FU׀\H(8tL/s=c['ZLҒ;D ń rb0[J:|欄 2X#K:ybyAUu5" Xd!&~hjL/h9ۮ>Gn20&ÅKG0}BòmhfY }:Mev4Bt(~EYYH%P,Yq(e9pؚ#O_T!1z3GG=XP H< s^ː;S+TĕAyȩ/noXNx^8MW[b8 rfNn,?tl_Xy7|ǎQV忸Ja930f!n="b]"%b.+)N=SӪ_1:|ULjZb\h5ZW- SqբոjZ\eja*Z)UVkqJ0W-ZUF{ۈ2W-LU j\8Xs\Nb!-ʗ4:j_#C/aMJ=07,cM֐9e\aG]·dQA-U.f [,$=,Ϣ=x,#wa,?5FˆYϦ W5l_e܃}۰EA0Ұ 6|p90fb!daM2i)H42 XXL]ʟ5x ڻ.O_cK)\a$NFH{8FtJ:S2i@ˬ`4`Un]W&;sbںj}W虼vI$Keb$p1g35ߗF,Oēv5bnq/9˯0uM1@ئ11@vhL Zҡs ۙM~f78HxU6hx_L*fN,%~ W)Ӱ髬ΥلVױ¬$JD*E-S)c,MM{S#S0DljpR3ֲ=1$[ZI9١+_(.OnQDJ sb{,pv?=?R޾hG.c1E43D<]skftvi ̡955P?X VN%yNR1߳mlwf`4=%&^F gmpXo}\ [3\+Dp9UK-Q"{0K,m˘nW?:YjJIIC,*(/Yzj3W_D_Ҧ=*_Ao:=s6JW 'V G?^ubb0?Xpcsxd\ C l7M| X~:n> Hwsanm/ZoY.,+hcgYiH+;JKYVghiĴeQm,β&S;*rs;JvUvvm9βEe[βҸSY5vUVw1l;J ,,0dnmcfgYZowhjO q 6^`+-ł'2@s- "Nl-O'ds۶~Ť\~KIWLj3I[E$&Jb$k}lql[&s0S03000ӿ0ݓ++++̔o7w xhOmMRI‰2Et2d!FHBO#}.Ih͉R jc>M{@Dހ4Whi:7Qyjn1,6piw13n?l5i3~JqZw>;Ц<[8;%J0QEz-_wytl5ieT%h'Q"$%Ysbbv׬9OӞo5ߙLMpG#1ρ=yA+wQWm1khm`0X̆CKX;g7\hd̐X CbajH,L mH\2򽹊{N,Wa<nEKB+PeVҪu"6IۉUS$}^/g 'KH9bdL r_v'4-v'yvd^T&^FgϵVv9gFިU_8ayf~hTP@N C&ĐIK1dV C&mŐIk1d^ C&ŐI1db C&ct !bȤ2i#Lڈ!bH4Gb+ۈmz6bq+޸XoN7n'[ƭzcd76 zcñt76MzX19c=Xi#sڈ6b=Xi'sډvb=Xi)sZc2szX19c=t瘎\k>szn Fmzn+NznKR&c=d\ñk8sMzX5 0 h!mzXOVb=N'ډD;h)-zXOXOXOXOXob>֛&cI ޤXoF7i#֛Mډ&zvbIKޤXoZ71MLzp71MLzӱt73z3ެXoF7k#֛ZfzvbY;ެXoR7k-֛f&cXof8֛fcXof:{I4j^}&p3gz/<[j<{Eޙ׿mz:XU9g^/ Lc6U7Zf2+3k4}o#FX{+vbzۉ}o)Zddhppttt盏|o>[6b=Xo#[vb=Xo'[b=X7&c=h|ño:MzXon>֛cy ޼XoF7o#֛ۉzvbyK޼XoZ77Mzsp77Mzsӱt3QV^|Z׳c%xSm#{ ]^t.[x2l0֫~*2'ry|FcOR z%c|bX/m#KۈVbX/m'KۉҖbX/m-KMzX/5륆cpRӱ^j:[cXoBh#[-ڈzvbE;ޢXoRh)[-Lz h0- z ӱt0=zOcb6b6b6bVbvbvbvbbbb'ޓXhd8{2=LzOcg޳X|BFFFJNNNRRZl2{6= zφcgӱ޳X녏"q:d N5DbhCaX$NDûe+Y~d.L]fnnz0Bv-W -/uDza`EimK*n[g\zϒvfjcV^w[|/edm0u,\+dܗvq6u?83;dX;Q6Nx'/@׺ k${F"A`,5̌d8JeIjJ'ck?txz6r+39p8!8GC5~O+5G:ڈD-D2i#Ar2YeVe|l 2mo\&j8 /Gax͙xalsa҆݁4x"Vӏ;~*ɂvk/G[4aAm/ҹd¾hl;MZok{ݻIfbn-Ni1 Q/qqX@+}G:X9rۻtlvw}}'W͌6$/yb^Evqa.ϊ(=m^Mf+[ 3+-1]7]/ #m:h_e3Z*~j]V{hvJZwb{6.VZpq)f4]pv҄Uv{k&]2]lC|b bkab &{kn*X77]6]֕볕E TSrU{=?g,?ú*sa^C.Qsv-9 Avʮ5cMfW 4nx5C;5rQ'fP{{bDD_5TDҀEk~{N%"k2"?ұdD]q1۠9^c-̄f-9e;O,4kkvKdjl)C1n+FoP`mAH{*ks!B9T>:ek+}-VZwiar\,Lq06.qd( Ԉ ㍋]2ָ`" &C/*̍ `24.x"š[Z^*b; [ 10xkfkl64Zeh/YUuVnr4ܘg1_*CcU1e31<?a1a1U1UbU 37fj״Иii̯l&j6kmpͥevwԦ5:@! WRI5FE#T iR-Z sCranHҲRT$-/u﹖ORBKE[vXcb3 ,KEANӵF; D).784J Z6*iY5QI[ϪJڊv5ygOI d|5cxt Q0k}°Y5 þfa,a_0kL_smY%"T iBN4h_ NöczvL[}5m{ۅio0m -5Cز] ޖپ@htmW^юO-C `Եl2'Q׮Fj@,l0leQxz6p˻'gA?dw=H~ oZ?ڱg}ѹԛ<[ʠ m!yx= 2a](̳T< #AK%MLC%&^z!62GmEZkYkY+hwPϤ6v -:ܰ4xtagjjAsAЁ&n ^tgIRt$tQm'mX`v^ ˱"CʒRt.fvb"yե>֓*E R1INj%/LrW}\/M6;,R-{A+=eH/}ݗc:پoө_̝ /hԃ˴0N9[1 JoRNi Z05<zO?@.ȑo{zSx3=['۩tΤQpäroaR5CI@wڲgZ^B։>BZ=^BV {i]ڞZV+8_nN G.Q/9+na"#z #9}&dW\]rڢv=PW}LDŽ* R6Evu$4*΍YoW,ϩ鹨YWMK2!:Y?kxtTJyr*?'˿v0|ލ.6ZseMv4Q, ~4IzG';\k e3 t$sQɝ aS]xkR v^DїqmxJx.^?ھ|8[M5EʿJ}'V%C.;0~f_ <;:KRY軏_F`b;"Z\!O96@{eKhädF,"_̐ue Ŀ vvD99Mi^\b({ NI |M\Jr,%yXzqb1s+(C@9w7l+POd./,ƸB2mv gIAu9\Npl:h\ywb;'lHq|s!]UjǕ? <}lyN"<&";oCɱ==/.Wcޢe3TF9)3Ft3 qYt mkVE]=Y5u qd( Tv7bPp 1U9J;֪ٹzW|f6*mΖNJ $wRfณ2ٝ,Nŝ+| अ edߝNhINhщ <ጠ#!cc!S(?(>!S(ϭ9!S?(>kkN ֐G)\8(>k%I01 ]#̜ic{bҍe9OO_(n0'xK|W^@.J9T§L>e/{aR|u.ē#"_DmW;Q*H5 3зzXiJ3 _zBN8q.MUAWAv4Q JO\9a<[_*NNp*^#T¡Ij^TiM{S9NUSH?vUQ$=LPN]64؎6366=O xsCꠎ7=O0TJ79OxsCTʡJB=氇)TDo{(BMԍ-2\Nb!-kbp<ԙHu)RDl'dT[^0 I? ) saM|{"I-;pչNs<0vEU+x'r-L<paacJ_b"b&AH8pE4$ߓ͒ T}x|Dp%I߲0xzuwovB#p=왴mM5~19IrdM;#;7@X.۹soַ k8>zi ɶ5ҙR_JT"+5Xu_yzMӮYUv,[~]LDVo"/*qNHs8AjNd$_oΛޛ%yϭXg^m`ȵu?HN,]V&7]j1b,pl:ۜGhe[>b!J+ҿ8c.QlS#^طdgq_Vj{=l7^@4` '82!nκeNfprLx?&;"Rٷ^vkš(M͵jup[reK'=,l9ہ#IټwM),S;m]4ct7k;NSx%7x./F$Ҿ#gPU) 9rUk'_:7n~bƫϔƂ4?KfsaG=XD&y$LrIWS^ ~y%+vԷFb8W<*\t^bT7D*OV>ZBb8yW^b_gW49[ [F0I=pTls NryQ=o+mņE6d5Wfy͏҆#~y+6haUVhκКm ᭘x^XmVLf-8 2eAZrJsȵJLgBe+ل܄9pZ*;Ǫ:x덫8{R)etR\茶UDF p 2(j dGSj:f: P*1@3@}0@S#t}b>@>ޙ~^ >yVu T#H ] дs~㋰SZfKe@ ?u) "1v#Jϳ0Ԟ=!yos YHJ/JOqtqw sA,O-?G(G(?GXyq6aQ-G8-)^:_0B\u%^oqAl^=b@`uu R6^N|~mfsu\sς9lz{1ҖmR eǃ<=Hi?W!O|Әv}P8^0z $B͝;DI9X[MDkRsբQmGCFSrde=un!4zr07j]}}X]uVC7Lkp un~OAU9m[nbsաL>ʀ@דts}oC삛ӯ^iaBѽopٌd'J/pYPMZn9v‰W:(i;+7Z~NCPz5Jp|ӝG>uB4D\αPQ>BE_\;:*q;4y&w=Nc},i͉L~XíўSܬ.W+4uMSȊ;7M!+4qMSȊ6M!+4mMSȊ6M!+4iMSȊ{6M!+4W))_WR(CwzW`փwK5wVJ; n &44. v"t*RaTj4Ƭ5Ƭ5Ƭ5Ƭ5Ƭ5Ƭ5Ƭ 5Ƭ 5Ƭ 5Ƭ 5Ƭ 5Ƭ5Ƭ5Ƭ5Ƭ5Ŭ҂iY%J !dLC*U20 !T`BV4ҀiY%J!dLC*U/ !_BV4~iY)J)fՙHSt_:/^}AxYEK-桺/`p^{^} u_: G H^}izH Uݗu_l}Wt_ (^}P`yUihݗ^sv xkk*x _}̜t_G4=<^lV-\Wlu_V0a=@>0A/ͽ/cu_>t!}iZTK߁/t_Du_./0/ _@uK ݗNK󕲖 nEGk]SݗՆ u_'kc 뾰l0t_OZ/&/ƧPt_ӿi'}I9z-ݗٷZ/t_: ^}t_rOhK-@s[^}i)^}iKJWt_/ X-4)/ c0.hLsؘu_:3eu_@=FbMBn\6 !u_`@&7ԚIּX=|XI!|AP l"VܯiXq!b횆k"VܭiXq!b͚k"VܫiXq!bŭj"VܩiXq7k*4Vy1kwRV*E28⚕r\( K:les K\VX0uf O_ 3ΆOY6 ۟%.ٛ4'-!zbBhtδݣQmT7P۱DnShM6մh kjZ`^6/Z`L5-!N8P83hkǷk‹&&p{Ѷ9mK;r4ik4HXhg5iyj gJ|{\yQ,VE!R3oO9:;mȵxxAزp9=&alٮ$ #ZHc/S9Ov^WJdK!6skKM*8z 7wd[Y pRAX~bnS,XP(o@3WLpl eN3;v-{ba=zqٻ_4F^!$GX1 Z~ H4]9Re$lZbAlLiv _⃹ӓ8 g8|_i]ו/i{)Ij2BJk;e;{㧹}oo\js[{:l>Z]قE.+`$E3!tt_/ዸ!LvΎ. RhwydS!FfߪșhYtd<} OjB cqMR ]Qi?Ffy) ] 7sJSӹAq؎Mon/IS"u W8*?&p 5K ? Qh%S&m mwO]xP6LlP?>~/t^zкh)Ǵ8ڲe#%4pcy/G|ć#Q| (}fOw#՗4Μ4El/ӥ~&+H7Cx A45;g*1(P u\;Uvf+q##rE$l˭h.T;w.KfD}k%/KB%MѻÕK^!D, sv^)d3$j@nfb!T85|ʠoKwwVzg|>2u%Ox2ȂH߅~6M>j3u@#s" ,݄#w[;qu3;D x+ c!6|:Kw~M$5],6;bx|F\@p}w̨jdY0`9V @boZ$I_bߋ6j6W ~9,'×T=~f?P 6pp/N 9UI6[~:/k:kUE2OA+h;͞ɑYTkduϑ0x1<#*`vl^3p6ďS E=g38e6qL?c.t8G}extd= }^Fʼna6T_C 0@x'G(yXjRN»[1_KB-7E>*\5{KE|1CuIQ9Fm X`)JԂrv^|nA^+&rs)koX.] np$t3|SSU7uH.q?SAvT5uPE_v`h\2"A6(9~*:*K=gM < gs^nKw1P )`j XSD| [tq[+Vq,D#aZ+՘AB&c^ő@[BJה5%hM aϖq/;rr*,F{?c;zQIw6*'<WU<{ᄁ#*.1TwVx:\: 'XTfP%pmpF8"x ~Pf>T0W$芀ϩܔ~ǣo=]I]k.5A/n z!͓3 ":%$ͤL$n$";wB5(I~ܭ0Ӹ\!ouܔfX #.{Uzd z3la%֚01sYrT=;9[(AoG^-5l.M˹)QAV]P4>'n> )y9KPli2P#$y3Vx)TƧt @|Di^xӌ"x7$)çHet UH@ X,bq;;`+Rh} wsGJJ}||?O$V9ȤAbn V.X%pAyTL6#*yg;u  k$5U p ܊%x8YvpeJ4U+PnM3:] lR&T wMpW m,R9T߾YoUT t1O `F z8ϱ)M߹稬щ9Id79d/wC0脛K\py9Mܹ\1k.U4gt+t놮UzDp 7糘&`WhؑH7O{2 pG4nte[EΣX$gB~yEa"s'5C?OTO;'72bIAi3nLمH\U9_Џno)oz/$*hOUl~I7KW45+^QF&n_f]F.Sі-o0C%?8eBscu8N*JıDO Lw1تKyddY.xJCW(c/݋(Tt >+Ax5A)#π9v@[p?dO3ZS /(?"7f" >KhۯQ42LK#340Pv&u&thGgUUA2Ճ;=u;߄C+dε=L V52Dt7qM@L{IzٷɯvByn[V.~i""}`˨M8w|=4/SlVq̲R'1]Nc;ߎg'o| %`{O%ݤMr Jq\6!غ_ QH/cI0sy׃^Nc"}]'UCFrb YB&.i\B~/|ABƟ(Xʫ3>!~TABxZW!2$Wہ hZO+9lݙ:%Qş5]Z9"K#%>eD giܐ)=[RRayF=|Rh5)l3eiyc&)2қ*g[4+ h9.-?[7Ukt /Y×^6|Ò5QQ{k|/X;WAQpRy#DL?Gg &*Ĩ:9d yE'╱߅A VҒ%'_6\/KS蛑|cYJh8!8\#ӇGuJV:Z/10*T X :'GFZ]`J~{x!WUot;Ei@ h+\Z]T=&  ,/HtR&^ms~Zi rKlj߰|re8E;B2~0yشJ,X*ZRERRsԤ"k R#vn8gJdHvJ5+s|)5N)1MpwS9.A$GO0HpD+2 A .9KzxYo }kFs f=EiZ< }SGj;jVVȱ+AQ\AZ,kxj 8&<_?&P`Pv%#}mdzv b Gʜn/~ QV[em16NTMQ}A!z&KRJKJXH7Iq+AOoz Ԉ<oXrNrc#޸Д _MR\%q_ pP8:7Qz(#qo] \!Vtg|ipߊ]ۯNˍ@oı<:xNdo.G"ɲ]cY{uju>OAz=4N4Gy73zOInKK]R6# KLq=mR;NY19IŜa3o%{o/6WϽCO'=7_2x%xuHbM_|:dα# 3;̠ #4J@ދB8Ȏ 2x#bmg߯Б_a圂!![DCL5o!#T0d J$"[?] T0l?Ѷ *ԸʧTpmX]iIO;f<_WwudسLOg­P5*a.އ!\!K=߾ ype]!p{ARW$ Y^x|J gFL &'Ͻ SZ,bbKbCK ٔH]tVM NFf Dic%uW CPrm;r0w@{Q<0hc[ -=gsu'b ?(vo?y`.Q{FecsnLjz~QЇ  U?g^{{"EbMmEF:cS\s {$TZoae$O$zUn ⩼NBB//C8S)%^LexJG-xE/1+h-؎:/j9BAvTH#TsV9Kh%0hW[ޭ*FK%K@m7(8շ z@ ?=uWWțGo+]lPTx.h X-ՊqOicgY{4[Dk[uo@5y$LiWV/ų2BIzSd47s\&~TP_)R*yÁrQ'RUYT<ƻ=h_?%;.rq{}Q`?tr⯁>r_J#"Nq/uNt3/CQ ?cEvW Rdf5%TuyнͬR o>ObA#ÿ2ہW; :I;4vdDQfA:J[7c {~es!HduGAN5? M$/V@ĭ ,"#x#G/s IB;hO"[m;] _B'K\3,r z}ܘtg%I6&SuU/WwU6bƉt|YrGq-ԙ-Znho!ʥ!Ed ΟYI 3yͣR„%gՆ bNyͲsuw^B=[$SxܢQ6v3 Zeb1UPhR~4ſ'IR+rٖbȱ)"{Q-׀Ћ!$_B34 FR{} mFh }*s $NVڠٿс0ܲvne hSQY.w5)=Wؾ*u1ԛ4>dj&PW-[Cs,81d&m,T&xœЍUl_uwZƶB@-^٩*i|ԺGqPE_9 ¨n@T)tQjyΰS,_/3K4 [䩸/#CwX4~hq1{e%g*(]2+w~{K%z "W[Hx)$B6K 0 Y w4 q$z-Er b:DHvˈK9ٷҿxSrxhOUg$qA`4k.d/]0JrJ\OSP|"az%/y~e+ Itŭ̄X.g4[\"## 2mi_^9ݯhxb3rR3?qrro/LKLw$$묉p=;4ip "UO\4if)Z's1Ť$ Yly]E:)Ej^~r׍avHWa\qQÏBc p;|Jߧ.*8zlGA8Vɚk(\[Y% q,TKZC| ?ލnb*n{~4BMTUg4/|=%f5I+LF a*pؿډ|ñWLȇ=y8 $N?u}l/:9|l{BlT* L.=ǡiĻQ? zcJHx6ӭ+ilG3t,8bف{'49FxOCRl/Rr »Kw4`N訐9 B& ;D+4dD,?Ӏis3B 0'dWȴ6h|GwyrG[]8tu{D '͢i647 7\e|L'3S=ۉT?)&a\BV@^h,HпyC :v :2? W9rzti{g@\fvDrR#N W }XN,^V%Q9 [ݎ䘟aW1sS\0wHL3sNsH'y ɑaqjo:G;$b$òpjWdtXM{:☿:ɍLVPi;I?8rz-`Yr>G;Xi ~7 UwV=P>l\wLc942b✘oR\].i|L|2Z@#sfDAl| 9vDAu"g2HnӐdGȯ0۠-1$^#NJxDr[Li7՗4Y `D>tFq_}6Y篑ܫǽpiRz_ciMvl3&}Cm,(tQ:ُ[ e f2>=}_?XO:EN CWUJ8k/7inQkD Q/pj@i^ P {a6S8o)j =o_Ip,f=NPMٔSmfs:C0#.d2x;covq\*:qGke/Ygjēr$t;L x7bθõ:󭗊nȻ:E4!>ɑ7WQ9r ^=9t>yxK^ I_튯%i~<-]G͢[)?S/IJ)xϵ$R&{.=8ڔGK<$W?W(u˻go0ЉKhկus{VPgAA8ZR| 4s=dX=4 V]d{;>|u8~:yE,roN*Y ;[cA\÷delwOTHT3r}^IG.lg^7~J~(r o)JҊ}!y8OCX `zDT^@=qW((+q9AEMf\$ (X/|zŐt^$[>~"^/tdgޝiAJ(q SVQ Oa|^F򻝌mn]ꌾ <֏&hyrw /6\zrmb] &(> wI.kT`Oc\GCu/ogVr/Hj?oX0S\>FiAm;>KVYb^P#h![Ƭ\v l+[  e C?dx:U׹;j}Cb>RԄS2ҒꖊdܭbO$ 1[h1S~k6]Uſo.!wވuMOC#fF]-yRs}%>3y2` vHu b%%?/ 4C%)[kq1rYR';r-r3ggw\:=8 ΣԎDVUC\r$)ò1qO>uKNRrxUL˜YT|[Roo-θz}hMY b@3#扶§s#qoG;ptQN pC {s*s{; bt\e=)Tl0"6H(g  yAj ߷DzHH.U4?]ED5 Khle<6}.e$[!4C ypՕz7U690I^t[}}P >]֯6}~oU򐟿}&3/[$r!ܿ1s(Pt lϪׇ/_?[o,sӿ\N9_zqp菆wO_W&ttE;uzaDvlUc4,zo7/忬΅5򷽋q闝ÿgon.o__v{ouo/7~,ѩ\\5l]{=;_zjlac㍯y6׿.~y %z^Ӷ?D뎕׵?~U^'xsRIW; .8cO7FM͟n}M=?M[za7:/}z`?߁KWۍ'=QuV?eZ{u5aoܯ [yv5ScW?>wwo װtC nxQh(G۷߭_>~[Eyӿtoࠩ)~=tn7ݛ .zTxqO;,LP-[N~{UPz}7 JI?ߌIZ?^ЫAPp߾W-ۻwr9ív8Y!חwֻ_[:8.N:P_xs_>~֚r|_o~4sVp{u?4|;_zk9l8lv[ȟscvrJ .wy=_] /cH|CsEe+Uw?h |N\As}ݕAO.7Am;:Hu\\U=\=\_:7rQS$ҧ,ASu;h}J$] G׻뛫^G\].)cUD8,):$[Tѻv.dz 6{ˮtn/8 T_Ǭw~p{\zyDv7a?ï__wM⇷_@(^=ww_ekGt9N?s?>S ܝluFa7O)ԙW5pK?'|}:?c_$Xy\{!W^^BnmGZ/,Fqi6& S[YZΉ,Q_7 |/Ȟj1=ٔ>\Cx-K֧P^)SJ@jnwaB]{z3"'/^8p?J#~RKY>;d~?GgHRoW|`wL$1#~vi~R;͒w)ӓ=;qOcO„=xbO?t24rd'&! -#,/6?QǺ2|/~X DHnSTJ_tx7ZG^:G.&> }St/KлCHz|u+WCR;dno'Et_*6p%h==~O^ )7u_~z)XO GC99.Zwvlv&Eql}-XuV:Xyګc{{[@Z}}|ߋ4eưs@^#U8a$b; vb*oԛxg]msz>q[*|8Q+W]{׳_sF/pU}gdtmՂӋ}Oa?4sx^u`zY^?x.rxP䣹l4onwz!oյVi ƴwYZ|wܗ\We+G +6縗>8hv! +Ws|wOó؃vv{uZg^8жuq lO_;%֬W۳gK=SAob4tAC=4f^_ s*9h8sP?惆 N㧝sq59 *LEN/@Yͤy]?\]\\G;="usQ/J#z׍AYxGj$MRXiں'.6xfWZ^-嵋Z0OU73ZYwfm؞p/%N kz(-Z૫E׹iW69 .eC7z#U՗K{ F%$NHI7m]ubp[(!W"=nZo\u{nU-3zUB]+Sں˿[^՗نsrPu{um\`v9^jo8\5tyQ\8NwwOJS7:;C׎zO\5b}qi^:2 Nlƚԫ) xTn';2p?1GK=;^3o?*sC> =?Qpc\x0#lTCnrwtUW>G5u3 !IԮj]A:Ѯuó^68jט;7ȡƿ>oep'qJV6~]*}v ɠ=4s ZEщBlE0)i@)K{We|Q2fںgv`^b:E%>[҆32[jBT~QKxãR\t~OӨR>Q(;JMFpdߎnf)Nn}%}-^]-R ߶P"jr*lԕ5G~v#oVOxsO ӫ t֨sYcgm&C{qUYxh6kXƕ_کjy,{rG5 2]CW2gȳtM\+8g8E+hyހ\4NA.J.^mO΋h'%Ӯ?tT>&.%֯ \Vvk" >QIj4.%%~A+6 ; ږ輆d׮ʻ{aPycg5-4WLWӿ:xf}s3a] IIv'-+ɿ%?&ߺEȁps;/5<^ GB#9!|Mʯay-tk'#?"čUK?jEo-Jn1[2ZIF^ =  B( óxjv0"Ơ¦\ĸi&ԔB]5`tXKCM3k$\kQ{/Tm~_9ۻpV=)6,:Vq{JW $s5sqs5R-x==IL:i(9MV&_M'w>MYlR/^nū$O5{{"rnTNN|Ʈ^Fz5Pˬ?!y^ŶqXzR֨~ڝ"R!R{jf8<{?vޖu?'([p_^z'C y{QVmUL* CFY6נmxT|N{^+R?I%6Np(gYl,5B;K;ck92R^`,(>0 w-|'*'O4Ct!j8겦y9{u9Sbg5D,~ggQ~x(h, EA_1gQЂC:#QEA7}(hӋ`ox#R nt\}<6njڣH:Ջp :a(~KPslNc!^6ZB/j^V7Da=5)n, %zݫS亄=fy֪i7cxJ-)v;2#ZgӺZ{ïWժܺRR*!bqƅM#bT"S7gP^hvI/vvEy絚k~k V׹&8_ٵ47qz5I+NZfs5]k ˱}_[1@G8 G9s Y1Svf֛M=@ȸ".uNiMC?C;S#|C װ=#ɻhtzt; !јk~m|pyqSo1Pe{Wm[fNn?w gy?kobbg~k7g69_w<5r̄Pz}h@|kBgx#R]ZCZ272DL[]v~5ᅜJϲ“DN;Q;d8՟6*r(׳zyv{=UuэܳaaӲR"]Yp{l(ȉ({M_ӕ덃U"9Zmп_~b*M C k*5 8ARM?QnT7Q椶VA!z?<ʁ&مj4 _ .t"^ݧ^hYDlw]mPթ<Ƌ|w|y:ak~9k9b`^Oۼۆ dx53$vvjxwغ$@Gh`ys.h(s?m).:.O=d%%/8aƳWnЯDY~%2yeVo?8dQԋˆGR?iM\6ga*) >4׷:ۅL8I6SN1JShgٗq΅qȿ״'.pfĮGHr)i~Tzբ/ *m$=hgY\m^AC:HoZ?.r~mv-_'U dD=jqV=gAr?[k+Ξ#oƞU7ш۰?K@mϊ(EDZFYQ(ܮduӠWުu2fBߺJ9hgL@HC&X8 LhS'A"NZlwU3wжv~m24G&U&eGxė î{cxu/Vٝ$ZnG#逵ιtX:; `Pqroٍ)="oP??{_.%I$^UȈvy齤"{̻MlR`yZYClk=*l%\4Iٹ0Ƽ #^6Y raftV|X:|j,V4\fsըB3 poBeoꨶ?ē#"u2 e{BW GݳFt9F 6ՁM+lFޜnKGw RSz^ iV&J۶Ym ,As:l@,\[d\U*ב9Xm=͠:~+@X5QCXAcHfMMűH|_%ԽPa¡F)SЧa6iI8Y*ͪ4/sܯ&nӍΠz`ӓ=~j:΅ev<^+ ^֌~{Q5HcA8Ưjf^71c-}Gu4-7IC]%F~-`v\Kû_RY RiϪ؁z{.溭[O\6!Fڡ?nIt wpOt.X3;p}qޠV?^auՏ\j>s>3ht|]V\&iY= Qlg(:g!WB(2,DQ??mwrB7fe(Pe>cT/>'s[ & @|>;B 4t6wn56oN s򭹻1hg'9r By5Z2O[hgPIFrUZNƅPer&3y+`Mb ?B7BvA[XydBiB#uSG Po\ǫpԕ;xv:i嶺0㮝sUXv? Jj07?.fF?W0{qQ74W rXzAWn_-$> 4eW˗ k Zٕ\MSo9n6@ j (rstss=+qeS$P׎&, U , M, szWGW5{ pS=r DHB]8ghą9g7nI{EsqijyT0jewͫ F* /ڼ7 wT &:FW ھ{X+þo߿9v2ӯlz(꟨Ug#v4,|!;R6FxXe IW<'mu5qnE^EQ懽ذJ|gq ?Ν?2?9"by!]U?# ]^l<% pNQuGwoܕ|ht(L6p=8'6R]͵~scen5f?J‹wgOFtQSknM%T)j:_U:ew I"3b̔S".p,HF`,:|{!!qU0mIoX.$7Sqg1ʄVjnG:t"2 5@6ZuMTȤ:Dh,aZ5@>NQ/M#1tv/{P F*pr72g2 AE~IP {zO#SBf~+yE^(' XT+HLY(gJ5m ȲG,n)OUtꥉi[O_:ӊ-_SJ#AQ ΤT5/R^ւZr5bppaqewיNjR 尠DObI|y"4 CYР]+?_9CFwVa!4n 2{o*=i'n7Sm/-BɎt5J'Yu,,H%%ĵa8;?*dHE"4Y$rZĔ=O{xYD,nogO zʫ^Vss8'nf9/Kt&6s?IW{d auDibp:TQnjwX„!LռO%Cu^ayLw1@D KEqe4*{\:hFɔo4);#GL"ʎOqIQj3y KCP}@Ku%47*X^K@4gQA[C$=(u/݀Ai˳EeCHKp`RDZS4A _5P#FMUvBꂮi`HSy $J @өtg(C d>q(s=ICG5\o mo塎@A2+fd P ~[h,F1e M#,,7{%*, ԯΟ.ա*֥q:͟v$!dYi9VnsOK]ﱽO7oq0O"M j#Kaz 6RО/kst΋ Khg_m}6MA5u9YG0e[զm8k&`mӉ;a@}3JU-g?]ԥ+%#vT0N1έ: xF\&7VP6E:?*1& 6z:4VDcUKQ/٦S:J-F&&sXn)Rڼ9w*XtjB,DPՁkي,F:mi0֞VO'8~4Y`tF,0j7eQ?~ nj0|Z  n_䳬JhX*3eitʈiƥ4qL9^r|mG񓿜W$JŮ}%PB4wA=Yz+j[]#]ujX${&M󷋫pYOR&))ʇz W5Y[QӅVԦhvk0.u]o'ӳ:~Dj ('OщxH  Ζf&ʃkL{M]ػ,h>HfYb3 db?ɗ33֑n ;R=_}bAL9 o9:VOMI:Mq:-17;M;E4:R5ܶ@B ߐof֥~1TlFl5;^ TGZ]Ihg*X6g2X/Mg#3McYGYY# Ib/ڳczi#ӻ>ŝL  -26CaQ aK vlU;i6Bqp~ >a`'M ;' XK~iݚ<4JJ]1,4m.Mr(KAU# `AnVt'w5|#8uY}Վ'b۴愾*S\uuƠ:c>>i{n1NNZ1^p v_ V5ZwME0Q FQ|>'2m M#,5У<2EPȔ(j&kǵg.ת1k*̩?YcWtrdo%5F4 S;#Gr<9RCvyqڿ7oo( fI0Ċ)_.] ͏7Sqg1u=1N',_\]̈́ o5,w yCAv"UA机._F*]0"f!njѤ3 .&N^VxTdlT$᳟i~Ckjb?PKKp..ed%J-s\7h{%k>6p&F6 BsZ y뚃Cj$ +Q) $ =7#RZHĹO] Y3p|>p3A yF,bG_:[i"ôsF_fkP w 1~!zi F· #mf1t(|t6S%[z҃mf3#kZ /@&L&]}xY7';tZ[)d`vQƲ (Geܐ\`L$gN<-GC\z=FbyleX&& &r`u)CE$27#8%y=H {3A7Q:jW`9':ج35exMdx4$@GxxT9l׽p}=KY,^KD / # 릋%7H%&($&o1=PēɑxvӐxr䙉F-ES1Qau6F \"`,FVjdvvFZ^ p隒a,\G!_4Z>6MAU\xجV?qJH-i+c-DaT?fK$V;yEl$I *) vz25O0q*zj *_b?LHpA溨X̻ 쏍DUy, xl'i%.{'}8c,nЫ^R0*޻M MnXfaړol2֩J ڱ@Zh䁬H;? |򯘞GIh[uR-繄@ImEJzVvzN!axleOɰ_4&ydN :UF!ߵrj@b'J؆3KejP25 "ązւ|%s(_-uYck3rdRy xIq]z2mJYVZtRip1UC,14Il&(eqlMcSPUϛGf5Y܏Tf߾wᳪ:y?(}Y{UUHaMCk`yݿUBʫ5p_)[@},~coiAf&IS!$e8l.5uʠΐY Tg(1p"RuyP$/5+w~ZWH?Kӧ%2=I3rdz<i8HnPԚ˽@hZ_&-C{fEd"WZfk)b+āiHzz*Azɝ. kvXA|v=F MakH5:QtF0+Cl}-h{iBJ-0*F1Tt1^}QJyU%FS%|Azwĉ9W]%Nsp4Hs. ^ /ZyV m9*QgYyu^=)imBi^pn=Ku+/weiվ߉%%hW{/.gWY~S (S %*}EK6:w1`wLvGed ]}8=a,"Rwf2tFh-7za?+zsHܦG)g((rA5G7Sqg17IBkN:5=X'+VfxQq21EUi* @BUSF (*uCQUd%&0K# >*H >Twd|jNM%2XqArnNj8}z$^Ks/b'$54- j tcN" */i tב:pSC* %AV2?2 S - ]aFPbw05{IEIesĝ5df\ ď߿{[)by7Ȱٯ> |<kܯs]dX=ٯr?0ҝ+Cz) \9yX>NHRYX:βP Otc$q43)K Nm/P2PV(agңnwFETt@`'p@2QR7렀_T7b*>Ryz5Jh1 R-qB*,DɉNX*}ŸfD.T qa2Q:0QPL(ٺ c?sx>߷Aa?LnA7;yHjߧgv-CoA/~43Q=dؠ5Sta)(B 0jx+F ?~&~H6&MR[9;^@?c P2fZ򒿑Y9˖VۮiUZʄH[t׏k^MDUitO s6/Tz}EݪJ *m:b@T`vTc&a\l/PQOH#'/#k_4q!Rxϛ%+!\u6Y &sI,\R+յU| elA 0k՛`ws fO J$| %* ʕ=~M"Vo%`>R Nӿ[?K[R3,!aˀZ:]Ё;NCY@2pn>"~_Y `xw?YfFIo;1$含?|=gIa=T/1Cub:9D g?SB!6,+DVg RAnWs'GӶQAwCqAt:Xqpb+$cRa5%H#B4aw#hC&I\C`ʹ. rEf<ؚDRkJTyLŝvPv몋oU25j/ HT)Ü2SP+"J\/Prh+EIZ}#0MEӷm똴n:Gd Wmݪjk |r+xT  w􆒭 4ChUh(/[X{a[X-$d0Џ,nTt K( .yJ==(,Lc1NNVۉ[PжD8x܉pm1]Cej/-_$ձ5'0&еmdk2 ؁&gAŰ,U{ofk$U- Q=Ώ=]D+h3.+Y&A.Yd%4l9 @f'/,;HNꮣGr va*?X a$6;0*Y_G:t"2I9[t>¨ffa!V/!r 8G换ԜEG9_Z׋,hOGDѼPy⹟ˌ{x˦P$LMxJt-) ׀ 4W0l0M;7/p .zeµ-\а𵭎/dH(E2E5YV @:[AR2wZ﫺:7;PdލBP4kC=A]4NR,gj"]ˆQKh ͓$YY_/6^tR}0 ~\h"D:Sؙ דEDވjP6H+pzOkEɦy3ڳ1J0js}H RTn/GT+\lU| #hh;]5sSz?Zs ӿ ^$[>o>D $nǏIQЋ=͍jiնa2wrpD0A֓[F4PR5DM ;#^Y\jU$^k./>n ׶)Y^J'hNOFCKvṱa~En c$ m26%IB+h$%aV 똦 ]ϱK.m#O 3B0ބXmh$t½ p~8NqtxUw}1b 0@dިjB1K&R+M"_ %˘_2lct cWsh]nHG$X㌜<(MbGOʑs\ ndu6Aq`7;ŬO l %G?̊q` J3iduFYgdU#GLdEMJ\ʴTۘ1V7.˴BIYx"m7\u^1[Wt4=8;Ukwn/%4!?tfo 䣿,=Ku-XV]a-j7 +ڂ ~KĘѼCki5s̘ F̆>I9#nd ?!>cٿ.1&`ybS6h<{xr8޽ =l[i+5]cV& c8F2M[8g#qm1xȑ6xmGC3ύ` j\ 4So.uBS̺2ϲu`&MiXN-λT |Kٜ,sQ6 $C ʽ࢝9cUC^Qv0S8;?5zZx.Np 2]MYj>al5t5%U;{ƴEpn'|kuTt{DvvpLACy"7@Bd# lzA{SUGr < HUb^65 <Auf̢ł1}g'WB\6lH,.r!E7uQTY  Fk|?҉\ IjDOVt՝-SfPΡcErɢ3r$OpfG\5pu45Jе-Sd9}=d2iCR_.b%ml<+I{-/%/WPJw"*y0+*M E VpR4%=zImqߛ`T=Sq_k,4TeM:dtteLz=`+kJJq| $֯Y }xipuԿHOSqX cX|R;(K3iD)h]I@=5^'BmAp" yR̉ {_s"|D8&9NˑR!9?\F[-eh¼RP"p[8$J+&9ȑ!9x~dtJ2YfUEEG]1mTYIg&>Ճfih7#L Q}ǁ=N:7Zq0]G)q˲> QPqI>I>ە^8Tm)2I@kǐb3 W92zp' j7ϗjd:U7{F d'Zt2 dhTHIsY7 A7yI"4gDlSG(g$kV >ڷ3v k"u<88X0ܱy݂AOCa7ͣx(F.dIZ ~M5V4I2tFhʟq>ez1W C ɡ.rhKc4 9~ A\ g_p1LЩdu3gRz-&7jW.g(su>(MF 7jQiuk E)kJRWI3rFEZ) 2MpDt|GٚIGgHƣ6~%KiK}Gcb^ߑkZ8B19xs|G 48[ |GIsr$Qy uQ&NwT'g,F>+u{Efe`DYZKAaNCSR|I/~lrԫ0o?Yxm~۰?{TFqO$38f6J^eOdZޛtUK»4V2|ڮa8=6.lM"`UMX|m˭N_McZn XnZ8&CUE[,u/{L‚ !`Miֳhx8Ra0N&xg[dK׳VCL`e e|bҖ-㓎7fOn1K?ɋ,CʤI3rlXnj:o@ 5g~o D |??(`CC*RlXd|N>o\Gk\VúWX"BO5}0FK޴ЌwX{ݗ( ca&wfNqoƤV R%-sHGҊ biWYy&ox&s;gſ/*޺z/(*YF7#|-Jˠ9"^KѠ1R6@d>*f~P0fj];Hh-Iv~C U p;%T[ƫda[3nەIK&M鞑3lWV&ە3vej㹌vechGo@RAJS$99ů%0q۰M$Dž2p#IʚHʅRpnb|H )X6|iJ6ڗmӆw|#4I6TT?3 {]o6dS W zEiLu>m)&TL6|fZC%HM_m֟W'[9EGJsqeMF:D S)]%48='gDDI9ul7:]6V×85/%4&Qg䌆t/*3pNIIb`z1|m:loI(3r$ʷ<_TG|y~.9hF1WkR`"R— wiDis(QI99#JJouTmXΔ̿e3_|+(_E|]7 =&Qu(#iu<#G\GSq񸎗UE|oN@߻r[%ZIg+#ngk.[%OkΖ=T@i1$WE"Iwd99̧F'!<^t1x<Ze5K^Lȟ#m!?C 7Ki ?LLg9s!y]3a @vFVȟ& G.)Qurba̿٨p`|vIepʌy0 eMKKg7A.t@{W?5b ]C1ŭTb4YMqFΈ H8'GZCx~dᴼjkR)l nKVSTSW?j 0F-E$JRNk :՘fH3կʁvu?f2 %{\_xOlsh ҷLt>LV 'Wvm6{ œԶ,득di9Pi ~Cvm!RJVyc]JK)%y_&MR#K)cOE%?e)%ϐͰT@8zRK((*qRпF)k)ZsrFqG.̗Gq<-:0=3Rj)s-{R&f/kod-e.MRt@V?5G\H51蛩8@& jN:HLBȟ"UTno?M=U>4(@FG"B\uK;2,$7HZT[gp~V& jW{KYl_bSu6-:|9e(]dRCzeȋ)f>u&Xc6Q̴Ȭi6h?ސօ8"=HhZY#(@zaGtʵfxiO섕5>YF{E)hQ1̺2ZY=[Gp-]h]0ڬti=8~|IMdx,L(j`/a>~e$d_y ܣIm-־lp IQ"x+/f6*8x r+E~H[ˤ0&ɲEr'T7tǜ3~ BU%~3&ȑum1EȺ~KP8&lμ~CwJbQtH~&9QY$MV#cYы2otʪ:9c1YRo8QW[OWٞf.dA.M)]ua_(+L CQ&f7ޏxG 74EƸ?b-_>fo?f~$M`?&j lZüӾ?*j QгJY6Vde[IR,C>ei"+ [>ei" \gp\'pV{4fTޘ@}rVvuͤZ3rFcUҊ=֠FHڎŃej ėڹq0C'7i8#i}NA!#qpЦJOV:&=f[᠓x;&qй4&?+Uc-qt CAlmy 8h;Q" $$$HD@SAY@0 <c>S͎KfAJ3rFJJUڰ+yN߃)(JUTuP$:Mwyq2y$4 =#g,$}R 17 Zl T WtPEpqo똡.,T|Hy9n%TN**Hiy1$TӃ*k*0pY"KL*Ip9CHQ;*̃Y/U.zri"^v\4:Y:+ yTOj7Ax`%$8MNZApP>7G|?T3=Wp9OZ|4&dc;q8M*&qhDHZ*h%[D^w(X)jg\k5|zZk@xtN1Fa9LѲ"L:|9UYRpQcu)^fŲI(3r$J,$J32^,ŵ}1>CZsz٭f$LѼHKJz F321piaSSx8d3VeTNK`I@sr$<$O D3 j"X-UE\/"Qf"4y6k9_{`%4 "t<{W>Q 1 $jB3PI& Tu-oѵ 5J^AX~aZq'lWDPAlu4с)힢Ȃ4UZ Sd4Ml7Mse44DM^_)D[EFMT%h"GU|\ $)G;+-RT9 [Am]54QU!p-˔=0X9%Y9r|غj5 )cƑ[[2tJ >#O!O?2tN >&2d|u ǩ:il^'M mmaS ݇6@?P8\z_Lna%4}~ZHbcaPkmE6lb4. Ԫ.y 6Bzy\670z[Ͻ4ν0_^bѵKGӸhMX[ mЇ8ɲ=5OBtմlNzK͂uLtL2_Tuu4ox8DP6?N!yZ+y[daC&Vczt!vQI!aZ/!r ^AN+Ԩ־KA¾VI}^⛤*$O&8I0>J7^B/DtCjcsZ3_>h;a4Su\8cv ^/ҽj6Eӻɼgф*Rlp iKROSOSvcyh-g{2ɕ4 TҭZ@YZ_mWx`QERѻ+ |_+$Q}^;XF/I*Yӎ$KKO Ub|dS7_3i]e)=0FSȅa䞲,[dQT0Xr* A* o%x9&K ȑ!K y~di4YZxNXJ q/':kM>BֲEi齿X‚4Y[8_`mpn oF+Igki7b.2l|a(Qc Sۙmpzm?zv=[(kYF|,L6lSUŠUّ$#V̾Dî# 2Muؕį(>=TI` @7hk{dmcD֤ B*~ABKdD * :hf*,Ƹ6EjN:Hd𪹈8zbu;5 #aҏ ;,4#ZɣgkB,a{UgJBV|ؾ*}l^R{LEϑW?2*OL?E~\ S;$F~آ zFcQqbD =r*RL *pM ]UJaP2Fuz^$II8˼}7&1t ,YmZ;b^ 3e#G̯0oM>p`paEց&Yfbu:8)RZ ¤u(FZ>o :T1rO rUa_fdyp|l_ -G27?\_2 i(ؐ:ZwstB#)7*;{GԮY9:o;Qqg?ɗü](}ca]$]cH6AXAFdA?#}LEL264)Hžc+Bjʾ_%aCwW&e.A:s" ŌE-"oxHNO+!H48kZb &no&n0ĭYlvCv0dz'n)%5ϵ~P-A@IA(HuTalwZɠVl,f,AEٚ/SPCKP.^~-OwD4pUDzҫ*RUGzUXA@DƨZK*O*y$O^ɓW](O@5(x"haqzx__q"%e| Z*  +~{1 2LfL: աvej'L`HCB#rE/sǮHĴѕG쀒; L6-&!A?YܨX`t4 Siv/,@az[uY΃0i#-3݇.L&eH{`{$`?{ ;Kf1&4)<#}X+<*[L/EG3V߹:6 u֤` Puj)f%GՑ/E]`I`W0j.4PEOA:Yy8T_Wi ]Õ^XIyDDb}{lv>`J$dcf1I.4q'Y\kņ> bdԇ8AuH /*M`HiFCxۙ]D7; t AŽǀATZdgf1#AkTSQj$L'~հ~z#\Z9-v8SfyᎬNjZpM.l&H*9L6̋Fgt9A*)S+W4:C =,2Pn`+$ϵ#$uDA$LAt/@:Y: E%PV7y頻(]ءH+ D_ 9S;hk(uLѕmӒ6 Ú IUXXO?5atvXv3}IM "`I;( JFr0"@vɒF'Et'?vS>} djb+L)h#eIߧU%TaA;:$nyGp|jTUEDWS1B-fIjf1$$56B&^xjTbR.!}M";fpنTӰxi)a.h#SBYz;fPA5M6mHw_.aEvu*@T@YDq g \׳ j%Fx?q2jt[Ꮘ}r\G"ܷREB7@C|2JVQ@WȶU5\LCv59AXWY4&4 jR5 5P(m A(;*ע07v&{#4N}hNñ- UI؞e0%YQ0&bt(}|]_UFe_}\@Aʾ 2&24MT[eqM@]d_r_Ue&24}N}/ H\,EUPRu_SZ fSt.-Ƕy͞@GWð䣿/h)]}dݍS.˗GGPGP{F >J']=P~|j)ƯmP͕9%<=Gg3QhuXJ"ETd?֏tbCi{ҟu8M `y<);&qR_xIt3ռTnD=klƛ}K/-Y ǩ*_o|I3x?{7?i_mFaݤo]$EzR/}Q(NW"PL GXfUF~]`L tWSVƎК|cG+!} qMt`^Pķ3/jY0ghПh7_B S p54A_CkW,ݳR);Rm O!cӝLTIvE_~Y)`t{T)QEt{^Id{붡-< 2ݮ|OgqpYJ%t$߲蔪>)cXg۠ۿo!~vi6a *UK&8z0RD?jA2{daO:9\^"`$`mYP? >_hHw9 ,DRlD[u|m8\zҢfaԎuѩwfxyjRk0KilfM+q-G7&c?m~6iAJB*f_7Q5?mN栖0P_5HVMݚ aVƻaiNH{wBE|}ڻuT%X?qpa]w1v1;5x'+K ' BɜA].W!H0.2IEX̼8nYF YtZ(TקRNUfL/[[TYq"V1XFl-U'qWg>| .* !>\tr8pѩQF! .* y+sAW S=(!Jݗ[{*|ɭ-].bd# )uj|SE%gY^b,+ YWK78]9$Cv}'8X?3Px]n"QR8)TE?t_Q(WJMӣ:M7T]/ N~W\eZxT O o(p5l4y`&w#[e-KVz232ܿ͡țQcHȝPJv#Y.fVJ6Ӈ{ReFf޳l @,qIJT-K`-GY۪:h7 SEOe˸M_*YRXx Ly4xT*4be)ȞT!N YjʲfjnI*DҏYJA&Yy:|,6혦n3f|oӿ쇕.M6oTǯLqnq*m~ܰ@G]y5˸MKw$s̄3Ɣ65Ibs?ӹ$'ʌ'vQ@T8P9f<-v[!ڳq3l\fd0 [>Y^%B4.IdZ-ZkgyxPKu*bɎ@)`:gs?t+bx-c-瀨fKؒ#*wYob{48TLGہ~ev:⟔'d,z77?L 8z1BgػF/S1WI_W~HQpgݻSۯ/,s>QL[Xݖw/w1c}-rLtΟ}͎9?WA6VO4Ufl9+}'v~(JJiحWZ}N7j`"VGgK/שKζVnV(OD(abpw_,")2#tDGE?IԌ)DX :,V IɌ?p>Y>Swġ7{Zm&>"tVzs6KqYٛ#ܕ4rf8D!)ҴWԺZ7VvFS٭-Rvؤx;3>Lu0SL3E3oJ$Y/,F#T'@wƪXU0_uI3b 2M~r?77=pb)k{|ićC7s 2s5K3{f*>/]M_& N ;s~q@yE[\-H;<3ZUh1EM3g R3ޟUֈ5+&g8t r,lAE-aKjXZUh.}EjN|Ma;ˈؽ-Gl}0^3f['D1l̜LvJ/{]ł(è)U/C'OEy1RE)yf/K:oއ_}MaP홵49秅)fE/NMI\USKld6 AlL6Ҹ T/;O;MSLyNYf M|S$h՗:7~e; Ddӟ՚\BhDٵHRC_%7OEm2J3~>3ߖ2i= d9d摾<Ϸ Ohd b\ܲ]Q-'Ph0a1$cݏ%oKZ3Iom3kaTҚ3~D:U=6̤^9g)f'vx;=əAt+d&zl%[.8S5Ƃ4:Qg=^o^v,ȬBiQd9GegQٙ[8QokNɣA$HۗܪJӮYj5r*71uQ`=~UnQogͲܥ->&\|,x8 Qo|#穿#zf13Z9),~m-A0BY@2K%ȑ>?΢ůQeVu^hk}}G>lrnV}]&>tH )~ɹg = T)q \(ʐ?$LygOɎ]dѣT'rXZɱv T;~r@ihRhShL)iT݃@h=+/km%?[RE4cM9ߗ̇I56Mr N''faHW70=O6:|f+f,U38z]sl<Ο{2݌:e2<f2Ǵy E]\ޝjNBKtOu򽬼$\kȯLTԄ m(h&w6q[پꐕ͙$ݑd8^jQYmbhq B= mO0MGB1 fV ~sWtY3ݏn~ U"(n*LjMFnR7uyebiz/|& >ԟE}f+6ש}XLMojyO$n$b:`'{.mqB;NeMoȩk貢҄L.\Λ'oZjMz-6e=a{g|1/8כY$]Cϛ~x_֛/oٛN)Mdc<j/~)tyQXI?{l)ӛ#]rL?%X=?ם݉DzB&楧kDx8;:N>]w^:LAV*S|+򶶎m$56Kr‰gnWt:bGo|] Y`[ 'ZmK P%.YdypbN=i9;9;iҬt`-o:21\Op= jfʘ9/]&vUxyzGOy=LgI~gȂ1{3fН?V>㬂"}I}.9}J+2wQPo^א5n a.3e+eop}B:Z,F[ʮi(8Mf|5+^7 }~a 29w/dgb=k/xZ%߽$JA"2׎ګ VGcҵ7oLI۶`znލs׸Vg/E)#4`­sˑ+Wy_3ȁɐT6CCٵCmBYgŊ|ד};(nn?ejoEc7u7pi~=_0z9DUXg(gv:_Ӌ21=ޓ AǀGDmF,5%vy#Q,}cmTc=7UϬ=,l2?& ȂTiJu Ҽ]SZxc#gp-X( nnv, z߽n]oݥ^.ͮʤV3Xܧ 1=UG?Uϱ&k3†X1pi6(gRoN^2(e{P# +٫1]j2͔_XK" ^,yAT6R̲(`v-lJj~X7nnCj~~"vf{vd#]E+VϷȴ8\zs 1enm}܆o3&zRF:pl  Y/^e$xFUCv@IYEi|Aƅ^e1̀dcB;S|Ϝ&k*{ٌ8~z~R|Ryel]FXGZ]t9N_EÛ9uvT/ìXI wc^[{4cetuDO~nkx jOf,S o?nR0'JwJ̃{MjgHX㧡.6uUsgm4@M3{>UTR'Yu4>y~d;ENV@Qq,Jxɞ%:@f jV&ǃ Tqt:Uk VFit$ =bEnfl*tv暉Sn(S&i`x" >y7C x(M3} ꢀ-0<|RfO]}}-b-; Ck֘5[󳷣;yO?ѻmw}Tu[1F}{Z?x7^$W׻_ s IwAݚ3pw VDw Iwefd7˪s]aR;_IvI͊6]MB0waYUi̩=f!4 ^4 ^! < "4މ?.Uww {O˱vn_.l;AxY$j=XF?yR=|!>?"A-o< TC,t߷m{g&ZU܇߶,6}'ۛ v.75 :Ws3apz/{\Z~|`Av9?kg+Ǽ9Gn6oq.&7#CǦ?pΎ33gy< ulBy>3#*TރTbEIm02As$TcWB×6owCu5 D!ߡ4e!@r;wfa釿=Y :lnfWWq Im\_e@x7}[~1yފsu2vŵ* K_]1{V.Vp. 9cgT፬rjlǖV1;x=I۾2` EZ2+ߧ9v*ltdS3+ H{ "n|M0_QORX}\7M\A؆f#uy :ZY 0fC/%߮>w P> -bjN/V%۞:zo==`6mLjJRLg2j?nQ '9 T؀+!0ׂ=|!r@buF~ `:i{T+yj%-Hvp’C<5EGGkeX%c#[Y;_YoS+㰲CVae9ݑUm3 qf$|[ZW;_Y`V}TKYِV{qljZt(pӬ8ut\#78o,0up$3B] eC%d!(kTGbyC$N Wڞ!VAm3%B׋HzpEUn} ױP ,cBe2L|G!{WO*UE㎊U5EZ8n!aSK) TC)fƚȘ^K B fpP^K`ECUuntCB5,v^r9ěd1pdVⰴ}Ȩ^\0~{ŭkyXa$yس]b[`Q15&H[KXa$] $mujK,*&O<<Ao0 wt)!!OKtliK@j>V?ۊ+xm#9Zx`,V%EJk B!hm_IױPo<ЧB …#zN;̙sO`.tX0J?ytNz;CasGIn2w{Q]a9QO匯{â -CsS8mjn?;MtK̍3v].vC xLWic(됳prxRDg/N`9'^gun=?,]gA;swTv%=+ ,R;,4DmsnBFun{b?6m\߱R龋hLCOX??@J4g4'G[6v߫{C s!tr3o"6yk& k%#~3OX< j+ 29\u9 GD-n / lScZxƶ022 # $dhn_N6HB>XbV-E%'vO t2|&0N6e'{}[f;nw>"v-RO:` Ev0vIμ(4t޻ø< @ _c 舀qDۿ\4':^hٯΟ/]IwfDО Qz[v4I#xAÌ2=}U>frMUFom[\S\%>\].?+/~%A"wQ=#hv>" 8d(r0,~k#w7G/c͂]E[7bߠ*Ys#KwTm@le ǯ~5f0poof,b՘LKC/^M:Y(CFp"y QZ/n ]'q( &~ Iь{THF h,f]_sG3G{G"nz> guhF2ܒɭ7Q]N!650eDʇ٢a3A tA07$t8z{- X-RAnUė(:0%0/{:LϗNvwv{M>:i67֐߅2xhL}fxLxcMh}^4V68`n@ ۧ > 0KR[U뽛O&9 @>ncD2}UF 8$]NGO߅k(߅P E$i/v-j$` Á<2M [`lD 3(!( Tknb,@JsZ煵BLO%@  *6r`$a-t*dzM ?Hf9Mh] ݹmѝ;, oLczVb.}7Ͻ*U/e$H $Ѽ<0=v _3aI (_ӫzg' ][ NJ@Gg"/հl^}j={ bDz'T`*# >ʂwRRf,\ srT~wLbb.՟mȭ01mİG&${\=o$gCR  R-ݵofrH :C0t:.| !1LzL· Nm7:0uYPN4Bc)m:;6Z`qt ?l]-8Kz:WGӻ81$ c80o @S[Ƴ= ʥ qqz5as D?r3KZn2 [1 Ffw p8aGGմU q߆ Ej:V,X1\w/b` ){FF4MAHi˥ڎ1W| by"=bOO|Ff01oVHO -Xʗ)3R&ߛ@ Hg4 8|觛ZS,\Jh\]ɷ%1*`P!czi&C jO?3 ʠv:Tޭ0 nw?Z;:Huo 7IC3= V"TĒ.gg2sRS4u,$ ^hLJP5}W10kG<߯ <^֭OVK"ժ@M1}X ?CDh" txGFoxִ!OlAlxY3TfL#nË2l/b㫮y 6T9.2L֪P0نrRzqlpY4 4#قmyk{ vt?Q0Mz*Id6wLO%Q|*O(<.`o0ػO Y2c3vjTF;-`or>H7}>܄]c >6w,Yx4,y9(?Y!|Hgoͭ8vJd#GѮtq mfJOxDG:? ?Q_ڋ삕*eV\[jK̢FT+"8Ee *.j/n.\^q],׺;qFQ'fקXmV'BȪf&ZUCŬ*m}bqZs q+H_{JUu"C#s(ֱf? \zA؇ Uo'ե6E<}?puzFKZwS&( oQ1R%yTE0;X6?Y@|kztȫ wv?cܽM  *VBF '7xsq.6:yʭL:եaΪ1;|)Z*g6ަg/K_{n,٣{G[8_2!/VAQ:dkD[˺u| /LiP$\e >DdFک\CP|tw6'+m]17gtbFNaX-c4aޖ}A`ͅj;no*]/'ߒAԐ?*nUw-xLr t/_EU9Ye-( f ]~Ci揅Vc |ܟsz^o3VWUCQuQUŠwNw5Eef4PѮy助v>&h߽e{5ν3ugfݚbܔlYe,!`Z?B O7~ 5C5ӧ ϛ]u~&rHMwξnGK*G,FKw&>YW)`n!9)Ze`$$c+M8 ]ӑ ܵE&%S,XQu sAuNގA`1 Mhx AC_E?w[hjҎCڋ;wV?V1:`r']U[+is4 mkd:(Uc_r~0ЬBwoYQ^K(}$|o9 HlC&k^J(y',Ҕ2/&ݓ9 > OPCFAXu)j/:4T!(JݫlKV3\ޑpk؛ÒpB܂A..Ĺxfq)Ηpz+M&N>o~6`-3ڠA%!]dNt~¥w}X$9 ?}z;boR?m?3:%lmyγNrK kLإ6iGu^Y9LzFkfxAV==@ mFj*MQL_/]a<=[NXȅ'o՟[X]PF+zWZsc_4>so{TYq yr*3峣&+%R9lbJߑAxa*pp20BS.}`*.E(G%~d#bl04"re$0&'78t[VWWSm(D|>+vz`O*Q߽Aj&﯐Cґ$n;fl"a{kJ!LԐ\q-a M<7\XS֟:lاhygvcOZ=CZ  # ґ5/X/V(}sJUyS3l3 Tewd˫kT5 ]$ZD/b_0Q1 E&(BțjLP3$hٯ鴰aYtXWQ:ˇt@YSxm57pi|afRO4mG񓿜Us$V[-hzC]@܋OnA,c_]E`q 4ZigO7Ԑ9P3i&KgBzgH"b>FB'$ RSݳNsմ?rv&𰄌vK$R!7R`{:-C6Q3 {iAei2od 2 1u9Qs=TcL4@KnvUچm)UJXg[]ӕjcw+]6D/"@aWp'S,eskd V.*@)L֩/·UAIB#8j!;}Lj6^?Aa{֙%EpGpxe0D}ܛhb8|4iCM!o?|⯗/6; KyM.5飍 siMB@`š&&K⌕$݃Np4A|B[Z$,IeP)$ >d?Yma,GA1,7Oo2{λI7 CI:}*ӏ,c:}l4Yy^$V򎁏Mae׍c}xSd ,ek~;wn,^7v 9jeF 0lpе:t{7MҾUpȂAWtU])gne2g9Vu,5ʕ*ϕGlo՟Y| c:njlt/l廌bkYN?TXMj?,FzSAQY(O(k͆DlQ}5-h/VL"VVfPu骬Ux kNǽ@v"Pd5\LYWg |rZZuQ{y(ra 3PAl)G;h_ur l6F~?+Dsl6+HĤUJASG``z_r3D=7 N .Ա.[]RFKhoqkg$pQ6]<.BY< h)XI & *MsHzpr{Vc)nR{;38o HE"A==/ڛϳ섴K0/5=HgWRe%(\NqN=tE5x 3#Fojclj?2Re )seT]B8iŶ%.sFLٿ ?+vQ\?G;҄u4#t<$߮&" QsGG>d'ꪥ!2ڠ\!z^ǀEYHf2 3WOVI~ ةGS`P23pv(tᯮ,E^-ߞc?G4`-)~Gzt,ld3wܡ$g%kF:2λh>ɹ1IV<9K%mo~l!'3Ge kTlUK1"2AҮރ|>wR k8@E0VjR|,iP]g WPfjF:n^T[΃T䄽 Z8EU؞żco+FTyrAژ**ouPWUMFD + N٬Y6:Tcrgn'r$*A"!bH}g+wq#!w#/>7dXha P[qFs~h2xɻnlEafR4]TU}ߤ:S~?W"Nj9(>ELx9Ҹ LCKI?} :j3E RrVU"Ft` .z^OIE{| Օa{IaZd*Gb@[M1^_g8 V/)Db@]5)*Ս^1玴$(>/:p5}kJ${]SrIBf-B4% T]})۷+6|=CSvU-.IF ٺ4(4}W0mcY:Āi&<_Reh1kj@ U4zr󑻹*1PđNHFm+lxFkKXpjY.wMZoGޠ L; K.o+,b\Ql^:KZp3|/O27,?(ĺ]WA} /#ܖpnƽ z\5ldQ_f耞u)*Mo<6ݧ!ՔXgLmU2ʚڵ_&e_X3YkP,\v$fr#Y[edl׶% >|T) X'FHR`Y om(s?G(4n?2benhA:Ȧov(6 ^]$ dm.mk`|ӱH,F3[m5nkqlee#~#K0H 4VFɟƯŝK*Ri",^6efi60b|5M]ӽj&8,ЂCjm]?`|-ųkOVx+<"]U' @x?ŵaiU`uŖ+ ^5Zۇct g 8ibC [0IB6oiٕ{rna0v F7]$ vUq$+ pm](G2=$d^oW}w_'r `8"QZ~nZ~nyEŝzV[ D ]l]>6: -̂9 5]Ju|9{]_x\PxHԃᨹhIBdY[P G~M ^HmoPIiL3PD/צX=5Q<$fVZ?fs5O3-n4\,c{3z΂e'Ved "4?/!JS4 #,stӅ>V_~}\yjb `ڽVpMG*RɎUc ٱXX/ǎU} coZUn"bÓ|]E=엁I`J_SwX\\]ݧ&l'!/¡WW7"D@+$rXhf6 Y!KV\d;ioS[vƜj00tq&ܤ[.Sz," ƽ}9ξZ.öyr;[W^,WE`e3<`u&а. j2 am7sEV?naTnrDJ7~۬6)/f_H;[BSL~'Ebi=H}.郇GLg=EU;jق]9 AaO,Z}3 ߮S94U PϞĖ{fEoR8F찬9wt*-lÝ  zy?4df|Y6=Z]5 ,JSmE涚$QAb,gLe jXv:H Wa(ꯎ>/T?cTl8P!oHC1hrF5yzZSuSޯ,]թ3'~Ge> Ef8"ȵ%Pe=hù=HꨀӪ{k/k͗l6qydbgL**bYX*eUЪ:r6$;(+J Vvw|/RgϱxlExC`(`IB}XaM2);Z(6mT%!θv>v5-J^*p> 8, WnGiB.C:|Mb0ǥ:9GGGe1BիoAȨ6ny E 2[v[G=odpMmdj18 5` N[u7?\G_NZ%O )b~q .E-oG]/oR?TV6q-3uvK[kAϥ4Q`{>mCXƇvͣ2fb/-kZ2CU0Ki(nhzt o?hA pWztlYl%%+{w,9b5lt~Fl؟`E8Q쏀+4keE5`^qگ'yhɺd[[m)%<@ # ]#\zIv$! r+YT]LȠQΫl.T J{^BR֬fnCEf}rFCLs۝sƅk\pG 4^HqFSןY>XoDA>*o r7K;860M^4ݛvF{^Za ^ (qP z1Xn޼GI4WW_!ÂX&D 2#vH):,_SUh>(#Rm+UNQsrͼKw\o%B̞G@IzhZa#M{!Ȣo"z%e1@mS,mܖ~ tkZJ+92Bq( y`q2@y'`HπPLs1 bAqt̀?HruBjItj8~HWO՟>N.Xך#l wN Gyʬs8VfQF[vDbL3f6iD|4ӂ3:V6JuP4X.ަ# ]y$Dy~t yXI!;]^n`!Fvewy2l؎Jp?7ߵ{ZF;M\^7}I.Tkǎhn\+*SGH,#S㾅nlƦ @ PG fA^hL&+ET8q~`,q#aP_Hs6ai*8|9i&$Pxo_$} 切:?*f?1!Ӄҏنr-;]ovRkph7,K䵮(g>3#]2ޱ`J~̳,ϮF2R̫ϳg)>a.Kxjh÷MloG1TkGEpnؕaks@E,wOU :֮f|o9]l؂XVG,K\V(=Z3|轃[ȵrtx_Bky([(U6=#mi߶ZjߘŞd-^Q- 3𛩸#G*:,3s[5|Mݧ9Z=ǀBamD"we߯[+@XWq}]ۋ;:kCsfPELBzho;XZgk#͆XP.[Fb,\h S_[u'5a&qݓi΅f, %_jT^ҏ'1/?f0akZtD vqaq y9p(u;hX~ӗ GupCTf g'&`d1JcV^='jw*$\lb\A^c9hKoNeR :i sNCLJ ig` oO>\tQؚh?nCpTђewZ@{XE4 MזDžtrM meȆ򷟃d/9_df9MhW0&D$&y|%0hi]DUy鴂mTS(_Tm/Yl?s.vVU~"Ę/rjj8jYVfac@ ..>0*6%~l@Yp& )D~ȃ5 dv)/t}`-C)?f=7ըmsy8#t84?p=rwXLbr Xv{uϫ ww. 4=50ۊ?pZDA}\Cd?pUcr`>dH7>1xZ-$4EtE:@ũ|Nr*0x[HP]~och} hFpC"Zu;T`A>okpUH@0{.=m#5ZL$9$]uyrh6n_@wzCx]B2~7 ǝ8͓%N4 %KD墻oBo 6 VAb.@2Na2#j`b=iaq3v1Rf9 Ӭ͠rQcu-tr^]@D(uEn!Xǻ{[#P^R86,bWOf쩮bGz9¶:LuֲܪY!~t_mB8=Z&`֞g@YDHv},s{F =4CGkUy] sw/#b(ZO}8<N5 ^xa6u o!Og鶛%Q^3a77)lD#ޤȞn64/f12"?x $%  ]vp*HEv$roqE_Nӑ$V|;GB(66\ujbmTIPi^yqK,ln0Y/Div"7ֵ6{L ]Amb8)r>:z~!Gx;~D n8'+\b4y{qYq[USʷN嶕Ieg=ڊh̊cD;Eg#<;ˈ:shZ~kVSFy?IEgNV{ڒ v%DtMс7Yq~x}pg@3. B Tu/z:Ye4AQ^+7ӣV88 M)sgoSʴZ_.46xcc&'3 EZǦߞ浦֞/{K@iJq0*P wBb*fl:kL܀T֟ ~J3hZ/;$xX dߖ5/ݳdZ蛩MSn$ߧg%%1,ڪ h_=VQ࠰;\^ XZy{e.fk]p)ȕw #Gu'fTb|blvmfU0 _vi@(Epׁ^Fi~Q9;כ%cȖ3ի+ڑV:#IVsC/?f|?qr۾kP)h r ap$yG^hgL[3r-Ò$=-frf)6᧙,b̜aй_kl=~OlS|X z_iH֏Q]!H2U%>q=7#o-0fΧoz aD47ͦBX $ޫ{#\qPmhyh i- 6x 봳9|rI}<@Rl9K[y.Y גo|vm~{ ئ{7reӘ噫'CY? eqWx2R e坤yQA$i.-hZ' 9Q PXE}eʊݵS.}tÀL^}ao[pQ]ոȣE.EvVHSR^!|_i]|W@걾mAg'/Ӕ#aUa] $S17IudlrFH (熙,{otuTv@8)mKd+hFHTFZDš~u$AwLAђ{`{MGؽ 9?sRQT9 ]S{[\K*mo;TFFiSf)2'+GD~Oت5T8ZF_!Vz@ hYcl$ sYٸ"/ Br5 nno*l[NqTrg{'5@݈?~= | k5$3CvUR&QI *=|EP|egdEPȽڪp;JR:έclVvCַve-a9wƯJ<͵lK՜ZN?dzԀRKCg.}ZPW{y\jјcPN Eqiuڻ7N{.?'Bٰ UuA?ifLk^gqi!jq`e-ym@ź)WWhiWѸٞTy򧇗s^ҕL6Ng8ozȲ6Kgܛȭ4m>gr"m#YmSQm8" F 07鑴܄ C Ƨ>E`@ X>of+ Qƃ&L֏Y[A4[ p~hOh)ZN7UI#J)][ a}n֟0Ϊ Wf~p {/ lBqmPXk"N7e| \zB IYYs0=^vu=[һ:D__xN8(ZBshjfILY/u_+`SɦfM۝ !Vam %Ƞ㹖GRl5n˂j 򿃻mfqcX/8^a0N'IQhe&BH~VbqM:w4!.»a>݄+ӹlq[/heAğ*Z (s?}R1_L΁F0}0NZށFY{u O>]~޽v>OQPJ ! uҹfԅEg WoQh}jJQ2z!;_-W4&GBsVoVeS?Zl|&KL".9--m-'eA\&et%eX6Hs, /ײ %| .P\DkY]]nzU1^0[elP90?FV0RhsAՀUNb#=;x/Zrb*KIQr-6YR,9yI"Yt&x0G[mB K/hatyw/)NQ6ܖvػ!2W;\CS1UqzgJ*su3 h]W~9k}aD زoC”"MPEAU/62&B4*>M zlkoQ_#8ð]pK N[R[(j."X'f97 zǝ'd~7M]{oy;ț`]f^rbt7{|rd̎9"=BUC+x.FgҺvw CzL-6b،|^FeeO;pK`T j8WW$$|`h+JEO+4!> 15@UğըFy/zFd -GM1- 87X/ƢwBk ! EeQ{kfMj`xיD3@w6*-DOk/\ڱU]i#]XivLH'Z- U9J[2oց]hu&T"!BwB.r/!IK[x ZgtINjELҪR_$'e@KM2FAR|BS.QS:*:7fûJmEC<9iQɉf9Ǝ+NWC#iP`B^/ >]{uJCK1m,6ągW zꓭx'QDFxRbNtu2rX}RB8RaȚj|  m R:q{B_du S &$97Pu|#>TK"p6ӕ&46ee{2n/jսHݟw5& $_@Aw&*xE}ӔL&=R>}K(2?-vbOdE":> =mV'lI.^q6VFh0 Ghi+!: T8fF lr O[r,]<<}쪣L019AQ^Hu\M2ZV*ӹ-Ōva?WVRNo!t"wUp), Lث5(b$v "FbZ#fq xAHB^] C`5Èj2/Z gY~<,k(%`J8Ib[e5mK/N|ŷ( 3+ӽ7u8t)GPaښL1M&e~wˢsd}^FJW<{:LR'fkꪭ6|*@پ٭m#{lZz뇦,yV{t܆@+F`fa#(e+d12@RD*ǤL-`0Ze{&fZ&D9v=Gttڃ(Ef̙(,_ ӻQ=&yԙ%S#HDcgAcVw,T%W?&]Mn#nHGg\UY{=lڼ9ѾcV?Ũά~rޖn'f_f>߭gy: ѷWјU}X6wPCujGz 8;6Zk; D_DpUG>>˦ƻZ:3@/)԰A]iW/DL: ͹I1 FM녈]x) Zgtr}'LG_avv a!z!b2YꅈY96t'tZM^5 5+ᯇZ!<-"!]8S'kY4>2RNKzH[z369-j9Â%`<~XFTw5.Q<㽏V׆† 8!K@.H,Vvf{'gp͢(_]ƭ0ka9HnAcؘ;Xn'U<}>} , DT\] +U`& CU J<"A^T1fq.HHCҲ@G*.S\Ͼ*Pdxᑢ.hёʫxwO5FV\#qgozt Y5M&2C.Sb::o f@h Fl)*F{ 7N_qss탨3[rC ֈE;Eg#<ˈu%f WUg+L6x6o^&>,Ձ$ZD//r$agNRQ( :KMte R"2N )|vW2Gȍ @V}p Xac6myn)8 ܴ!qKqġx~Ck-؛%ƕ-F:<5,c'(tk؃p\ƅ ^g; Q5J,hg)6n.~n^%!d>"R=-ހy[˂R6I[P{ IJ,5׉# HMKl Rg-Ĭ} ׀VbϋKL˹ݧ7,nj*iGi~ P [@<(G)k)@^*;]4 :ZxhyLR9T^WCr5 ?jxE{puDŹۅT $پr z-GkQ썄OSOՊL+Hx »&I>!|*/ɬJ:>ת3fuYNٔxf}+Bm`~bCtfqmq,6f&O0#Ŧ[iVu ohihmMRvhB\@k߅jֶ B+}5Tʻ*kKziRun{.wNSӄR;z? hkAoiẃ{'\p' QcCnXQxG$Lb_*3Zk~O^k˳Džfj:V,il";N:{kh͜]7V3gKbV!(n!e$" l׉l $".݊hP/G4:'5<ıҊX(m,Z}mTHb*.vυ5c|Mߨ:إGKuу Ӌ ryM.2f^(F;j[x Y[\ȩVkhð6=ʱlh:Eт}/btps =Hǥ/muX0@Tg^RiyWdpULWXXıUnR%,&y2d{k'ލ)(4!4:c gN='7{Vq"aa>ks;^m6#jRyP6 /+Vֳ/d!" b/꾰p3C\^a5 2&ԉ8;bFӮ <(Oő_)sOrPSiOu1q%;gL<$@_]ɱ6(%0L%Pneعt;u {C%tZ{?rq5jFJw2YDˇ_÷/͒Yu:Jj*CU0=lƈ-nP3U3yzy.!}Q6VM!Yy'΃ܦh#t_$"B!YyX . V28{ Y_Y WWj7:9uQ66Nrts[x/90?fMk=,͛GIJWBRR :jKp%X "ߞnڀpU!xـҋ]PALyw3#6$rfSa<> Љf[,#hy/7g `jAv_3/rKº S1GòLut?ާ3^vE|ÁKZWGqsm8K§ sV.|lڻr[ܣ|TðF-3zQ/ܼnoDEr%E(Mg7FG5T3d=Q!'MOd" =ťnqfVlqa:K3|ִ{l`Gg͋e&ƞ}K "ҏwo'>_ WaQ!:Ⱦ Q̢w ftaq0Yz{3$(fwJ[msd'z% YT :aN,Sĸwr/VkO=hN:Bv.,l3W9/?NjjfaMIlbqo,Q-7lC}zuH:*[?N]7^vUȑ"hՁ3-@$j͂ºݿ,e"Su8űf:/Ir5{,$9ݩ]$CrSЊ_]ɱxV uazDYhn/wC: ~ S[3򁳷PmnfWWqp1Hx1>fz|;|oN,xVD$lMgfI} )Lٛxl+bUSCl8h׊,mLkmq"sC^,׉O!IfE@I3jq!6 Oڭ $UMpu^/SFIzD4N;hn{vVNjg11`CR&H/)H%IhBK#+3iy&*x@?%s- XyԻ 1 5Z2`q܇1xoBoo zBom,9q6{4„Fq ۿT~PEq8<ע|'4,\!k4QmyFa^˘3Ŷ%$`M{_ѧUU%$Mnx骮MSRX#e$P>~$@4p0k&Y8Q㆝!BD-!gj1?tМ|u(qhyԄhyFsO@< om+cxRCsp'JɹaVrD 8L"nQ:EDAϖ%c2LECxN,tɶ܏C'"]@"]X`GrF7V rGxH@$˫E!5RPr9ە?ރj%68ځ}O|CѦn7Q`15nV܁6߃JXSCd\@j|>a0^i}of}URw5bDۓ.u[ET&W?ihɵ| {ס\ :5:\TxD,9-q95fx˓1X?JI $r2AdQ-pyj.=? /2p5k!Ӭ3:>p'XA_̼Ufд, EڶU Y21MAD?v{DQ<,( ClOV3Y퐴R9k_؋i&J1& 1W(/[!MK]4Q̼0ysTuU6IB7csӰtZ5 8Nj&1[z 쎶l09x@ )_N=n]$zJ^ tkY?9 ].A5<~f?&ZAZ&3 bM B95OA(ΕT0)jJ(T ';ZPf 2/G<E\s! #y:;_Lj)<gggjt+mXxNRwl4;mwl3m#Ukd ]soOVyRb$ej~|d~ o5kJ$Vw$˟} q;$davix-R_0_5_0/dist/abi/abi_dumps/davix_0.3.1-gcc48-x86_64-linux-gnu.abi.tar.gz000066400000000000000000004505431257152637300262420ustar00rootroot00000000000000S]moH+ÔddY#İhM1䰛5~MJ %KSX3Ilߪ>E»Kʟ˫~ӽ^1:\Yʕٛ7?Q?xo_fw×_?ݽa>}}<<}_[_rEgc?.|gO?$t}d۟/>ǻ^P<YI+pBR.ioo{׻m| @ #:54?Z;{7O{6,?~yl 5t{?||oE ~y$|tK~˜VPfۍs_s*Xnf4]Q۟D8 xK8DifJɅJջl6l*tW_{=eI|(f?]NwPWךυ(2A"|rI}=ΒB;wK3y)ԃ/V$xD9D:J%2n Bǚ]^G&OƂyҿ`!nK+Q@-"ZW˺o{n.*$j$]B5AmU,mf2Fն]ƉTJrAwEHU=DRIyj-&柴;AT_@{H%nT!T򶮌$!-Zff$K.8؟PяZ#2+wz ^@HS)˥bc h"T*|zѷ0Z;DL\FϘ>?I`гhO\?4FI,5 [ͣػv1c 3Fv93Kuc>nknd2.!78xasܒL1L>;Wٔg_w}(eb:2F A7edDʅbð;9 V䮫MfM/[t]p3||Z9Pɿ[ J[ P#Џ)ؐ+ђJ%m4]yҩAZơMſpY/;.6yF 01.|d5Դ73^1pv*x^znל6w1mEL~Km&wevk1) LDmZ[u]h+~c;ZߓK+'{⎪!tު!t.ۺȟ:imF'v.m+S5?ۘ?[ tGB3AK{D2ʪv𯞃Ynx-0B Q ySMyC!b1B0o^v)"|u)U/3dݵTgYt[1GZX.z0 .T^ˢ+jgo7RjpuZMjꯧ#7Xި#4_H=^ʣ~G.\z]Koy]JWσϷdg7EfTq+ w߀-aC_ qwq:o ;gdΓ1Ĵ (bOkfՋpg~5|kpcZR,7sa}Ք֑CǔH>Q/nEBvm$^A I6>ک:WH[>ڑ:1tZFۇ $)vc,TGФN,*8̒ emnM"_t"-7'(emIPx׻$v@F1E_óϓdM Ѻx g\6sqNAV)ym>VXↇՒW<,@}Hl!rusu.vxXAux{X.ԃ<> ú9[=,V =b<>r}"kVVSyXúv s[=,IJ= q!͞mȁaϞ Yo 0޷c~˰K8cCگK|mlm&/gCpy.,Y${S dd{'b׏Y9xmF{gFr%N0tI!X.^,!bͯmLN҇lNSQv[a F#ڗ@[<'NMacWE8ԩ@qIvsߗ?R E0| E_` LE,J'$D.%Ts U3!s '50FWhC3 ixZ$dq$.ȩ ^,9L#MBg+hZ(O7`Z-G"{. @k1AE"58-IKZQP"0.; nW]d&CO&̻c}!iWJ0Lm\qeGu5pF$>p<xmb Wݚf+9Lpsu31IU "BjN[h=Ģ9 9uI uzY 1%:+_'2@h^ԁGr-*!/q ruxK@/"폙N&I^'< 4%|zr%$ vR+<|!x7ڂ2J)x D*J)<E2OAt]R4jAuZ4 2>L2c a0 OL?6NCXר5 ~+K@1 E!ʫck,?^F-J?%pC$Lta@OI2}7Y n oP̷(49ɋ3$;Ɖjˁ޻ ع6N&Lݵ.{0RsTa%H/,}z|c0*n_mmekj4)ۛ|=KEÆ(;icx )x6'K\)CƸ0k^άmIsPnIT gúcY>s55KeWnY:0<~-c[urTug#%P^ȥτ}F}h4; |kypp<i<sXM%Ac9&vrgd0wL2.K/qWǟDUt23K2QX̳ !jML,qha vG-%Y,Lsk?Leݶ,LuuԥSQF ѕ&_7ōq훏v#=XK).&M)cϡ=mM~ɀsm_0h#1~E ;ua*sł!1 IӶ n#d?OrĢ /3B4AM(dJ'Js%y 4 =9Q$`;Ei) C`#ؙ)Z &aa֣CNe2c{g]KݦCV/:| ' Zt̡ʏ"$0 2c#QQhi$Q10e`X4`C#Ke҂5gЀ M[~IcY1  qSIAXHBi.}(Jm)pv+Xfa ]7 SJeG8 rKz3?Z O"+CHz#!uA\/]krXւeZEh[FhtwRX \0Ɖ}=9ԉYQ_@LmZc/S^ӕ FpY껣$CUV鰂fuF#@inKpfJ nXMfeg%{M^eC&?ױXޯ*p< a 1? 쩴5G'NB^i#G6C4zl?ŢY2A""e@sZA{iXζp-ބφ~WB+m:Dt3.di1 ‮2+0, )wۥ{WnyM\VN<ۢ*ivY`Ղobe/0WӎӴe f,FZ;o_< T<+Ȋ y7Vr:P1ȱ=v&[8Qc'*lodc#eS p*̢(ѰPLmhu6g>7;=p.qfmT"4"ڐ: WdGU^ v0٠7;$:CW%jfxbY6t=aK.J̃eV4` k,|/: XfbvV$$03xD3F̘JhDDsb_0*xTaj,Gkz՗nAnWa2Q0Q VX<|x:2YR)Q$jqрdLT!G0H xQWqQk 4Eul/2ݚ 8s tHI&0DCTSy<0k(xB bƃhCf:s]\5QMj[,_xm}5"nܽkw%s:Y|6n:tGrgE6oMY_(lK *sVBP((xr㶻}-%JͽT,ޯwbQuϏ:P)I'۾ ۢˣ=d;j=ndU|~`'@ϭKN2`32lC ^"btJ(h^pqLuPmbM(C="EW>¶ ,zWۦQM /.0U  oZ@SEg2 bL{w}:ʦT_e{G!F6sՍmA6%^kZT6YWݵ <ʆ /6GU 2u((?\,;p`5;&sb.Ǣv(g9UB.7laR݉ :Lp]'{DrޟW>I>) L.[Ƞ-&"s$yh92M̖Ś*nw"TQ I}Q%MW `T#nBm'ܳjjeQMeTԓ }y 46h, TW2crlKQbR4`T>AuJ*J(@_.?]P\ )#rԉ,#`12I !9?q࢞OQ?6UIHΘVʶ.aGBL]*vD 9Ys =t*BFt# iJU[8zQMd٩1G:q.-qT1c5ױZ<}NjL藽*ovsY!W-Ӡ#V;sGR^.Z:D!6cS|G[yqC F64".* o DY]ͲGܞQ湹"DQ8窓m*gNVLm x!a 858LBR-lJ8H5YXD)Z)ԆA,9U B$iJGٔBTk41QpN5cbts(PUM\=]$]6Xz.=%uridNy*+aK!}[ fQY'Z%О/G8&ȓ%WCEkFT9Ʃ$h( SסU]ͻ"V@E"k4rmWAQٱ¢ b$QRC~!Uy>)izf7Mtv%Z&|ܠIѷĢ|6I+焥9IXTrѕZXd퀪œ,='fϥmYbb;p;t%9Vat0XNuV! 791̜]EsUe.tZ~VBQH*LAaR'J>rdvjRPV|P+~3xTD"n0I$;Wdeptž>nݏ9“ÑHi(*׮8sUAdFȰH$2I"(wYuC5!؊Xtt' Y R 7Q: 4U.0FMEL*ꈺ^R5탊=8Ǣs(Zuԕf_>αga`^"DOk Nc}:1aFf {_82&ct? ztTWLgkR+`RmPN+2j d  riMD  /!.`RQh6tp%zsKj]N%AįJH*P0nD=VQi|!UFnTn+rQ=[P=9A#4hnI%|TuK4$JP˔RRbG+mLЇ]MBN{9€n6oYxDfGa;✰ǩGEJQ FDnHWIH+j3PJ--RH(]:\&QAK2Ḫj4Bb.($ G.+ % \d{r5&ׯ`JJhr8ZUxjGG n<\Ta⹲$trRΕRBW5\-d #pB;$ e&샰 n(UF)]:_Ҳ unUlQ-e(M܍^!SqJyjHe#=?HҊ F{ #5WҁKP_hL SA]0]x,="X$$S§Z eE΃9||gX;] )_r1ϝ,nQ֐W2r/b+;VPe焙?BEC&TpKU^a*%hI8{FmIR kF&EUH8$-X nT 02^\&!; (!ե Eyo?Ι~=m$FcB6-$& 1 )1}՚Q#{ tyx :@zaͬҍtWLUYjEDSEKH(ZQ>\FL?B76L ndu ,Sɲ:iWR-(dU1W]N *A|> ݥ? &OvXK*7#B# +gIvbIGpeC')*QD#Xe`3A GF8 <lj+H\S4K.f?m;"*mT`K0VaQ T󘪹aXDi`1An`1^MMB%lF]}ƢHTUם(jovmH+ToIaU.<-:+XDH!iB"znC\JD!|H8IƓ.\dG5+c5ͧLbIl?tSU9HY(Mt$/վ7 !u+)ݲt*}CIȖr~zU BqNEǼjG.R!f0ŹN0i 2̓uigS`QE'H.>r=kO[c6M4Cږx;'Q}!m0WV(X]:]wSfkPH\2a vӪ= ,٭8>+n:eE ]pmw,XkQ` ^:6c"']odiT "+*ъCG%#{";r#^9i&,C*-\̶@{R#~beB4"ٹFK:;(du'UTTKZR792%QDVڀX>6wUn~Bu\ޠqҨ5 ha!}Ve/ ]dBr{ւjEtXܑ5՞r/E6n pJ= %N8PXx T T 4^# Q١(&; bn9d#ZJӎOAѥ5 ;0bZtpiYF\Ys|n nPeH5 B.rWjgi}@쨜l XqB!GVeaDdg,]2@P_E^^l٠ yԊO3d)*4a]hpAۭ(a8۪֍ui\/I&\nDjXra0,b$ OJt5J4: "0ӄbF-XKYA~V`sut+LW% 7J[# 0spZB.-/`"r~sks+lDeu+"(?,F"-jruH#s*^I2:$:RF2KZdtFQbdӏPTk9\sJtr "K UěRI_?]M";-=uߌ`VHȱ$(yŶO~DPo̙R5`)T م nd% %.D˻ۛevAcDus[1]$*esUo٘/ThwSuXtMa@NG!Y qcX#9 )lt/Rlhn36s: FR`X4Ȯ[ŜBdaDk)5UL ςB&睦eF$]s\^UP=7DMj&CkU7yl=5%~DJD;ʱUB&WFWE$\ UTn"2Jx{Q;q]^]8/茅RŅT[;jA'f1ч fD1KE(-={G VoGGF6KT`nVi=Kf5zZq.,EYQg|J<¢S$mm.wT`TT]FVs-AV'g)Ud\ϒo]vIBK6*}VJ(؜RisA[k0j(TS}JDuՅrINS-jM^#Xҽ7_: Jk4v:HGhK5)tJ"J-bIIH9 W$ZLĜtݖp wL6!lJCQΐs}U SQ^RhtWm7hti&H8w,:$kJQzuV'ٴB$ *nE{ڠ1'G87pdSvI|.}WH%]Zx&NQmr܅EX `@*ߌGQ (YSʨT@h],C9w.c!oEQ+|rO ]d5KSWwƔ@ЏBSO_TgO/mi+T-VN-IAJ8J+ޓvqKߺ+dE*k7M|(ủ%M>Tu$Yd+W{ P w{][AKA6S5Hfyb%sAGhtX+ZVt9?.NY ӶwA#[.{$#dt`m nmJ$kΗL^(dGe?c2q?dGYTE'gDCNI ;ҥtWS?LnRzG+#;OɱhS$V(ml$){mKUm=3#'K 0ҾTp%:;UXNLJ0͢S !Rh@T%;~n|gGVo/,+H!9 UR^~ cH"yHuEj5'9ajNZ"([Z݊0D^t]eV>mϡ췲-ZE(OW*ڳi(v,)Ru;"Z9iDx +TBCl4zfI3[v#d5K,9YkG9d7 05#k!lKĢmdR$ZF&S g](T2`tBR#GE69:|XruptO֓#"TUOR2RQXq-]V4RhUw &rkOHF5IHŦܮIuDQXTrQګ}T(َBj4%a*MUeaW!`Si2M.U"*L޿:܎TeKN,QFحF1Tcǜ(xL6@9n_YO)YH/hN+KhQ.-J4|k+^6PAcVӆC 3A )QЭ^HepdkBSտ3rMvDu~p5(χĀWĀ7xt`!@?MkJTRSd/?x6%QtI,^`txadz rG؋PFEڠ[tF ctRa3HPx16@' G~B[AZ%YsTga/ɞUx)!R %^RȪ{ڰS6%mS6n0YfVrzKT -%'m*!cn# yrGm1F5.Ⴅċ^ iu*C3$s'5o _; o~;4` t>=>olq~]\t?I3Me2 ,>){CuSQs{ D!(QkO6rB-4P<}4~fw꜊\ `n0, uEG ;JW}`> i>%5@`#_2O XFIo;HG?&wϣϨ0, BWf+Q!HB@l|hB&h5i f4YPQH3%[X#1v`M .%iyhCGm v6()VqtT7hlИjl̀>~ RzR{Rܞ?|}}Ek_@YSh,~ 5 [Zm'lY  IKZ''a {h{ӷvhҀ& hlXڂ 9t?F#lO|,AB@B &7aK&#E+[ǃT+f:Ũ3g`st{Eٚ=?c9&`KB mAj])XlK X-=@ r` p@3H/-;ypzFFY60 D h +h9@l 110s44EI1&tyF.tTR/N &eOW.ຍ*i)qa467jR⪣Kfƿ?G50\+pED15q꽕 $ WT5xw^Ug$&w(HTm1S?R~-R+|4S|Q\QXE9Yln%x;vMCB۠ʀL}$Rés pV |r"KRs&"pgWdxs\3ۍd837d }K,sx58aK SAEIsHW54dPn%&BzwC "L`PU3M *rW7~I1,C0l꽰~?B]e_2(<` 5)WjvF8fd#>䧯k 4*UlY. Rvep@uF, W)RpTT #S`ScWi΄B@'PQ0$2Q*[n娈H33lU9,lzˉYd%Z0/lZ䗶 P`G>Ȕ!:#uƳYm5u0m]KtP6\c hx:_`cdnh'ǛB- sBMn#6.ӷri]5xDrVX6YAѤHǥ+4.آ\Ag+0Aa` PCԗWzwk)p!~x r`4$>zf_>%pУO t?-8p]AW^+\X p"VJܭoKX8Պ2D|x8}O*:$ +!1SJpyy*D{&'Ȗ萑-#[#Fsx:($eĿ_`؇ b|Ջ5 c3*6sD%aN܎']Kq H{TFނD1䯍(LD%gb #6js^ v{JLD2q6/A}N~60<"*YH 1RlḼsrH}!D鏙tgbف\U@\i6Sb-0 >%n=0O,9sa%.9~kUZ8>}r~.yd: *DIYw6 }\~D^c9作 l۪`g,9@GlC!'šmaq0;)uwh82a%Ct8[J5j ~ o[/ @T_7ipxTfJ?_ :!欦)!b#E11(11@)܀/, ,("E*( f2PyF1~x>㧈Y8N0?yԱ~9ߤH`G7,I XzEnBr\wg '9: yD#9aN4>U{س$^O63BP/ p}z zwxɠuHQْegLIAs/M;) r8"mv0Hxy0 wi0K,zb#iЏb.Δ%GB `[1<}%bb9Xoz3P۬&F(XԬy~e+2z0O ]!fbK[ \`QV~U7T$'PUTlΝ<7l?O3D s"{r^4"gbG΋FT--,6/c.f[>Z b]z"7(b+,ͪqeA|\K>j˅ܵlkP. ۰)\e/  Kw394r՞7T؂c%:F=%!V3{J4mKz2>{Mf(d;.+S ؈7 J&]rp@9޽ wa`c- o{m0ضW #^ģ2tۡo"cKZ`JdW%SYn!lq PteCyShgܼ=&6hp#F<\!p 'nU#8GNp?GS`Ԇ|LsJpLcZiA 2dL, fV˅oP fAU+{LPTt}pӳvMyp4Ry'l cs LjW[ E ?to4lR| -%P`;,-6Sw<1QF7((PÙU`v2i$#!3^0Y&/<'O'kFJ޵O~ Q-:B1E p}QNRIP@UԊ^[#;w!β@WvQZF psTEIGPz !I$6"G+8`F)lZ)b46VTBd6%4fcG}g6/Ue5M>K p2q#A1L r;d*d; JtKevp;SZkX@`s1o93˓Я g& yd9[[pB΁6 CެM"ݣ42_2)=qKP3W94&S&_rhHMW-܀A&nk8c e* sP 8P :u2ŸO#"@N<1(I/G5wWI1? P@^Ahh8hz'qy`khW! ڡ7Zh ZM耵 \ٞU.."?FEˀZ oRݹb@Bd^Y%nX%JѪ$Z GΪzš7DMÓ:WAQKxHxJlA~2?x2? .),σ۫@J`11x,&>Ő# D kLtbs0cF!ɋmsh;~<У~<~=Sr?%FN+=IHǀ>r@uS*zoxFDg X)LepID ߄za@=߲8/Ɍm142 Й*(ƨP¾:C`A_cWVhDƄjME&}q#j$;~h zs!A|Q_q*੍R ]yCے ̧f}>hjauрhPeb+)xeo% CZ7> p^CS|??O ߟp=M~zFۓzK3?ӈ+jt&(X0ßhx}G3|H*Ygc &s$`nqژnA;hkYSHe5XP #̷bwn:1*̞ [+f1D1$ ǧMT@ORiD9DrkH9䙍?SW-*$x:1h2N:DS(ƀS^Mrip~%4+OQͼ~A<_KkP@Ur>0FCbA3f#Į&Q3D zuAޒ΢4 @mz!I)E2/]6i9>ΓvyX$[ ,"'TZLqB;֋q.u-~10Ǒ]O45HXQ ,؂3%@D}OvOjyAL& i Թ:DdA)09pWA 7$Ҙ:ptFs *L5HG4Y0pp"KomͤD΍'Ku.gq: ,:Fz(uz:\:! C㈒GH5m(p \0E};::y9} v@׫-.`x lj9P~Jg$>){3:T>zzczqt?W$~X?%'пFoh :> O N޶x rhey)k`+Ѐj<.p?>=OFȩaӆܤ~wO{LgNa3TBZ76R KFF<5N~gg8~xzBBUN>]?=~FZkkAT;P͠ww0lQ3zxN PI :?F_?S⃴Sc3zG: V aL^F콿&ޑ %n.!אLJn#H@ZbRb+,8+!5/%2Q0N8J= f֏uJs?~D޳uaAd n+6ɫ5hɳ~[숋>yW֬L /?Mp#:70 3t 8yxܔJ c0Oا~26l%RrODiY'oAq.2~*aSٱ6> &w~U>|UA@)@i}|qJd*`)i h< HU- h+GtlYJc7[ (l)01Mߏ=" -U@Jpc[J~62qYgm*$MifY%xkZg+ AmQ۹BNBn%ƽYͣDnD Ml/gv9df νcĀW0nB!+I W)*{^,s i\&! yWa,u2aI{=VO00Y4xX70v9 +DcacČXpƈHEJr(g[kɻ!q^ȯT9 B e@bo]xX(^0Kpu 56nOAgtDdB\87`xH`'`<.X^h<0N*2 Jc7YB:`n,tuҲ=݀KM6Xu>"A+<')m+^y Beͭ`c 8<1 [  ɨ-4ࠧKlE7R#-f h&&y4>M}ݷF&7 P!0}|h$[tV}gwӇ AKLZ>ƼȼAFN"@)DB"Q tQfr1VN:3[/3w81!_Aj.IFzI8Ys 3 ?YS%)vWҗ}Y`O?>}#*itI|T%A;AdO_@$zOl;ƋLȱĀgRsm(v Tfw?BkWt7@I&ߐ!(tp) ; ŒD2AG4hTݔF"͆#l1RmxaUA}`xX%:BnN ($ʡqQV% l& X=#>*'0Plhj *nзoP# jQj[\Vrm1YUYYr_(HKKD"#Y◭4H7@FLOVy xAl$0cklcY |r0# oAwD'*:Vv[9{"d)d)Hr$p? OoQW_]-8q@+p`CP O2d[+M*WԈT^-ږ&6m臽9fm*92ҙû6u yOp;^G (i18uJIEP<`(1~i$a<**9j*9`sMTT44N&zwn|hg 5,Le dt?~b w(ExAJ?@Z8#[5x k v6T96ʨAcU P? u#:rgzP`qt?7Tp9' AhnפTm7nҤ Ý6䀸@k1 H,jZIÆ  oM\cǡ_pc<@N0Au|v@V#%W t:I.i dz#{jKDToApSo튠xRoEdb*yp hbWv{*ga : X1܉ԶPܠb)ǡrZ#'!{5i]ܸ ,Yn61Ra- *npA b_g+|,_+_!>bOs,@L&z6倶lAZwߠ) P) @R)r{ J[K5Xl_@?ǿλR)1Y^. BiG)'D4Mqx 5~`UNnkd@At1wޚVX},CfcQgsXS'篔kC)6ƒ TQ$V"twb3QܞᤆXm DarA(qÀz&J` OWI*4[g_wtq7X&c9T eBLS!_ML*vsm-gZ[7UA es BVWPBI)~@_a23立 }7gϣg6}[<|TxzDyׄ &`\d3)GCP%&8{ ;ma!Z qȢqW4,hEc#NU$pH|TcFN!CN4|yDiX"c4,qC~HL)d)`/a Ѱ?r@a 8f>>R}#8Pr6N x[E'4n^ɈwRx[ީ{ k{@xc A }ݴ!:Y*(v&/fE`PEQf[b+ O tݱJ_h$p^ phƂɵ)[kdhGFh<_eϰLy Oĵ!qu3 D#:aPTC\Da @&7!qK„=QuyvDB_M N\IL!V* #-1{x q<];" WٓCg8|r*ZH OP mu M#9}ꦑ w =@ ppI#Ui# ؉EyHPuɽ͉[SiTH=zwSH%-* H-6赤 w>}땾3|BQPϯxNw-Z%"kH<6!Mmߣ707,7,7,a԰ܰΰS9&jjsAr_)(P ꍜQOG}[KBpYpF#4;aɷG j > { N{P:zfo:E(O⧚ZH(˦qH$6<"^[ h0ϥ pz! B@^X+;wNn3B&:IÖC,`~sPEb;{RZ^ Jt}f5 /K}k@|@+fѷ40xdR7bqQu1I3jyKK,q iaGaES@RJ~˯T>CUN` Vt!v}%~?x!5tћ ȥʽL*2%RL T⣼RIkOXOyk=,([n/}?63Sv ưiKMr6J/ 7TË:>J5|zxD!#[w=";k`Xࣿ%v8T2mL0c˄xK¤:I`I- |`-05Ĩ #3blշǯ? UWn1* le)ʜ &U!u  b 0зCXfY'V*LJ;Pa h VZrWx@[3+H}r$1b7[';{x s襡7^a|8- [.r`NMp>У`J, 0&4jgv1_B .):֞Z]IKE$m yŦ9 'W,HI#I5O_G Ƹog y ]DVlP8hY+A֓ D )@j# h&>U8Jp`~}F_wЀmS7$,ݒl0 "TC, oႳ:&GX:}\?~?ESMǿƌq2½@i$Љ};c+',yC}h":epkYb8^Z."nИ13_Pu2$F xGf+Y$g%@QGP}2~.K"`E*#گ # _ yl), ʤClcN~U 4pߣ_ FIrpS=@./XtNㅖ<d{cÔjJ8EWv:hb /Meyc z@er|Pu[2jw -j2oP-gӖ ٟw tР1nr=0 KR% Ƥ\j q5*aU9hcȈpٷ l{Tc10KUlir!#"#sPWll>؆>f>F> JҘ3'mn= PHb@hA4X]*;X 4&t(ZTt]MZ~a=6*0*EH_dS*:4I9h@[ ;1"5kZGkK]J %6GW0S@N;b{|@t#)R,cgW '2.VfH/-Յ!"#4hks$g&%y8ܔ=\Z܂9 G&WFv|gp˸BMN#-$0eM̪F>0uJU ::+X1,kad 1[-T&<qN+$XgRM`SSF.X&. oZۖ WsK 3y4-\pou`> GiUd |hr<"NO }<?NAj~}td4==7D0`_>do4N{w}ض-bPJOܫmEYm"Kh%tEB^vT k~e6u ; ksyN Sgrb"G/_1ϯl*Wر =y} <`*U PicHEB9Xp3}+cĹBGV^ XsAEǘL7E Ht@7Ogކ%JtD&Oe9|N}QR߫~2~z?>8%|6C+ >?[M@.Q? p>[x?IOPYCb:{Fe jU=б=u8?&SS|/7POh0['KlճFo2~y,"F$U MBTRヴ;9:M_2N|z6$ߧ> $`NL(C:k|cgngyh[1 }t%4J5H/0<~=,9LG Vr .U>c4}gDVcf4 a p_^ g:r tHN A#LP*(1e99OFC)_-\X8=ø`ze$IA؈!i.XP) DK_d>2t9dt?~b5gPJ>|a|nGM؇dΟ: Pc "րzsPO}D$Ud7Ȉ4Ÿ30MLxZTEid)H`S@'UJ|&_հTU!j };W{ip lFR@er\Z6Ldw Ti$?tm`%|Ihcc Fw~\brӏgݏ@zw F^N! W Z%:eip`rs'W 1<5q-.p nu䯪9?whidMDGX* Wl4>t% sAȁ#z8dw60\c/[pXメԻo} (Cz}[|cWBCmY*z%^!C7S[z\Nh&A6 m86FF6 @ pHO:6KjSw1 \oÀM-!tulQx@rh\st4z; k5׫ATz\ol5 z\^\O~ǿT^ iWE,[z%>\OhW4k7׫kxLs= kБJ|Ds8ޖ^hWCUU!j\N\jW2m 0*z\OA0dPs= h4׫cU *^ iE4׫cU)ֶz[ψ]qߖѸhW̳]C+07ȕ}*&21F>$p3`l޸5p-0BC7j P-6y7ӼqKhިAȣp98|W3\yy^ ȹyca ycXӼgOCD/%wNѯ+"Fx tc+ c8jF 8$ 0?,+m/JtB@bE ][V _H&Z\)^&+ naEJY˟%8'ڔx>LfbC2,Al.~8|3ٻ8Re4)!V2*2š̊J<Nbf[5IX*_{MSMB%TP~y!;J2gnMw`?tHĄn,px,UlQiʁDrd6!wW]C]69Kl#lV`D됄z%>L*W Apiv0;x`<+DWZ/c W2Z徆3F䈯󹠊%Ղ:w_@TX+;. EK@8эQZ5 Hi+\^ip@谼J7SiN but_[_ K걕L߮9- GW*1Yc&k:+ӸZ}(`N-j,Y~GQ)S.' r.'P FP`tCIv2NɀD||A7FUB),s1Ew.#++7U2;GgGad2`!/hr*4AFgn42^>p:w'*gE}"х0,PXTq¢;X2R jW2,;uܕ޶\Q)v* i[fE@Mn,cn96MBʇ/sGkKj=68הrVEMJIh2UYX0P 8Kъ:ģA!,_H@hZRnV\48gq" 1&ķ^1pҊJ,l(V *Ug0GX\¤ET`Jpyܬ4bq&n=ڃe] c)EnW/=IDt]HJǬk !@Eq) ݵ<V v?4J/|lԷi_Ek *Rp5Hw "y *R<m%IUdO-,A|@t2+0+"[XA"'ӜXtЇd:v3uX :vHW*TpZcd/g1H*>q SC Q:R}sVdrC#B1]@A 1*q&Lb gpsD;%ǓP%tDPp@rMr2\" "9Y_gA|@RTRv>$mDLlT,pi2)?U>J(Kh eqfufTeVzuu1H+EҕJ}0XF `i@!8J@`~󓪈p|${{ԥ{vw4PD@=bDلV0Y)B$Fk>WykTKKe9,$7HQp»n"%ހF~&axCϵIPa炢VLϭpUo[.\x,qaSW\Yl9fsZ΅\sah9\Yl9fsXz9\sZ΅\s^gVz@E NPV (2 3ԂGbid@;8e\Cc*@h A 8ZNy ;.6 듉Xv \` U˿e}Tz r&TIhd C&Th2ad#dcn +hIFO.{,Vt9(XBhMRg`ɓg[A@ Mw+6#`& 0"k M pPSJ*n uP &JhH/ԵY[oPnUrH+0%-A(@JyJ \PAGn@ͩBB &,ă K[SL "N Vrv.vB"Ik#DvG/Xf@ sVǬ"WnbsZc ;V"+jqu˱]+F Jū2%p@T.x\\8Ta<- ;l`E+Pb D̑t ͷ@)^s_~'Ru_ j)T,W5!ojJP瓶@QLTHx0+eji `/J`Zvέ* RG߷/ϝ &v1LiL4zN-qИ,yYn%9 Ft9rf !S $I#*-{e(G=ېyj?NF.ġN{* ~NhP!˦'F(|+ ɖ35p`>^e!1E3V=8W*=Ϡ/B%e:8˻PAH0N#U0K]>U5:jr |aoRoQaoPU^Gn0 aҌ|[ZB~Jx;xrZݲA'W թI|! c^fq̚bB, 마0F5laQq3b&V?즟|r~̊G3EA%>O)᳔:ǕD=2213\]_\*wpȸeU=*G/"?dK;k{ obE\\&qÅU$$/MKptzyqi}aeA# \4p_]=Nf Z<@:(\T|U H'8OB8c~C1Cb8`bPg肞}pq8GI>W`n5QhDgٯ] W c*l>u|#ӄC,5cV[ks:ma+U۳0&#^MFV%Q6Zm2z+CK1r5ʉP|}PcCRzk!ūc+߸~s=k˗"3㽼`-CgW:E %DL50|=MX_."DNf@(uUIb+sFz"FMDUa0d?Mk5#ÕJ^e;Xx|0e+vѬ7 ^Mݖɕ0k_ܓ e8Zyng}1T!幎.&Qk)JA釗9zd8N:>+ImRoミ!P%>8z$9>hM~VI+-PUwtTz䧿[ޫy"7iz]^`wV~d$`:&ޣ`k 2^ |3鍢S'}}}\)%4-ix!{W&lK$J3u5y?.YEs Dҿ+P HIiͨBt^)u6=gKkNNГꆹͥ,Jgk3#OʩZ;)嶞IV}u#`"CD*nVQ{ P+՛Por90?Dnglz/1?Mg(nnOi-h)oׯk{Wlzط)\kGJsYMݷSnҨF> ϓj/lŃ.pSY)z4v#h뼔% c,E;X"zenU%E=9S7̧yU~D5am+/Y1M b:kKSO-Jp\SEw,E~%"c+* _ /Vbo)L*j .CB1)w0=ЛE)1 jy<{ES^ WHl^%4- ٕ {wɴ_Py058}sbZ{b4y9 70MjqҖ!5/%R38< U2)Vx{!-̆WEnsS&U5+_tܲpzk~ޜ4O(kWJ՚ڰao{y6Vfcl򿣝 jĴ Ȳ]Q:vaӢ:},+"g^-0 ׉xmf /iCjc1@#askc4&x`C) ~- Z_3Y.F{gFLq @y@ Cg @ i(D1 v)6ǡ|NQ QQ 8PhOiQ󾀇hx&gxF&'ay%Zyv%*'TC $>A XIYbz$={#6z4#0s̒ fo]Ev(k4 sϭKӢ5rW.jn3K!4UQ? :RG3chEqq-Q(Ls4X>R'd8L#uy{|`Ԋ1 z,=D>"AŠbOd1'Y ,D~"AOŠb[d1-Y z,F#EC"#gYd,~rY?9EO"'gzYd,rYo9Ef:gzYd},>rY9EO"'gYd,rYO9E["-gȌ,B3u#[v9Q=E' k,7.R4W-sZ1z2H~8`l+?1Ei{r&^>^ՐGinI§RE`.Wl&)rP0f 7鬌7g}~ge}2A_:Luf2㬲25ge0^pD4Cq: FUixƭ%{ inIy1vX[p\鏿\?ߚzn6kG`[i-ʐжj'rp8Q#0o۪}!SX*XhPw_>#)w x%v{7=_!@Lx |Tz o3Rk%|+˓K.Pn%l\5#{(M\Om_V廓6gi~_{}zƾV~Or/G~/yK'9<!ԫ= pچ$h[MV~&<Fga&ga{,t?038la0Uf~Ta[~pCwS3Uk38H >n^ 09k9L OF>(qg#sXZb9dF+XBM5Sxohh8s RgpPwK5|g͏"JvVQUN}^xdc PL0Qdr6,92ssw!K}fFjRA!':lP[uI+*Y>H/lKZ%O_3C ]ev6L2]9i LP`D~"|K$Di=Jc AUgh\DWB]Gmq!o5lH. KT µU2muD_]`;OF?r2iSR(Ǩ{UꖳefT*wm_ w._( ?2jJa(eưqk ;I#ICmrRMI MI239)'9u6C3MFZU$Y"jj絥4\L4tm~:}߭Ɂ˚s֦afd iiNCr7tm~+}&.H}>u:3&<0n-̳UX&4qC󉾁>~|ʟo|WϘ{> BsOm,XٿPf_(3<_(/sˌ83E/y}:2q>DZVC>Oh-?DZVC>EOh]?DZgnx{yЎq*yЎq*yЎq*yЎq*yЎq*y?}‰AABC7Q ;(Hf $3tk 2d@2C7K Oht:yP'L' -'ʼn}BAqbТ~2yP'D4Jm*+UڬT)U5U-'$j/Bݞ%W6%| TI=& ʼnDT"N(ՏZA\OiIT}B' y}"' }"' y}"BxOj|BVs%n'mըf xkU|i g@BhJ 4:%K A#RN(z>A$ OW>Oc>Oo\>O{osxb=ŮYUC.kM%Շid/Ip=} IBIKD$ONcFFDs!WiM2:<q;<ϙ!Mԫu]x_WDa5yj >BhUMՖSM{B uf{oo%+dUǛ{8"3/od{$ړ(6R4(BlT$N9;H*cr-ވXC/%4ڱSߙҋs6nͿ89 |;HOƨj'(PN/]dC?>iF}D>;Pt>鴢#dBݓd7O^ڸe$rW{*QOJ$]Yz.dVs[Ȃn"\Iάya P_TB/<›0kzBCz/°Ӻza\#K|*2Fwu ۫U kRlrh7XX,Zy ,mFvbE+Ţbldhc,Yܦ6nE/j([? m&rmv63n }T1~Gr#NFJVEs:} þ.eO8p9U埊':T& jV@,I)rpں+IY[OZ5}|^R ݣ!5j+Ii^ᔕaB|)n.12X\EvK:RPDb%ruʞV)+͘Fњ|P"د] %+ |mE \_)1]jON{t?P]hȫa6 @ ?#q e62md(0F,饧Ȋh}T[=@o aؓ ߙǭ&p@'^"ᖱEA *䓊G*Zblzôdx6L,>Ly}bߚ^(m^܏5Mz>*ֺ]~ SZI˩6YZΫT Y|iVE5l;9nY6gVn߄zSˊšC]m2*M)5aʇl&<MxF.5GCTKE\9A;VbAz <ѱ6e\7{WU`,8[q[Ȱz~,wC-A᥌.Z[<\{yO9엝nQdV4p$/^ڞlSnxBt fxV989++Ԝ Q-ox?7pjf-kC- ĵ<3q1ᾲp9 +i [[ a9̰\3,b~:HSg/!G}wj5f^mmfW1׭Z*xCjTyh>Nu5~N>׶J5g+W ~vqmOoå5%d4xqKӇGȨ9qObt܆C|-Gv4n<*LxV7Qk0|If U&9+f?M]C}bQþV_͗R'}p]6fΖ%ڊ% Oo}a͆g̳=Vtn% {ZM=&Va/ɰdxRI{?j2^pL2_<$idP FQELd4nN4I BlG%F$ePڹ NwM|A&Oh2u'ύ5⍣ccci3cJ1cZ#t#'ۣwtd, Iok0E9Pнw0|!ցRHe,d<~1B1VttӚ{vcS=oQY,]aGu)vq*Y!U[ 4uj) kip7(MtFx ;p!܁ ܁ ܁iE:) Zm==CҼEߴ9.`=R~;B,Kް= LFÒ?&W 6bKzoP,vau;PxHtW#PuCkY)D334n3C㛡y5C(!DAIDAYJ0koCD`N4}$ 4W7$;}@ҧ *}@' *}@ҧ* JPJPaU(z V7\طD&2=azJb|L)!`?wEO@) yb~$m5\N@)Ӳ*[dQ_n$? c%#^}ZJd,VNCCh}/ ½#L#̼# ##y}COcºb֗q@@s#6{F|d}eVzUtĨTN`Lr D(ϮHP}(!fcbjTU Oh͎az@;%8c#,f:X 5pA? H` +d=8>rA 3`  EM j_G7ƣ_:$:w7GbY= t{:Z)`nE]]"{fyԋcI@a#YtK| ptC#;}%eTG~z3ph 8Bȕ4&txL;Hv{r_cuXJ:z$3S_ ؔI -N?7dÒ,L|в]JZu6B+Q6dCT;#b+B:H[a<9`m0e؃8m=,؊p/x gb7k,J""FQW)e9ίܟ0nlˑ'=Mp!1cT0TaCP0_!Nz $qkP~A9<]aܰژx{ `Hcl4^Qѓ*0/-\ ߱#rm{}nXE̶%/11  {4=4DrD ϿK\J)Aj=SjЫiۈUSj`WeWeU{qUfdLUYqU^\eTx_2SqUf*N1zJ^콸ʨ*3qUf*ʠqUhbq59htߕwxx}&)X{:an!, d&?'[nfd cFOfdFO?Jhnò*3a56…k3a`]&k4Si[ʂ jЫAR4b GW0,8%KWdsQk8m+{Ax㤱a0ɥ7&d6yӆ74bϻ<ǝqJwlnu`7 LP]OPo [&8Iwvs;߈`ް#27rKCxM Xok35OsD: U ] vh0P]bmQ4Nݬu`v@{iҀfO&3f1CvhL,7tBrtJN)hP_ ~$`4ivPͮҨh73F1UԌqfL7c4apk4Ҡnu3e9<C6hsP 0siϵ!C@vWnP~*.ҏ 1w&? Qy(p}T~> %t>"G$}@P̏0ceMfvY9e* x[c*H/;VI Ǜd}x[e{&T;mԎ܎o厷/Rx{%x[;^Oj&v*;޾$0m获M3;V`fv̽ikN]yz;ߐ@[t?/@?(zSm=[SᩍKo~ܛ-YN&o<ͅRo\Чc_=0bk#̉Ko-f7g:-;?Ft&ύw\ngvZ8%?-q%;-q'9-q^OKu/x={#Dewo wԻ ի$)ԁh_ꅋ',-KusګH&4 EoÓ=+w1oQRJy~>#տxRn2zC;@aB\KoJSxrFE "{S7Ґؤ̽@IX`zޗ"$7 _ӋE-F98Ss RS:)rQNQGNIQ)jD;R#_ 5{ԯQq[Yu-yrb d>g(? Ҩ edpuaؿ Gn@5ur7@QgAiNmhClw~zGB}پ1~35m1#ͩ MbfCXAeMr?(S_ONs?D Uxxjd~zS(|l&MǖIsb]@ަ6['ͩ MMݟAZN%Qz$Jޤ7D=iN> -f'(yOS|mjmiF*au`|l ~BX<e`т=Z3fX; lȰvh-̰bY/1欟sO9'Ɯcz1gŘ31d93c ǘ31t93cLǘ6ccL#ƴ{1>bL%ƴ1~bL)ƴ{1bLdi1m1m8ƴ ǘ6cڦcL|阏11Cc:=ŘN1Gc:ĘN?1Oc:=ŘNo1c2tLƘ1c:cLt阎11&7cr1&7cbLG{1y1&#Ęc~bLS{1yo1&7cr1&7cr1&7cr1&7cr1|97cǘby1漧sG9#Ɯc1Ę~byO1漧s[97cMƘs1p97cMǘs1t4c.ǘK1沇sG)\c.1Ę~be?1沟sS)\c.MƘK1h4c. ǘK1t4c4d5o5~F8͚1jvx$q#|i>i>CgO1>b̟}Ę?{1c'OgO1b̟&c̟&c̟Fc̟c̟c̟c̟c̟cL|陏1=1Ccz=Ř^1GczĘ^?1Ocz=Ř^o1g2LƘ3czcLt陎1=1o>ǘ!1bL#{1~bL'{1bL7c&cLh1}1o:Mǘ3xko>~ Yz7@~!'{z@޷?;ϟ#~w?29P=}~sy!n}{=}Wρ=ǩuX'ϱ/8^԰(5%J RÞ԰(5)J {Rþ԰(5-J {R԰(53J G(54|=DaQ0^/̟ zy^q^/8׋~E?zy^v^/L y0|^/ y0}^11fb>Lz1>b̤3#L1^b̤3'L1b̤3-LLƘ31c&cp11fb:ǘ33cf=ĘY1fScf}ĘY/1fOcfĘYO1fScf&cd131ff8Lǘ33c1_ǘcb>bמb>b>b^b~b~b~bמbמbbW1hj8|5c1_Mǘc̵sm>\1=Ę>buO1溏sG%\c1ĘbuO1溷sm2\1Fc̵sm8\1צc5< W<{ax`4:LDCCDF+,#,oKK B%}g1p}@rJWlz0_,E1pKdV4~* !u-ǯUn7Q [m@BQxp^ZJOc6s#r1.V~ ׇa ~֚_Kr=LYCth>fR! B~ؖ9V)GY/|>_q(T׏#ČB1&sXF̟J8KF#1a9[R?yQEޕG])S rIx.Fǥ0U#zF~%9 ˇ<]{O3cr=9UL+Ⱦ7cc,~}Oji$)ԉ 4S R!mx |O^񂙳3eJe de; <Ʉ2& n4WH۲*3ڸ-"V+[0JqOTY&3̜I_TLrE -T5s e;< - wso[ÈaDnDD׌ lP``ayv.{ov.|nx7\ƬusJXq=6WL%z; $[Z Drk_Nu O D͸|Y4Zf`jf`j&&3k2&3k2þ&3k2&3k2þ&3k2aXlJ}yO271VQnf;0m8_Q5m޽mff-4|МBC=={̴L{[hdQzʼZ` b͡rL*Ʉr#,`L p'Sd2LP8Lqʊ]kY&|,+O+>ThԞ3+yOK?MȘ ;md'8#} nA8L;;A Y> F0), ^` OO(v@!(< 胒>. e<`'|TIA PA2z >*}QX5QDKںU^ 0k<蹾b.li {(ZW$T;@Z7H&iT&Mjy 굑+s܅Y@ъFaĨ}7\ {LO"ky?fEuFEuR_n5B~ŝ:BøՓw wHC 20_` 29W67Sz+j٭[qp0ץ^hTP20=8gV %D#"%D}yi' EɍQ3F<˭fxqq֑N֑s/2Ri2s۳kB~[%cUd!P#ES !0-<$E$ l4e˛v߇2bg>=qjo`B$Z@!]Ubŭ5DylyN"B. ЀgG5l0=` 0a|0X>P_%UYe@5ƀ 4zXoڻ b:9MWK#<3Pev'}bIN wReT܉MVϰ  Iߝ v'v'D<{&GK#Y۱`,XiV| MlŧphiV| NriNT- ЊOVSvr4`+>'GK⓸zRy:`΂*w`fNdUM-2&'gA6`p0K=ns?,7@E=nD__7}'b+]u:$W{^_z|?UWt(&LC >dSah݆ #rBFfHjRo|EYZ44_]`ǫձeM@W4q=bG\aR ⍑woNmg'2.H'>VvX8&i 2_N8[&M8%MwΠM<QDTfVވT}OT(~MzRA=A)JQ MTiʧRX*mʧPx8hS>[IKp.2\c6[b]ԙLj~ RUJT' 4շ!Mdq->F?[|~$ xw,+ %A2YN%X? >1 k;P%lu`G}o4W$\4VŸVybIr + jVO_34 &_w['&ϼoyQl'*.ٗ`ŖIt9OT=/>[-,W0gRm54b-mN.n'WyunAz-Yw*6Vx, kEQe{zY. J6 GtKz%`گt&4ynU[ iXbkdy,Jy# 7l2F9ss_~t/emyn7÷+Vd]Ğ& l+],v-k6[z .qX _לHr 3GRDógeHt\lG# ކ=L }l-A1N[n-SKLnN"Y0MX8'ؗ$"V_O1jГp~L`<;"<ɷ]k (S͵a9dX>T :p'(`eyċ4 lUӘ*W.=Kψl.uKש|m%U }Q4#toim~%6)!8`?ÛNO4O [6aW`ceY$\C1ޝ|_h]νT,s!GPI"$<.i bчU\/Fg]^h~E"zc[")#Z ,I?Ms:̠^@և;3}{v1v6(#wy``c^#"~<01*dmWyXl$){=Iy~_beKMO?V4c?=}N@ReX.C#8@F:j0 6DLJ(+ܰ.؄SSեu#eQ@nE/j?*e)|kvDhe+P_ۡyUťF'+~' P1ND&#dHGe @:\*\t,Hqҡ2<;ƣY=Jf-"˂p"hM 58 ‡D@‡i ~/o6WɣE*¤-L Z8"PK#)jd^?Bm I*!BI . 4$9RhHrz+ǟZMc:-ݞ-tGYgٯ] ToyaiSo=DP^1UvO3g^P2^3fű6Ki{f)#` Rj"ض4`A6 ᱹoU-j~FYkڔTӕo\رTwP3H\5ܟMK2.TI08L#\m-nkR0,M.XvhØ>fB\@ƪE{uuv3ewZmI;}دT]_$<睚*ָ;lk`5wm;~W-|W5|W=XKwF:P#@P!@}(ȫXPA]!@3+t E( jXLk b)A$`*XDkb A ~L eLmć lB( t=vj)un] MFo@Ǒwji$Ky2Cߓ!'[q ERyPyŰ}Dd|{ƭ8h/ t^b Ya[gAY/oc Y/>/tt<# kb(|Dq8xsiƿ=`'ҸDmxӘlƌE1r捵lZ7Z A^0i;AeWDbfXmak8:l y-anC:oӏ {:hzV PcjR^nÿIMG򋦇ty6$a=BEi]SlH5J\\Y"UE ׶ŵwDl`m})y]{fCFꚾ+ +D0YnU~eƖnGgs Zc4sIWlI}w :$:(H¥<56=9G>݆v57*>-fW #r7Z}+CPy30G>Q9slanϱZw;=S_riN}]M{[PХSeWBԩ..q~y]uO[[TuU1[1[61[v1[1[1[61[v1[1[1[b1[b1[6c1[vc1[c1[c]1zXC{ X!zG%ִrݛcg?XcD/"o,t}oDXL(B:_7j,݉ԅJyP6u]t$C B.<'k.Y$C$ ɭyBY:oV.<ӽ.<ow$@}a!e"ah\0}Nga3); O[t!|& \u Qv!drJ=]7k]x"O OGĖk<[ntDlOGĖ+<[ntDlNGĖ;[ntDlNGĖ;[ntDl s͝ϭWw:w^J 8R[ BJQc9R K:’ӍC+, K'Ӻ 3O F 3 ǟ0d07^uˉyDAr{t;٥|u7K6n#H:n#H:o#HK{@AZ-Fi5t,8xWm 2i7`S]i~lwIru&\^b~qi~Kk~eбfKp5(^ ]Bi-28븬W,SL^kVP^`¼^/k'Zg%Pynj[/,J,16eS\1DŽB_1`y ;}L((cB172!wpȄBu2d>,=J>#*#* ̞#c0BC s0>N#]-C~m<7{5G:t͍N?iib>-F rH"̗u Pn#DF.n#dBQvpF(zGP\nk)MLڴ'߶y,! T(͇tPAPZFZF!C"7Us d0ڨķQH.S#o5R~v#IBF';uR!XZP Cr]zt}N/^*oRy ]/Qa/*aH\D]7{K48JwNlYe/Αe/2ih&74gwwi={I;`pj[{PY>o۬##)P|HJ(CUq$u7i\'%dJ! ݅BePkwQgShBSSLwFu`*9P#:x|݌ޔLJG JfЃ)|H3ZqB;ffП--V ż^ 9P4ӗ(|Hьf>*Lf>* T3|c+8rU23RԍvEJKA%fV*Y 6cf9N̅hJFIk乶SٯV^WJdA1_+ ǶFFػjtWXH[vi׌G뉞WwVn0QV y̍a֎tSG9>E™>B OHa,qԍ L֥jhc z` Uk_ژvMFg Jhl; cz5tCpZp"8D#A0}<)["4-iu[L#+x,dVga`sk{;͚%1lVeJH%cIߖz?Hx< @`>Ya]AGb? NrBF "`H_ЏĝuĔ}Jsߩl^rp#O ,M%BȘ/\!txATz/ ZQ;t$pwycEhv@4_VZEMRrCFB#H`Ǐr`t91M`՗r??{8~ܝ>݈jS/sn`ls,]sb_$"%)j%D>~}"d gj~@Y 1||H$Y@I+z'䣿 ] h} wIuKb(mZCY+KL9rqjKLr;{J_Z1ML*~>l\-,1xf뻘zo kbtzbxr@n܄>ݚ[ăuUxs7qf,xʨטHW;Ŭ%'3ŤGq~厜JO`bmurf Y6K0e?y]A?m{KH0zkAq'DR5~n_^\~߇ѝ?G{ UX/*:jOШ42ޤtt}94~t >z\V sœ?$bj샏{wMzW+Be}cbL#Ps?ѐ¾*-&x] NpN@_QhRͥ^^>MR$(r3 :F1[Ha_@)8w!ILs|! ZO/ݚ,;Y3/W{W%𕼔l?@دvnX j\Z)XF"|z Biܣݐ{ag`xw)fDH7y[< wsHMFYm,n L-Z4lCrlߺ!#nA'pgyfk4HilR ,ZYx5qucjsw>-+ Y (rZze@MZVċ0K) H<&K^lz xpM&0L)5$svӷuү#qL v~!"rO" \Ųjhx0zQrub|$V! ?xԄ@uIE\ǟ}` ǝO wrWnB sXzþWgXU@ >MBf`! \|-#;ſz?jc3Ȱ9)!9C6 Naa)W|M:= FokF?_u.`C W>|g$J{o_,e莗bRIBsheI,&:fVe3$܉ ׬P 1[l(d~1pOLVv%|%{h- A+TE}fpfJ6N֓kG+0 YL30\܆851% ʯK[ϒOP96nwu}o,0 izyp.tGrSaP[>~}/09N0\ȕLqXB=LSF>Y@&5RLc)h(|0Z:jxH t=eW.y5!_|0`0' erj ^fQ)dV~+=r0Gb9aBC;6TX]Sw2[ ;IέnLlv=@7ȌA#Sdn @3ގ9ip@wao]Lxz#fx1b7V7^0d->B&vqKRŒz^W<V|}bO^]y͠ %mQrM(Sd2"6͖pD#bb iтwprw8i~LBB)cB SR{S$Ԣfx^s]46bU'Yg\w(< }P(q!칀4 @2dz]#Xw)rMM _oo|O7L} yuǦ,10 HrmH^N^1B0N//m'oSŋi=xD䞞sǝ[w' >#O_|άSx ,+o!B-uA1@/`ME.BGa,m5nTD.F29gtIV!šk(crTc9!`BpQ&g(|T\؉)O`ʸ.!HH¶~IA΀?24KKdApiCeRaTs[p^(y\=DzOQ. w߾=rW*)}T@_1 |l E+!Y=6 ekٗ$1{fJXⓣL%lJA p (acPU H n`o ۾"7-v"GiYVq]bL z* BQ4dD,P><-Fx<"{b GbU%uc^.qSSO8ޫ0ywpPaO^-Yt;C.WMŔDh^B oh"žK,CN<Ts?΍zt zdDre ZxsQf'0N+J& QS3\ebT( "<1pEV tL = hb膴vt~Em$~C袏\x<1A%r2y]17׻<Y:uːI?]w10؊x483֙:/e } HpHm[Q]J%r{ ԹXbz Rg_'IaV< >^Lo.{}UsjYzd %dH !>MB,nZ}NZDѧR]R6z*óH7H='\=EŚ:bTHº9ȹ!X`/6XM ڦLg}0:΃Nf Y P,!%X;#I1Lz-Aypn֨p(YqKc(F䤂Np-I)3PB_NOH ~wLѷU4SGbo7GMdi1l*#quu3d[ObPZv( RhV" A,a_ïqdׅfm|P,sL/r (*@z;8RbkX0+)(e>8W78+!ŠgR`$G>&&86KFEiCf^.ѭᦅ(k/FYyP,mA# x *Rr3 P̀p? A3plD C~"dŏ ENGj2H^WO,IΉ߯VT@aP"W%rŐ?AB0Xg}BÒ_1BkdD(Kb~v={Y6ӌmkEx{ف`EҦ0 sXL })gx^/d3E~*&?jor,ʇ(8F~&ꁝ'|CLp Rg =: c0c8]u3| G\C}_ޅ plFL#wȀ L\@c5=|͌(y_OC}ͬ9Dizu=@ $Daqd-og<)"TM"Pbd}Xj2 uYБ oSh _ Vђ3.vsAX×EFVdoN Y%m$P ~4 }92vR0m*,?*d*$]Üď zPmqےr/~Ĝ'.`{n9Ec#@ -x;=& RʹM`~vn:x'sC]}!di ј?S* TBLLqrN2lZ&TX)njO .SȘ^G$Z<6PE$Ȗ><F`sJg < ,ߺ8L'c):> ufnDa'5egXOx?%l٩FGKL(-Ķ21Bx9nNuZF888Ax"I_tKOv'd'!'yG?{`}@Ve:(ScJ0RW{<:F-/n(~F|̴S} tOo[@(5Ys_4 RdDZQ!GF|ZH/!cHNO"Y;.p 9Qо݄3d٣2c6I!W ~ً#Cgd.۩PŗM,H/3!A<y* otWM8p6t P" D']݈nZai-4F< c|A<! = {9%_2~rD:4PfvE.S%?Jgapf|{2jDB\JiH Ꮑ)57M63()^WT"W.١M.k/YGb ~4T&|&.#IG2q\(zŢnoMi{UFG d$n#41 Y) Mnjz(MoHLdXb?-F9 8uT@5ePlBxPU@8%bd5wࡏL~U-g? cǨd^Ḋw FB)_}R XdzJ g5 .л;_4A,kT!3b3̗BO,]yF\m.qV,vZ>ꤳBSiTTj6q{R%'0A}SyA~؉J׆{Ai6^PFrtFg<$U"B. :F෠-6eW(W_Ht'"O^ *Ú1z_Ht-~̇- -^'( <Ñ7JJ{R$DaPv50 #{XIppI'swτov+0,&y,F#enk T.!|o WJ.HG$;?xgQNj1 G*)-'s>RП䶮_l!'Eפ,S p9)Kq`i9px}wU)I-h,8ybV"Ӈk'a8:qnp !0N&c_H~cfi-U400BfNw A^rD@ߞCO*f `To5],a)PiN#iDW\UP2**E\|v $6+r/YRy2zj-"P.I)-a6Ey!_ӈ1p9 'KG_VQA +MIع^l 21XR^m2!ӳ$-K;CSI$|FN*UBu>`)R=E*ʕ[S252bڿ{>ŧ3޵x#`&,(G:ԺupN}j%\ F],qy*iԠ)RרS)R 'X|ZJ@SQf'rbNrѯ\/gstʂu 0S;z챨pC Y$W@VՇQT5Q[O@XuR*T ѣ GA 5ş"zJ\= J$* +@º3\AG*I!!}{,(AlU-{G"ZO| V8_O}X2WcS(=yKB05F&+[9x+1rbqYivqو4gO"~?X;? Ot~Swr~ƒ(DgcXO OS)Y2|*l KJDH +$<]YgNοQ]? &ݍ*VLVbĔj3Iig(Y;&9夛*"Yc ֘bCvHŦ9HR9H.}6ooDz@co8!fe=SuB^v5ߓfŖe6{'H,VaMՃȽs{~FF-eƾ&5"q9]搦=\>Dg8C2!"((\T c-a/k.\<_?NtSMSt='CO-n^p7o9['?7O"א~ {_ܞ  =qP$Ua{c:2dH[d!#-7 NE^!h;3xד 4`ktҹW4`!h;ph/pOhϐڹ=CF[37 CFfhK)NEF'$  w> 2]/v FOHR'>*CP>_ # (\L}C`}a2Xwn)v]A=Dp_ȳ.=.؟]Ccy\b‰E>SeD+"΁nZϙ"_Tgs|Tqw8/n˜G#0\TyVHG?} XDŽ.U`'%c!\`2N,9vZTw-׉~{{!^h.o/໋Ocn(iYHt>Ԡg~Ha/ł݈)1[sQe$QF!LfEt_eWBj:Ŝb@5PFߋ{.p&;ݵ8 }pƨ)hr0| Έ?nW W1ob|by=)4Ntֿ# 7€̪]ϩ%.?ppV;-?# aRpY7n1咑W$\y[YQ- trۏ#vvHc}"$Zx!M)*ߘ)r\z;p`O9>wQ)k\nJzN-_cY,N_3Fozs'#m`Xk=\ #x͵,O9snCm:GjZGo$ُ9hԡW0u"cӯW>XШǕLܟBdm+PwA&!&-nh,Y#Q |\))znǫn">uM/?o!k %+y@o= E)૪Qtf;*$lŔ_P~{oDH$S7y|?sS~w0pA܀bpWndrn4 _v+m@oL 9ĝa? V@&qRxA^rG|_Pl\ſ\srψ LgxGڞʽbMp}~ Wz^cټWLU5"0uS*S9yE%IyÐɘp^Vʷe ]S|SY%lghϵď:0nڀ8:L4", afҍ.b?.´ {BD$_x. z1Ay|f_]p 2}O]dg7ƽh|&뚔a#C](} 1C_6p࿾Y2 R7\د҈^7$;ϱ"Y[?B6FT;eYyxD/$z@ Q% ZbjTU^C;FE>BW0ǟxEn I!X@?@Lќ1_165)>z𰲕W)L1$ /#:/a̙Q yc~/98y#IAbH!WlD!£SODe4r6s+/^1RY/(/,q$K2y~^1W ⹘ 9s|&o-?3#V%*>w{*"no5>.nE (f< GEa$z?vBq0@H" bw1:˻JIIQ&(*H uD; X$Lɜ/a4!H:=7UhzJ` Y_2 }$tOcpN"f=ZH󨆉֏G7g ?'wz֏ +q凹ZW{A?2~("S^yGz)}leCr~>E@'u(6V6vRk)*1 Æ4Y?|r7 aݳ/ Mn?$D->6$…Gg㫦tս/?kF'OIU\5{W}eu~%|u1IVdָQzaA 7fLwӯ3G?Lmr"oJw5H0Ogj2> M3A}n9dvxf{L^5Ywskf42TZqY+}Ñ9)|6]fcKodb-|1h'ٺ}ankНm xn.EgI}|.2`$5hvƒG_hNj{ێͿm["lB=Qj=#\j6 YY'ʍҳhTU,xuūÑFD]ݏ1'A"N DzhJI.[Ȯ_5 XB. ^$vDbs`>sǂI m`kW:,6x7?d_5HI vonMR>0yiI??ґdq>~b):+%"}"S@)Ra2Mt?w5~|[}?k;Mn󺢛c[6 >ևwoB睞DGE`Xm7TJs4DP)h٩ڋQ7QW{d[76cIUT Se뺭hx*Э36,phdZCx44M]\_#kSʦ.:68LH9ѷ#:?/D ɏ_1Mpᡭm S,JuL@uk&[L|*/\}o_C04JRu9Wߙ:s6~y@v_h:XozarbJ9`2A9JVe RE]˫\qF{ k72:\H*s46nJ %.vk ԭ F("6)`<ϖ_:Z u)>H]6"6̽cArEBwG7"Q&]U=Ϟț#M}C#d|hnɟ}z=Ii QqIt7IiRIM̐Ztt 3X3b@U)f8ٻ0zb_ĉa:|ec(߱Oƥ63D.u1ceXyqt] z@C[Eݙݡ)z8gCpc$wdRuI'-C3OڠvHRWP4/)s|vS6( _ g U94{Gqڋzm@*{lZ]^e3*;E^DC m Je˛ΆqсTᑢnf4u=hsCodЕ'GGܷSGQl|4\Sxtϖ Ke(5!n0IkX  HBy4Ԁh!r5 9 MjYc;Ύ _'߾f?SE 9hm7tOyT:'@B.W^h]k^rMd 0[4S^T=bj#4ꅶ|%S$/fl^h]jf)>xYvR-\i"HG]Gf);$EWJV *CSV G>%geJGC3@C{$2,8i`JA4^Z&%8! &6H ǨZq)F#8Q0rMS0jcM$) 㱘q7IԦDh96 bMY Gq`j:հ; m8ZtZwm*Ө12Ki{Z=6yVwbQ}̒3aG7sbנ^>qT/fn}O`='5S~xdž/8H_$4X~O?xpRT>K%UCA"X\,Jfސ\ ^9%phzr $JFziEq`:#^l}\duTm0@-s,荪Q*Dԧ؏ց:%݇ u8S53ސf.T"6 ynj3oĭzVRYuU>*eT=zV)vM:sF>lճj+E7T*YYU5hgaճا$u(81+J+EdXUGԔ$~S >_7z.V;RjfU;mkVn\(q_RS$'m *<)kdUL4ffCvGb :F{/ESEG>ZaZn@o5;j{C1XmDCmvHE>Q#; 4ŎK ,HBq:R +%8*"sOPW*L.7xt [al_i?guCJv4fceeMcƫu1 9RXT8*70,Bw5hCW+J-8/&YC]D{-i#a + -o\|%u>2ZG:eH`ZA)yJ]TG&L\٨ ս7)> Muo+oQ[A/+l4 MT9rQNuZn0] I6MO6yt?iw\Vr#[й}j X_(caA0ZX96-,Y> ]+>Pt(:S]6h6҄7o؆15Fѽ7`3w8{ڄ1 aET:ޢ|PRBQw54oWZmH[٢G!83Eє̠$+{$ A hڒ:Qm]oo,0u~X`vPydK[5бZ5Dt|U>Ⱖn0_U]4mFjUrVf[Uf k.3 Ӭg@S (pM 8z4 u$dgg5KR$ } CלADvHpf;8%.f-IJQ{ޒ}Z5g݌VMצ(CBAYWłdŪvuh"0j_`*!(b%YB*2Gi qoh>~0OFs~BxѝZ`KRbe^ew3~L|Zh!97*!7U)8x{{.XWG%ufLT"-H)C]y mS8UDg }6RA aOx ڥF#NQp4QІe!X@Dי͡8"w%wM9p61rnY%GOq] m%*lŠX34ŠW=y^!3=}`г-HfXgG.}"ˇpwŲ NX@*SOȃ7hi +o *&lF+MѼ9ydP-kIiYEZA*[0^yhI)r}rX"(:..=,LԆRv-˜(NY!4){S^@1ʖTXFپVDo(DoMkFsEVbyT1۬ .ܚXu+bT.tnFݯ\B-yUa%Yb&ܹ㹋lZ#3IqqgdoZ%_VccCr._n/nD"dyA7?/8M:V;_`ْ%睱V &߿.Y8FNO5Քdhx^G@ހJW8Jc+}"WbAzBa[6'z?szZT5 !X݋lxO-Ɍ.i7U/-Y-.uMLI%Ŋ.g/qLYhw6:3=$wKuΏ95Kp( Md混aX:`=O-i;2ךb-a*]G-.&K16*"cD|8Hq1n)6IFgD[) Mh0;RDD"+D߮88HO8)E9L-8\`GUu* k8aij0ɱʄkz\zQy>[H# .;4Rq:Z@fcT+5&^=b uW^m?dE+)6RZ+(N:N)ɫz8"}Pw(R)}1?iۆ,UAc&a PGCx_V JR\ 6;b Hs'ږ9@#Ғ?q"?Db@0פnqxS}Ew􇭍'ӏbczNG,+WO}[4tG9N:NL΁wfXRE\|&&M\F ?k1k([ ERء{;aĥvn [ ?Buqq$K:h\3Ռ[ي1LYf} Kf4RVr1tUQŽ(5|S/ld|a_09g{*ry[@L+wpx4P<5=⩑L:wXT[8*a䅫KmW:?@$8"cM sAQIO5\G\GbhW6}pnuP<etl5?m)h&`wcKn(;GIS^ )@S(q5Ja藊;7W3 ; TePbuF18{ad['3] 7 piSHKƽ=-s{ TyBД%Ќx'΋&P44E4L]`괺[΍\\DW;4E.rG}\dDuKaZeK5v "ӣY&U^ Fu+jЊ5 [.6MYp\v0yDs(ˬD:ԺR~|uK0t:3m[֙[bgo8L) !c⨍wc+N=l/BT,-2] H%;iA:oyZt[1gjQ9h0GbhQ9>QN`c]*cC*/D~y^f||+az5RA == c, /ck띑bCd;lU*&UXX Y*;3xS9|)}0o >'ӏ3~0fl߿Lf s4Ԍ~ ^[:&ќU Cθuf9j(́u=r nG#&r*VAS%؇qT va0KU6HTv-?OjYz@Fd!L77h.+/E|3 Q33剔# mu va3mᬎtyHD.=?_u뺖oR峗OXiCUb8*0CQ提m7ّyJ58XاhŪx4rP;4|Z}~"H9!ee.Ƣ03_okm8* J2κI+EVj4U|G' U\抓U Rl ;̷Y?Slɣh~7]\WԎnox[ TmҋgjL M6"['$D9TeaeTG|qӆ.z , YP5Y0wѶ9 SNWt [ (C%} }" !rnA5"u_PN?&;ula@u;5 Kf2ˆT6DWbݞ>nn~Хw ۢZunׄRMT<QEwҒ#C(J3gcx4Uj6ƒ̃hrt`M9˺9r2L,Cf (ʔI4* ֎Q {MQQw͆;E PbG>Q(=cFCC*X**:]ņ]Uu;AcEDPVc&H؇(x˔<ء)ʃ#8$u(*N_3+:&xf:r*ZFxy&Kr4=ȓמlNuϩ%[ ۋ:RsZ0A^]5ĆbmN0ȉw 1N ]A$аf *z{Q8ja\*^Hե;OUHb nUZ|&7̺E!֩7naym_a޾BP CW]$x䃛j&$tܿ~q'\.s,t.miNaTbz}`J (Cw>"QJ*L|ged*жES>e&"uo7v`{Y[i(O;Ӳ3 W[ 1K܄c}.y]UP+/Ȱei=) )*:۵MdߐOޱoHX7rhuunc`^% m\0M>a~Y% *,߅ULrEkWI!NxMt:q)S~p֧eKհlszl_(v㠕p/~=%ܣ "'g5RFoXFCӒ :'4%LeBo2:RqU)8X l#,JȣZH(+:5ɆL*#S -1rNj+@bC E4ҜhD*hDc\6CstPQhe+КR)c+ BvHӤv}ڶ>Od9ߩ<8hWQρcVho_l`=wg1L#R=:O&0Am2&Xtj4NpG4G߭NP  !(Q>U 6c4fPU7$;_DXӄܞ1I5i/gJTLslpN,df),Gqrw~vѭ ma'|]E|zEeb(=hÒKLP,ݐ~Waٖd2%xEH#ނ7p`A$vJ;zL%mr86q6N:ZgS.ᱦwutB8H 7 RVTMJ!q(\hܑ?6Q h*0[rJXb)I%-`ԄC߮CakA_ѕXܹd9fTu4> }i#<մ, V'dG$K0|8u*2Y?S5E=TL.l.?P'Z)k]]Ř} q2y%d2| wA;B]ٞߧGQV$%% l4u?O)}w!X)0M^{pc>G`iҒ@~&jګC{*VVztK1lR#~jT#Q ~STaXk\jWCۼ#|qhYśZנ8gg%i=q:/X="ƉB9Bh(T6A@䥥e!]mܹ.諐mԽ:n \}&槀Z?Kz涵OǒWYwn{v(/FN~_L&K C a&ս(["xqԈNBy\+Yٷ5Ԡ88~^p({kP|4ݕI h59*뮾iK^BXZHcmvTGSyy-$ 6rg`eIe6IVQr܄RgJh;IM9|uJ[ࢸ/0c]ӆF#NbV>I'Ѩ~Fha4U;#y\o#[U8cj3m#L)c8UJ$g LK]I6{/vOw5Qt]oKhxFng%E>4,-^HP6"r[uNZЁ\с ݅X֗j /g7F(#,>iOB?B!6=0=^чekRt }msE:Peh죸Ⱥ/l9${|yXRLף8g߭h*(ι8/R ݝ_&+ QH$MVf@v8Ivxl!c K6AB^E/.y"rm a\T\^.k~rq`M<'q*dc㧎d[.l3kjZ״\Ve,@kgW\`~׳$x䃛>?FnߓHE1OSKF=Ϟ-+s¶D.@ mn~99l\FP/RmYMl©D{$` M05&[cIVYS)0a{,u$eW㽈 yx/|ЮFSއqTwq=ݏ.'-A- kHǸZ϶:ubϘ\ڀ=HˋWyk0ujmHœ)j4ڂѰ;wLTիҟn)2 cj{̋}TM;z]w5a XЪW2C(}\F4 UbKb{70Swk>m*8O0P^e"h1K>FLm,_>qhսhkv5ODL$zQ͠GKӎlIuGv 2ѢEvQRh>8YR@상&̕6łgFL3K$ArC>]h:[V5MԍZ kvV$wJ%>tM4 g6H?a3 Y3cܪ<N/ V[o&jJJ ǷoA:<{Ј/܆fYxeYvXʙaZ0pyHtOCPlu1@q~o=w~XRaI}є0r{7G-N$ۖd``A`34 `8`-_slHZcIirCՔMqUչr:DX`]Gljz%_”?f˃Kuo7\+:ǚ~x;Z@JJqsUqk6hh0Z)]/0j8;wR}K0{aI&B5GSq8xQ󨚋Ou#`Z +-𫭍HʭL. ? ^.Ďcž ]Z[x˴ A?@zguCS>z,iƖ MmB.RNytήucҧ &r|T,Nљ-j_;Q؃ J7ӡ/U}bΣh3%dV,d;mCzm8@CCVY<20cv=q;3m2z+u2%H'5e2Quܚ j&0D'tɥt| *]وݩnӖU] $Ih "5VE ΩU.ZU׿s^w ".V0zrwk]ӡmum4 %d.K >1]`i&k`N_/ש e'vy xNlu}X;cgp ~ZMXaF?ki$j4U|+]䩧.60B>zuit)w\%]z ,.gEpTO ?Є^F*7Rp-y2i1 7 nh)h&n{zO" m~{M ~]A9\-$.g/nz[u/VMqCBgPUfjіԱ.He8C'cP0SK2a?ZYŦ]g$! 4>cύ?bFS<qاڗr0 h\J8HJ{!k O',Ry0KHR٭ 8Gp| uq&븕ՓO X];nsgCg⬄xSYO;Py]oh|(zKq,!F1CfQf1=rͬ1n dJSPZ%ǨGD]`QBAN>:a"+kTzd,șr1OdF!C/*iJoP+ ,neXl+[1Iy5. X2զ&X݂UB1GS Ņ'zH8wW/V5`cAB"Ηj6h=o 01 *k p[ˉLhb *vA^=bY-H,;wl!O֒8bTC('hW20LQ2#i :L'ҵ܎I$sF'ſ GS!8X!Pq-`h$" wLCr80.'PwP*l,oT,+ =r͓"ܗ,s u8فqS7zJfrťhg5gvjH-0Cc,wh(G'T|8Q\+*ZÜ Msm7FֻQh?WbHOVwtb zèj\hJKj1\ȥ&E[x z)3S=aTO#j)QzY)-ϒ]H7f$a.6 EE^^[p&! kp >MUx~\'_T@| plSQ[7Ru8h,clCRY2`Je{GWm 3gmZO%k:d[_W[ wr65Slyt{w)pfSvKb;5.UA/6v{< PDaEU[OJc>9%@t@uW)uDu8V>462uڇݡ2L_Ggu2>ueCK6qKxcK㭯w.ƴGBڹO犘3ǩ Or^Er5c|"d~A'rph!_'D~ʷOX%S+Rp18"-dX&ʾRg[4yP]<}s=}t!ɹ,.H'RF{n@ٮ! J"YSJbciP-;TlK[ZݺQY5Π3Ha8#UplIiKݘ]_脛=<4n ?7#ܴtY, iJuz4&Q,vbt gp}58X.ְ=_oBʫS8#id'v|>^IܧW6tnQ"J{;P*xԧD-ɦ;W3CPA/6U vwu* ^z7٧5rᶺ25mD8q>qlyl7qpjq\$f ׳Z>o<'3zf:ը)_xNCǂ o1Fm 7:ux3㇁XXbƑD>ܾllll-w|cXo794L>:hכz( {]W[{L%drf[Ё\с ŕ`icclvF|inz7#5+tS)[ B[bPz ҡ>/FaBŧDi6nN ,lלV5b܀09윖i%jx;8ښ!'ŠLbb*$rp4UJU%FE ۚIsRh7Uk^rz6|"bny G#OG !=et %+ xn ,c ͂Ϗt -B7eިe9e@!:;E Un&xyf][թtQOK;madbCm݊IBO3="3K;Ta^5I(Ӷόu$-2`ؖM}-IQM/k 4?r~ i~Ñ&%Ÿ%Rέ?őKC*diLP^^j9Wd9Nqj8M͜j;0Čމl\c$ۧl _av-tvN|5-˞u^-6T~ cIU",IkX~$p&̫g?d?(ernT(=]mۣ"~2Kg~2 xQYRd*Fc% 5-9v#u?un7޲bhYL]7Q-34s/N f}Yp$ul SW?4]N݁⼭;MNae9- cz?/Ux>EGw^5Y9ɍ:jhwA{d3sҝ x̎"Tܴv4Zӈܬݫ)Zo(۸%c0/,L8E`kROb:/) DDx' >dm}x$$b\~{x"X'ln-Rŧ" :\ 1+Rٽ?;H%ke̱5dk_TԶ"[: bKY-rږpjW tվ(S aTÿjo4酏Ps# Z7䁞$b(CSn^ kS8fЅB/uysrf-dS&tʒ4( #4يݍLrfhu?C2 amM6BI0w$݇Koa@km~klT{`. th^PtW D|!U: @`ZoU lJ+ZA-.1Evo0Dn+W^<4\@׏I%~^ lab^w߼A. +QU);]:B/@iܺv#5s5[ؔe'0 f XGҜD.w(Lmuش@'2@+U &x/GK&/Ԅzu]4ً)o@ 7ZD~"b}.xe. K^iKJuj'qzn8. TpwK̵3vQ46UtIF5RB$Ŵ=wAVj z1cqU6@YLK—H$  O|` mӾ=|!߀"E#Ǧex&:4Ds7qْ#ilfZg\$b0Elk3KYp ysd2 ^_;Yׇ{6Q'ө a`YI '{8m+tJ@szaZj[6D+޻̳_tI@d) ǔ&|:EC,h-Ytrfr!}O[uʱiȕL(e_)0ؔ;MsЦVM,96 -]Ə'ɋi4p`I$zŸ/ek~ l [D϶{5L[\Ћ_,`Ж햙paWr ބ kr?ߊE=}xss C꾑9)>{(h,'S7)I/4))-F8h$paS"$\V$(BGpOu`O+ggkcؤ&z͡ggcޫ%IJ}S){!1*!4?<ơ<g/mi}6וTq޴D BXσK 9j3蟌Kܥ2n3Lz8J:Oݦ/5$p itg::st`E…\/32#5y*sGmUL߭r1h~ s瀼P :yQ"ٖgXӴ%}&<9}~RaL˜GpΧ6ҍ{/Ǩ*.;Kؖ)2Pb]$r@yimk>dcP;gb jA*Boݒcrי)QazuPd٭.Ӌ ׊@f+Y8H>v~8eSbw^0=,M(W6ƴexͬ!x&X[TYۛ#aS5ЅL ^X Ueȯ*2^_ټl&cQ, "X'Xy{Gt#ĔbYU!4.G7Jof{vhn.$]҆<7dAYOE7lTEpSv :WpEl0Z$RCBǕIݦvsC~)__&ۧDXd.JUn %#R)*[dDTPڠsmr‘XFHוbo um,hzء]\mFO{KոP$q=Bwu.4TqCh*wGCZ}a\Յf*"O3gۢIE zQz#͖MkX$0} ~Y%#~5Mȍj0:Ukn '\NPN1\wu=U>Z;YCUat#Bl]28GSEkGpTZq6_};`:UZιXش9Wrf~Nmc$UZӢh.[&|vhmDNj?'QMTsQ}Kh\ tMM LK/°lI\<.©>M]*-\UμI՞-S)#H]Q06u]rQ]W{ bJ+(׏-۪ρ&ܴsO،dG& \p4Uz:\j|raB# `d 9kr=2.҆qۻ!Rm .KEUϖS):M9 SQ,՟dWYxz?X*P.mKM6^SE99*s>s.QN,{iG^v۾ VOV(Z U!4Ux{Ge7*mu%) هގ$=)[#l oc88TmK:UmιXҳ}6fގ/\x3_4Ye$Q}8fҼ^=2!7Z~ [%y{5^uDvZXdwT+T593 X؛h00 gSMf>_i>]Nv]I>v)X ྒhP^rQ$I41AyZ_w\K:UOfuO{ǃN2Qhι"1]~>*g\Rl\Ts9BMvISGhMQ|.>Յbhש'|.Kc?juYju՘{*֏ML5GS{՘ jH āgP.(&A|QC!Wjt8!@y!˔sۜ5EY:!["`MQQ鋲E@/Ep/?۬[1/"``,EXi(E lTl^M9P9wWH1tL!]rV$7+2;kn^&cb7—ɋ3hV18Ի8w K hby#T+O9f`~31;u C>XUzrlrNa{:07c<Vrz|oĤ{Y>gHB1#!IٔȊ({2 rq1]CQjL(bL(QLMѡ9:Np9~ӡ('PCu=C@f r4Eq\Zm[S,C͖orpOs)~}4;sFKw᙮ 9̼z693ĥj-ƀ^8%UkeTU8bS t31"o{nH&eBc1WB7\2v7ks? 9 G314t L3a˓VL67U)PMM9u`zyoNwݽd`cM,ĺӭ,gMRM{:m upe(1R9T@kqT\*8il,Tq6eKeŚ`%BmG-/cc!H2Z.;[ԀҮ_uUKk(%cK2ߔg?/K7z24E Lj4%#ƒ`~U+֯ZxF\Jع3'xԠZ WINc }_GA:HH\4!T^J{x"XmJ~;q8 =( GT]OkE1TUd7}.sZ}]u6z;/k,Qj#_4I4_gצ{tW{DQMn>}9o?Nw+7qLlŒ=<"yi U!9 Bg].牱mTÚgR-!h^N18˪>qթ#*a.aҿ֑nJQ6,PTt֗PDKݺJz?$L S"/-߉B5x9/+iTvLeu\$RDh/7L"#SQ, y2mu_֡TS˭v O갅wzI#6%+Hs90lN[]peUʁrfE%5?NWKN= KQKnb`\eT4vNފRREQpD((U֊:Wt~Z*gs5H-smfd, ;3z-=8Zߙ'z9=w#EϤƢA!t!b׹}/ yM3gE :U: ;\y1d("‹ZK1Iz[ٔ^gɛ7U,;M9uKm2uNw{jt 9 6Liݳq[Y.?,RcM+/E[o VFJ, ϦF:s>FjMQRX٘kb^usрIHM_GSTRGpM<_H MlƗbYSw+Qw)v(&Q|Q~GluW%ι8r[kCƺq] L](M3.Us *}4u GSkpʷƦ||:?\k_C Gdh,lk$ Eq0tR(d[SkECS1u !RN >PU(2Z߉cFXp BzKC5E͑kDHۅM5u؞WtVKRb ]8:u^o0ݻUjCZiPekrfdrT) :\Wl{f0D wV~~'뺐͛t8|#lri9j maS3$m]@JvDvB Z. %mSkJ,kp&+'R@(Ȭv!4p |K>J,9K%%8#? -10O<_H4QMq5xŚtib^ztپI V޵D'JW~ҏਪ&PU-QU7[X65ˍ楲zR>Hyκ*]iֈ2:Ch*UU>Ś:U \|ͷSuUCMW3 3_ 0QڃBܱ.rѹ}^@hu:CG:UE*-J^NjnڶHH(( nl ˎK)HPg! I3CHV\j҈`E4ސ\NQƧ€ 嘩 Iˀwn ܭ+~ ç[~HD `EtTijb #(4T<+1IT<+h*UJl6*9Ь ^P\;P0c#+B W?W:J|9C yM&7ߘC|2tdEa4QDfI\sK&\,A빆4EtӼ/c 7Ĥwƴ0睼/wt)λ#8ȥ81e7Jjg3R8,aFQ.^m$T֧!DjvY~א}wC*g!4,>ơ-.T*qKl[>8 `lbBmG->x5ŔN7RwAi&K*?H9 *山k Ǡbm pWU:h :kP&#E9%*!48ơ-SrJBCtJ )qηrJ;%4HזTz 3zmYc{Ë#-]+Y95V?^nHUPխɂI[XN.RiTXLsy돏:*?9e2&ӯ3gH/!D[ A;s4mR2k`R(Ո9*M6x?eِMG}\?ZmXcDQǑUD|־S% [}tGɡ)/i2s{7gsZbĐ)Sݟ#ɨ{_ ~TSiEj }PMoo8mo M2} ,9aT~2!LY?`\/9f]e,G*HOMݧTQܧ.;9 *i]UvoLH.pb~-)[f7:mї%5E ޞ.m)y{CdD@ZS{5?d:tlEavz,ɚ mرrlj멆1㱦R5_:iK9sl E } XQ۟>3crb/\XV԰J9ք zC47oXOuKtz#5-ͧɡFx9 ?$BwC73fԒN#54ш][("<>r~3Jyti#\0ghE[FB*tA][k k-Sw`xb7w?ph vp8gkp,O%`sN<.U_%_4̝&[o%D=X~B;ٶhb[<[TjDQ#=޾.rCXb>bF5 Wf$bp"^VGWHFb(4 1\n0)CGRav}Q#lEPyV,]'?34S6W=?ެ#n?wW~TOL #MS({zt@/]tբ)GFO.]cxѱ)VNI5aMM=G ']=:'jyU u*!ǣ{t,ɒh-EluzdlWg_+XUhS;C]FOX#M֩\$KK-=r%ʰF>&$a,3Y4\_=fJ4{bvt{$Z ZG׻_>w |G)Ǖ>aDjLX 7ҥi\ZEn0_)jTsmni͆ Ccl$/3 j:v76OTɊ@j [>WU |I?2tQM_HW[{ղ!A A .fC|s0҄j@9X!U,WsyΉqӢ^0dO49#L_ipNjc'sMoL5LxDr/s;`6eJƨ;]'#q-RS@a}N#MIK<60A2?%"u"K=GÂ{R>N,|k`h\vy}O߉Wm!!7KjggK՗aLeQ}}| gζ ~p`Lvkl=™0H~-C:naœjЇZƾL1d0Wtvpn^Ha[jIt_vl]}BIV@nj zQ]+w;\wi=?7Jj}&C Y~MՕ=jC޽O*S#)%@PN|67yCY:K>(>b"͒rO/]. tuYe:ߞ+(Ȏ0`$شT kFv7tk\݂9҇<KO|3MNT0;K+r> bxU2sA5*Ӡs7L!f ϔ"ȓ 2L "%<"!c+ 0_V}a()yPzyP}09P8w=D[++~s 1ijI+z X7cx]..U`8 @scîZIYG b`WZK=QGӅY=(rpJ:M)X'ȥ?Ar^zB/<*j3&V2萸Hs*dȋ04J}F>h&lӉ-lY)!>J{cQO &_BDs䑭pEj‡ƨ髅Mש yYOg>0q|0È$vU?u6s;fF:X ?f?bQ;!=]#$WpN>cύ?ȎyX>P 'ܐNȉ;M("'g>N>K<*'eئpZ*pZ*wGfB,*;,/Tx #!L N䔏dzap?tm"<өE8|wAq`CRBE!- +\! pf*u#<0 agG. a<ᓳϛLu#‰^4xQnF,xRw{"L`(HdEќe9ƀ?U0N0ٟh55ȓxEqaIa u'<4͜VpԹ A.~yPЋߌ.e ]'_&ZW$JU_Zn ghK(m5?3S"w'sΝ O="zweDs?nFT(jDd O6`$d18OVliUWaZ8?f]rX&3_l!Qoiu/\.s5B;) FTZ=:T 2( ?@SwڔSԊ$X (8Z@Ehb}9ٗ"W9y$+ۊzA[>9 }t.wK\F߯sahл9C*n?lGw㚹O>ъ"t,!k1@lgRC20ROFt5wG2lR 2@&l"pes=Ïfl$پ^*h*8]]@E0]]?u=xPZ%X%PpBqi&.xF쇣b7O/g_!7?0*XBI &>_ձ8ObD̔T& ˓a7Ab\%Mj/LE6ع$!J]"r" FXKaO#gf-AkK"ny_'aO'=ƔiҕXܹ_Rӏ9]WAzm,iUНX{sV}&XԪWfjꆾ8۩H@- bz%ͥ֫UH'J>V"nVƇ Ga#CAcLE\yuH1(հfI 59|[2{(Gx F>mɽ^$M4<]g::5d&+ny3*iYG70'4B"? -QK^ij OJPƅ:ʸPśjG)ろH'}q uQ ?JHs ?q1aʂPjea'DZi^0 (yJbB'(/v84E LSp4EїۋНsrve?{(/ hF3("eM]Lٕ8ld-3]ᤡ/ 7u#z^ٙTwkDC|ҍM3>PepfjKC)ωy F Xvcckʢ([ce`5V[c %rڛBKf~Lf`p6)NJ{nSݔ]0srNO9P9~i6"`zҵxnր?|\xHaz 1X}Q}q' 26``GRbSXLf#gJk\Y~f$b%*Y,عd 'vyz ȄsJ1}q-V/՜d6pnfhu\ ςpSJ{׃P{|)㕿L܄CM>4܄l.lT!,w7>Hs4X2";0VȾ\s+76yiR٧`?}vșs R'=?LSXII<:$: 9fE{rwS^+vH9kJkBH3{H+v6-Ko`yySc!md-?st7XVޣ@m6-imLN@ sK}tKvQL}"BI{n0_= L3ܪtGoD3qVaL51m?-Ht s:<Er CX_&s!N+;Z#yq!V5al TCJpM0.&+} 5Rn9PdxU0 %NG6[q_8C( ";[2++]v&qf,\?an'vx5p>qD}0f t88/6NMHנ|CcoQ$:K~:l=5}Ռ|pqc)bc^d`dE/D^4w;(hh$`u HZO7¿Y ;JY,>HNG7gohҊڞEʎ~_ o77wPa=mniew.ΆvAih{e>Ys`]n*K@@;o4n'ѫv^!yP܇ZKfxD+ts{E3o*In`FHE.$G5yorרwdu<#583^H#^tc$ on-] 10kN X8?!hKZ쟲NԋDԪ^.Iqͳ,oiiff3{KGo"c,,\RxKH vb|9`qʅZDᯉUQ WlL쳫?X̮<>Ens< HspHϙՂhfu,) nWDeiUz7?aX\e?+@,<1igFC~`hqt#M&%mm20lnȂ^QɆtUs e@:vxÃ9u`Pd@_XͰ )*蛮dbf^o (ލzQ7/wty`Nl JhfpPrPsc/8 D-8k{>P-tnuYŲ (6lo@LH% ;F@[# :F(eChui0l.w\ mIH;x;\+Śض(Fă7)֌=g?w=1 υU kVξ٥y݅lC+$l7>b@`YeQcJ e0 Dp(C~dLіғ-c7A:ޣPEX_dhAY`o7~P*f@] u"1WELQ+ c Z-hc/\}km1#]SZ1_>{I1uӷ0hx(Y]"='8l2W)BMNy.M n.1 _d2y$t@Ν;`Nh.YN#<`$qzN.h"8$0uX n=,jVHaΝCjHAcDtjNEf-N~O/O>N˒yٜc[iT:N:!ԇy<^1]5CCÛ=#"^ rdm:aF6JB6pM4VtʒfqRoWPxT4ԏ~,hИӗ 91;0F?wlZ*.A -8n* 62ZhQ h z5jR&hrl6 qjB34dv~%sIDwd)w:)P;acuc25,gKƌׇ'C osҩxB/cRQy ,hƎu iNW~wEZt{N zg\1޾m!g[W 7[jp{Aw;pGΝ?cԗ&Gr Kr7gC.O27،PӼr6=7tϾ9Ԇ$"D/z6Aymd.c3:_L􈬼2vWџ~& zX5Η/sLfoIZ֛IXy +Ir *.Qł8׳ev N]~SL[xS`-^=t~p6}||o/sŸ ,ouY,G7vr|wH$ Co;5՟'gcPٕ3g2^%'m? ?kvㄺ9=z7SFw7?:6@f$'d()dgtJ`Jp(I%8c* tYm]/68x?'ϫ;^|gX ~ƒg7&K79]}ԦdO$-a^5#~hlzrF <G_,36C?\L|0xƏx[Jyg;()=rX2q %~@کkuc 8{+׬+nڹ AԠ$*LHTٔU9aּjרlZN}E~syo./7Dw;w3͚f0-ȇP"XO!JrС 0O/g^!~dSo1?@L fWE8+}g$zϗfr.$+%I;ʿmkU`mOo]AWm|GR7\Z>~0u%Hڸr;{[#ƈ9,gݐvwEUOiyA.a= t֫U-W+57Y'J/.ָb1ugc#͜8RR:Ͻn0a"mR:el]9]>1ۧ@q+)evwfJI$]ƑöZt#rCO_ P5o!dto1-@?Ѯ^D!o|+1.nGӃaD8 %|F,4ef:4X欚?SW=1de1uÙ18֌ b8^_at0}'='w=_YǿYbhaF:<77B%Ȓ]wn׫E>/,&\|˝x̽&NطnY %tj=Y*ĬZmtXСtz1\̩d4>ߘy&dkΗ0Yg;s7qP󥜉,=]6$sb~߸[_{u{.'1+|\LĺvB mi(Su[{,%7,fɽwxfdLW&S~mN9:Ø?itK8L3{k$"̙,N8IRq O${Do"[ 2_f\E,\<r `t.#L#pm}@j?:MkgI', @@ j /O$k W}GrXME/MݪU3'z8%C}c.qm+;~ӽ|_L翁SN7Zko{}y>qի{[vx3,2ma~hY6ɁyɿfCjqY@D4or3-}1jv. k>, lT/x vf’5ց}w&t% NoۥeuN,tjy&Qӧg~BOj7Cw*t?vX3ɹN;9)E2Βբ>iʿeSuKUM*s{_*\}gZmYM/C*԰A ç[G:]ÏTg9Z`PY*kq ƺ 58Vs-WXX%/C#]Z?܀а|<{GY{c޶|ߖl]P*ppŠ8܈C٘,? .fn{6!ÍzG|G9e.pB~MH0's)7͔oozA/s(nyp"6H_ p Idimu-)WUR@e\0hE]hL=c˼#姬 b!?~?Tuv/vs|Ճ(Rb뢃/)Y®(|6u0*:XWuv ;ؘYLiÀt?>mp״Cijh~0WcWMKH:ܼ?R>{T'He@}wuit}MOS;nڭoܣU]lH,w>1#e aNdž`R"XYb{N_i.5ͨSZc1@o_̪B!֞Y}h߁@B!oyЪB-Pg" B-P+CަpEmrlBA.̍zy;e?AQ?)N> M9#͜g {&K}R򰟯ْEj6jW`gS?"9z֜Z6Fw6u6AXmnFM0a8Aci8Ñ &;S :֧yGz=0egs›O{y3-}:qp[~x} çs_m?4g&|QC^st:0?jkc/"f>CDLcJ=|TJ$^h`]I}]#xx'k?d7z]L?l3ӻO?ݡq@,45i&EZ}YYa7p{慧vgݜCgSE{uRL<({]n| Yމ=eZ@&WLϙOPMTC-ɖ\ ]-ֱ0lW |Z+/iX nr(_x̚1͜ko^NE_-\כ}zK W~Ukqy; R.^7Ĭc#{+&ۼ駬АKN;9_a[ynږ>pKY-B?O?$s5w'dW]|z5wݠtS..CBwlbr|·{[]Q,Ch{y'ar4Wޥr#yxSx>u*1ܜ&ߡqd`щ2bHUiU o16 w?!]l]W'sAjiA+ w G{ym"*Tb% 1:Mqr~w1ϡޏ廴. ,޴Jߏg?2p}I!E䐦='iY-DЯ4ұvJLYzSf (*(ux?X)&[|Ȃ$dϹwl#qcY6w6E0+7p웽 I~iF>,P,mz_xUy%aK5ԵN 'u: r 7\y=X!դB#ۥ|閦- <"4ߤK`}#sMB )So|Jbst8[$ݤbƒk*XJ 5]ھj{$&&uV8~Eh ]=nul;oUDz#$ 0d2ଯ4-=-};$;~7UHf69{W3nH o:0bQ{%: 01^e&Wln[1ݱ$x=y| *G蛺ϣ\pi,JQP*[Uw.Gj.KNA -G+ЬqGZ8zM2QPgf ` Dd>kW)Jt"v֖+ 3Zr<@Mܳ˻:mW8UejpZZG[o|}K( RoW?aպ7 ІX^ !P|51[sr`Z<ͬ9ΜU Ai7pdyz۾R n͞ Tb`̬קEٚMeD,}rC+@o.MtvI\ergD/!$ߞ}}KDRloGn/}U֚џ3|/U9 ONuͰSX.r^+~[d )@DMdO 2\.mdQSy8϶R/r<H^kԞ^VbPn3JvXKl4!}ko!P?kg̨}oӌ,mN`K5cn"eN2L SE';-`r_hD3\:}@tj-.җjUnja9=e'4w{lZgm$Z1śc;7=s (EL0@{0]p&qD$&ѳlÉLGLJ/A ˡBC \%SÐٗ}aAй]}hvSkۧk_J u;o݉3,Nw蝁uErwnA+_Vin!Z`Zhe[t v F8*U Gטr#< vM.Z7Խ7Qh[S~/ړU;d]lާ>Gc$:uU"q ?:)sK Yx=8˒- VGGD݋gY "=bQöI3. O%{P\m{0ր #;# /${;w<k{{a [QثBѳ~ւ#ϰmū@ 8$r (:ΉJmc28߃ML̯դƹImcOjD Քh5vzn^U@ysZ-$V*cU=ЬZ ɦ"RƏi稱S]LrWsaHyU5D:x{z^uez?o~44 Q>4s{ (>ن~E=[.= h":@_]٫kM%GȜ[y[wHwxӷyU-7u00r!9q%*j14st%G̿g7-PAyY|9 ~_{,qҖYqsӎQ;[}>?.wk[|*~D_JIaBʨJȟ;^a&bomC}p=<9z7hֳ,FNڂer!Z<5Äx4yF:X3};Ǟ/ &f&dT\$Qᑷ=Fui<3"?SH'`NΜ;O`77$YG3 E_HΧ 8}ぱ&`k V(Ttݯy {'!߿wـ9XuܫuW)CTnDN Sl0fv˶4wee8v@Ѻ]"d8jMšZ>@boL46QNFH/WjD+oyIE;sjX)C94`[mr9""HUm̻o,˂m@sN5w'~ZKgnc1urǥ[/7}lnVu!hqh>6^ck*>K:EK|agZo/L$M:*@9{۩`iOTVD]'ҚAm-4{;a!2<9N B^`~gOuT2d%j!'eoPt;*K hdzRfgwE[)c-jI"ODy[Uy$2rp{dqYdh[.6V}ҝx ٦KΙsl Sb$ʺ~Ym19V&Ht䩐@o=b3EY%>2וgŌwn{Niw.DfwFgiXQN2Ԙ_ȟ A_~t^0 >2NҶUk\VulOi /r2B4ml"Bin8r%'+Caj8Óz.Wϊkvn1kgk֓-Q+Ƃ˝ӕ֞5}5(R5ɬvȊqkn& rCr\`|אa܁|YqIՐ眊/0{??/$ !&Y YA*4wmwyL~J$̥ $~ ePO`n}rۻMMݼ{ 2?Qr$Jt2:p ɴpI)%kZ[A6&:L>!L `fBVf^ϳ*ЬS }4m/j&PIgdo#Pi5ߎ*mqkk+j{_duz6|"=H0>gIy)|^際7 c)毶U.i6,q1{sm!ɢ a+eʽƇtuƟ$ip 35^=1 }8l͈׸5~K+oELh,PJ+>_@߽dnTB|c$Uue5ƄOd2"|hXc!0^??nNSˍɺ}BW O#zmZnnx9fb D~oȬD&bfV3뒗/ekx<gp؏?j^5P9Đۛ$SRkϱrX\ -(u~)ź$xoZ Њa d7M*.T G?qţBa]ñ>ф'P8LbeMV(g̓Rbt!xi]7B#L{4Lc;Gq=vPNqz[ y~.NX ϏL Idhh$+\X, zF% 1,Gx0DTR-6LMa-Z-WA`\M!ǁSPcƣsءN7k3++Z] /c;y(D08X@T ń)B&8O!M22o߼'"~ Tt*e 5z=\G(g~{xU0U}]3eB6kcXD|dR?k(Lnf0@yF44uqdIeFuមb^T7)VLS~=m+G{@i6䁷%W =颤հ4(1pRZӶ[Ϟl-4Jk/fw9(҂?ڍ<TiW^0'yn8Oyb:qYuz\`][{[NjX;ke۷^4q3VL>{ݚ>S۵2xuyik+$4mפ|u]LSkNbNlg=(t6 YDH|P6UWH/@e!f77!8MÈ#+;+*)$/X.#j,fRş<@=)lCψh.3@# ?}M!&LvؠK5Eh\(PP3A ]txR3׌ .GS۪kR&RFɅ!_ ݐRAmL൚om(y(U[Zm[iTIR|aTG%eT!c&lC׈vqm# GXjd_U֜+fLFgL:M;#udž|Z<ߍHVmbbk87z`]^N** m/W1J8or`gYv%0N$~\84?{=8%C(kY5w,;==S4&&tkWOqy;A[EcUYE?gףr'LMwc-n:畽52CK8i sZ:5 7kvAgbQO*TLCQKӲ' uG ŤI'7ÌH]=$5*LJG8,)KPЏpdU!{X 4V?˛,zf_"Uw̾F{DMt<6nqdRw{-Nm܆8+X˭s9^ ٶC.gi1D8Jp8&:¡[>9gW|9 (ʰ`/ML r05VE07Ǥ, i$t0""ҵt$$[9+ǂ"S̩KV)6L#~W!>Ѥ\&E%V¯3K/o+B|LK48oT)3g?] D% 1w1Sǭ>}c Jkܟ)i7p]Nhn>258 ivI3߅h U[c @c3(G|#|B꫒E%xv>M|m.ROj=mTӽdgSyZDAxIAw@]/_7~$g#Qua*6^8YzS 9M>LzKy\ ta"WYܔSY\ ^"6*IOB5F EäZNƬ3訣uB9\KRG9H6{͊}4\aC[ o\ȗ|'=hKOQ6=pKvgG0 mqߎK]ų1Q޻uF_i+y[<]B,&~C&_{^flXsze 7 ꂞ甾,8.9C4h·t _I)l/>}@*|T5}h:c@R<2B\e:"Dn,UX1Aj&Wty8aq[i$y'ED#1x}s2)2?`#_)e8[m"ۀ ' AO1wض ($*uqıɍ듑͑:G<}e/p@=r\\|CQSt;dlv)F|OZV6E~/lvtfcVJThpSTlkLŎrm0 \u 6yL 0 OFy0ۃL;g݉ XosL$$%PxAA Σ*$^u L>.ENwz!}mPd̗7i}WMqtt L KS`vL7磇xɈGoMhDC#*ڭk&;Qܠw R|˃#Hf׍Gۼ{^F,3 m[Ǐlܷ&}(;( Ӛi9X-0NACb K: 4tߑL*؅=ALg:w2¯ O͝#Io-AΝ#Io-Aϝ#Iq-Aϝ#Iq-Aϝ#Iq p*œZy8%qr!akm4<9}!GV~q$`鹜Q06~ˆxooa o MO#`92yHc3ΣIy=I="'5yشcv τTUu8}r&(?po7sUe yC)601L+s@ `ƃ@uƊp^<nXa&Uw0aiH/C C} kqG$]ySf̀Ƣ=Bs=Fzj| g3G`e@ct%gYK=p.Q¡!by⹥M]7U󮄏] 8R6Ct.«hfݪ́Ҝ+o8N*Md X;RvƾX[1P1qyZGXYEG~"*eN<d8R;_AsXFu^ vv"B04T|Ovi^Ia]{GlY㗗xcbf|w;!ܝ 30Crݖ#4Rf2Wbk8cW~:W$KqDzR%.>k.e4{ qK;ɦl>^, p/,WtL6OwU"USiH} ()T{@:Όi(e_GR{3 S3Ayb [<@NgqJw{}}7(,FieQ^X'ܥ€ϣHtMM"(w=9] s:C_N;WeEz}s8CBf9Ş1-;Jt?,-V0]&QgU^iXw;U>7kab&(t]^4P \uُ?ܾ_Ʌ } q/B.&a|{2=(Ua_WgU,\2e2 M~@wgLWTox*.fRfE$^gzR4\l\#BD0<r_74pCuxt_{ZyF~5@W;Ta1PI@)X0]_a .Yĭ*v!TӘ(Y\}uv_Co#T("Vo+d%4bԓ6%9+zlK{cuQLqwx>-6͇@'JXp=f Z %_ kpGk VY\+&\ FéC]uI} qg4} GqډrTŀ2eum}UBT'սI;;z?ea y er^'RFJ,J%nfNqtϻ/3aF5ҬV jr4{Wd}4$tYzvOz`<ɤʤCԤºbY7a4- jנּ9ݠսIXohϟIci>Z:4XtI-t_{w`x(x [4=9 4Τ;|G3nb\9Giۇ\> ,~:0LMdUb11!ňT+>~.AUbH1m,Jp!2ۉ z$&DS8\-'{Toc@eUc/U"IaEGZV87}D l~z=r\\|M+j;<9rnR҅OZV6E~Bv3k3jxtZ tp4>~.g#v;uɎ((GC+ 98;M4 C+l;62|y/k>n^UoF/M,D%p/m5]'`¸\Iӷ dXglfY';$=1, h ؚ?Πm1S}1gfjdr{9;&т}x Kzik98Ϻx}Tpo wėI"Ƹ06Ai{+8ۘ( ºk>?h|enBu)#Zd6^'8;\׻'RVP+,5:2@֡j]0%'w%mY>O[L{z>'ϛ 3!єvюW>Kcr{<݅=/n3*PH˅ykD7]|\y8~a`r6*cl_ʁ<'K1Ih "z]EdAuE\dY[l>fyɔ-`veŏ§ yr|2)O#]uva)]oVCw'33p>u[X&>`Ŝ?x0T h0unsi#j *Cwl[<8t؀U4ϢqSa8~K/njj lt"\m dKCc nF"~2@ 7Zu/SRᒨ$ y3GjX- =IP=[Gg #91ȰC!.v1H TJ4Lndh fÚ\9#SOd[UJ Y; %3fs~',wW=51 @z`& 29aTlG[m5Eg4_Hp'9e1N)54TCƥR!Ķ_Ziq T'/QNuf>-id融%ǒ ꅧx7_I8-eY<2i&^ Bԉe(k_~?6/L=֛Z1CHKf=l@ oتgu3&0 F64lm{9z wM}KR`<x޷vJW lgcKi8RW9+[>7.n/w.k)-## fBݓ-c.d:$CXݓ̧0A+RIaፒ+EXʠ{:]/TutIpK.?MȘChz@PkscAޙ&d3wp:螉anhl%nޝlUwyWU)§`("oN[uJ}h$QvUYff,!E8 uD¥pznLtZ4 9AvB.fۺ}'ۛUo7xi5ת0"OWi "u3: æ uct݊^u@l 5C2wqp<0S<4*?pPz&C wR wzwv08LpAҷ !It٘j4=,P/ůt u#öO8%+ 2al.e*EnhE_ ]ΜAA4jq:ʉe4{ qK@-Mr-Lt /Q =U(u<Ҟ kOd#@Ջ(*TO$d$`C^BCW;CNF`!xF#'ODBI'=l:52Q8ei@'\f1,rzM3-Gö#S]d˺Poۀwf[K} p4x[9}#W\GcnvO;Vu@oEu7zÃmm'nI>@9 {M&@i:\VqPMwn)ut9mUgtM "QJqGa( S27 A@ ~6bAP>Ǔ( x#d]e#>k;kn$̲ׯ}H;"R:5EI)wGҌ]0wm- + _䒏 X2yI,'uV) rTAwE*I,N u)hPFS^ [ 9f' 2ĕ@o.!+LCM)O dxzġ'hLBUC5ֆPO8 | :什]rEL^x)Ѳ[3%ͧ*Z6c @zCn~=MO Ķl9ί6\|>?D/QL'ک\In@6%% i@Ǝhmߑt1|n0%WSr%:GoR@\@)hsl'ot7.I,\,2s\qAUo>O?N`)Agk>O~by+O~)B_╀UI|WĆ-ѝ 촑֛0>]3c[n/oio6zE*p.PqJ&%~iۦ 5 ;m w!/wY: qvta*SHsh ެ{yy Jfp)Ap, .XώK[X:Yt'0Vf+{'^TʈjqUlqA{QscSNs SBhOTBI1pbڀ %l*^@FGl]HfL;UbFJF{ٺ'J ޻^NaKmb#$dOB5",H(LY(Q"u|:{"'R>~bj+=Oq4)^IL槻}=5=&ovz괟)h7T7nݪOZa 8x]ʣ&alv$@9Ow;%\͸ Hh5! Ń*u{"+&軤zf#^]suV%`^uUsc㠞AT )$cK"{Ta&^g2o~ f c,a}xc+ŵ3]y4#{`PfM`]CLҭ _w}[ez;j=K4G6d.>PMo$G*\󠻤VA.Ht@}pAَkp"l rv!i.ۧ mr! Z遌.WZ TAtaªY#oɘ S8[+bu|8rU/~<1 qmn DqG'*JY'ɇ}i_CP>QXIZH:n_Zl T|kV0 oh6N_9]8.jçvVG[w=jz[))/Eu0!w/fJaT߯NU:ˈ$,z7o\[F"ipd?}fVTEPWtO88ktY1ؔ^>AzW;uZI^<_@To[fW駟OBTySIZl^a.^r> ~E2 ?wC3H$(=.8P/>IxO S>s'2'sO(}J|<)xH/`u[Yt%Rq'ׂ# 4Wʏ8nx=gax\ 2QQl-K\S4|)7:TTv!0=\;[?MV_̯ӀYjU1%#?RiY$ꏐ̨Ì! ?B(U<߲ʪn RADPd@aѱ0Mej7 bkv89dWG/fQFvTwJs,ďgrBdu$B3@C||w;3@iy4q VD K*֕ 㞅 R& !O"~xh(Єt fF{q;^]%fW.l6 59XUcHe},d66%v, FBjywSO~Tբ2,/L!}ր@\֨G'jIqLRڒg) ^FL @l!L=jfJ1 %Do4x2b]:&~fwq`l?m/O82D5;(zE(JPek蓮{>O zYs˱TGg*غbM1iʓ?Yxr: k [6tۈrrmXm5 *eղ,YV7uTunKqJO>QQht! ׻g4EHV]nTnO@:g|?#a~|~]<{cK@ifaM Mmo+ߕ_DUե'wU3yxqYӎ݋81Tu83W|qhJ6C"vn"@a tma>~&aQ! \K-6pK-vA~ky[KvJ*}](/;IXm_-#o'U:'^a/D~؋P^sU޲<G{knGD4Xr@AO噋*=~zMڵ+ (~ 쫣p1i5GU+S6#>o|hOj|`g8uy0F}n{p@j0;*<~׎}=Q%ڿ {_R;s&lh0vƉh9i%)[QT gDe>^/z[|̉pB+ܤ{v&E3=x2=S \"=C75L҈}'ehrxH3@EkJd0eq{rEVšaiuX`)}R :4 ¬(U݃h(je@^&D(ڮbHöL֣hogFc(E;c?#w ZRpYZl-enwW8KѭB:`KW9*Rr "etT(PaR*#2Na/Qȫg)C ߱;vS,cp,p ){/^{8 ٣<B_ HY!;)t&7U(vnF!xOGι%Km0|trMk@u+ 9a&餧Nȸ0^S\ȟ_#sQ˲+x;DUښՆo`z`hniz$33dj t0V2ޝ0:;T5ne.~ %G]_|v\@aAp/ka\4*76HSsmu\/QVTΫmgr_g}*c!lC|9nªB!}mp;V8xF-C~Yg`zmw[ߞwWi0za k6:ȭ>p,<6T5dd_ ̻4蟷=/MwJ\Mp)H(xm]HrykP=K{,rK[kʯ$i2nX(2&}ӄMx8JQ( 0"$3}ib6^s1bkr9m¶j+YA|ueOm18~@/ Lcqʤ LkS\o@?QAW,?Vl LƮ3뺪 j25B@躧xJ8}Ζ8cɊ>Y_҄X.Z P֘GYi!Mnyф Z~AʇkC%΢qf_ %ñq!hYLR|x ~ ɌC\!\6@(@ ;ټe2IP0<[q R2<wN $%`ʤut+bfj…[ }V {tP>SpZX6Q/řM '2N6HN ;ٰ-#{znjboT/,-<ǰ(^p*#'!Z"'C`: 얹~!ј2"ctJFmv:Ȟdn)>Ey,(C` E}wl_quރd [H'Lь51>/fU&£0&K>?oUMK [Tǝ IW :[2"@$ ǽ =W5$L,n \ aBߦ.2dQ44wboеch|Z#ȋ Eזۧ G\UʜoKtFA5"pw u]("e,>ycEGY^(U|3$vZ^/]޽KA>fgSw9zs8".ЖBu&% LqBGhUC>bqɣIB8/Rt,>LnZ,rORS-_wZ#u3-S Zq![`', sܛ4ٛP>G>nJ@|'?KQߕPh: GAvE*f#=].Jی1MW|WGL1\۳txN 2Bwl@\M;zVpNSЊRlA9<.e$gb=>/AE]8%ޚc]ըfف#`Ht׀[`uQ,`NYؚԀOU0ʋCcUpߞOŊtj@hPJ}zQV /N]&Q rZUhl X2*LoO(:'I@l9.W͝=T.*l(v:7ҘhY:< ӽ*H2_iY:,H8H5,o-,NQa߬ aWTyx6.fRXCٺ>Ζ[w_0Wx(-pq}^iDSH2)Fk'px} +I s,/fՕ\H4~HAsbYoѴU(E VfRauP EQ}6`<8r/gtdUOJ]ȹF+([lq@hZ*+Do1#υ{U㲦hOH [܏Y:<r`ր?Gֱ e1ao^clޘ9aJ:M/he㦳YqL}06q4FDA691dannn޴}υ{7^#v qj 'i0NaF0ժσX#̭5Jg~u֛g\mTʂTm ISӗ0=4Yt]ezğIh)hl#;eKPպSDRDhzR8ͣqqj9p>P@`ltxWY-*}\?}'WǬz>X/]N9bK-{e4<<r^ -M~9E|3c=(B@ݽ 4wF=T$<{Kf[.<<_3,υ>]r \3qm37|cG,98bm8h?`2FpZ"L&`{ N9>&2Ѹszf'[eDz!K"sX$\ zIdw" s uvb)̾S^™™ۜ0m*h[?x`bo_:mv^ROLSW%K}\ڝ$["Bٽ{ ]_B ]{%m ~++`&M_a.AɎC 1u[R,b̞miߴxkW ^^rP:y2T&Q}C4RhQYp#(\A{oa..j!)^PYn..,@qz!:,ҟȒz ܋# st؋TДYJL9]Yyl׈ENκ2YI4}%˦yY\L?&,oip\x}7 ό]¡H Bx $SrE/Y$%j!4}܈8X LΞcː3Q_y`<}\q=VоeZ>`XISl銤uZ9E̟uuHN%纘+S2n±tR6L͐ e 밧p#x )z6Ưf$ ҳb7AzYu xE53IIObxA17jiXMQ۞^9*n?:*BQCA)x!"ɽ-1Uųd\ kYAϲ@Rg4qBjҁTբz{shP<,QDϛXoP#*K} //X]Plډۑ1-LؾĘ=yϝ:4L\RKjiSd/Kbԉ}tsi}[/i\'@%#x.9˗>g)}^GG,fd>{Is9'rSB@Wу2_##V[ufcQv!?<p:U9\\dY(l\˒t [sܛ2GgX)'5PaeL§y0URܚژx [h~,͊a1p2zJIEXSCϳ/H7W?F5 (9w8]/Y *xvSg%?B5ک'_v/b򫤡O":ݱ!Չ$WƕNw]I mV?[Qv3vAG_N왤 uJ&-:Y2'jq L!*{mQDf\.8MJ^\ne#U7k<߽)Ud3olj䫸Z,Wz:%[Tک oARS>jIk~9ǵ1A)Nxslۊf# Tm2Ar,zev~*'* Bj2 V1vu!iTMޑIUs9R xc„$M^K>=Ȃl`+ aիx֋WuwCԕ\X 1Nj۳|j2Y>$'ڴݬⲼQvnΣq⃬GVW."㋘r+{y*$ I6+92YfYhU_"_)ѷߣmGm? Re 8%,y&jh1e$E|y.s@\s69xg;&uoj&m<<_ ygAqYo:@ҨAoaCes # 2iH7rȲoc脅ixX#l2jp?K%yJ?\6Z,X84ذ]M3Ԉ WիycQ#r vWHOH%3ur!IO7ֳ'#S)S9'tS n `kPM i igd8co&i3T5h=_i" =B 6jCV$jnהזX 9+&£Z[$EU%ͣ1A''E*u,x*;ap Zv5E74avo[ `T ;a "/ϝ)A8qW(|Z\1V~ '+^EsC!7JAZ4pc%,<.L/]ϮF,*.#a~Zod<(nnŏk!|28sׄ!`l6Go\JnQio?<G9iGUWў!;4gX+ mFyf1HXbhW|5A 4cL{h>_ 'to&I]#1TQcΣfHOsvሶSI}g$㞍D `htfNVF*:=`Bu{Pko:LBsl@Bod6hu7C@\crtfJ(ꄏJJ&Hūұ ^\_DiX keH_XU4~u}%/6U(kr۳qkv¢1Qr6ev:J`Ԝ?PY`Zc)qlIFGR!3b)շɠBBBV9gCqL"nKM.KҨ$Մa_  I2A!e4`v -AVbU|LDpkiԶ↚>O MR:f0k3C^3RFwA Pu~Y9Y1| Gw5Jg)CoXd.k}eG mR 4a 0.,WtKh*Ty;$ڮu}6Y{޺ \TqvU5PNwq*/<̰f*r%i%z4NuDҥH"(iӕqK˯_pW♒:Q!?z!m)š]WAZ#{a`?g^ "R<_;:FUI5(Sc?c!$GyI9;Ē-1j?_(+ br-UGZu$-DcvC~YIO^bCT aP:Wbr;h]0Ϣ [&ڦ +9Ix$"L@p:8G",K"C|Aj|W4m,0_.8k2-q:lQ=QIժ ARnJUԞG ;`t])Qj_C:bytFK?w1%TǗ{3G8IDӅNIj PP)pE7JW-Ϝp/Y[8Zy85qie8M @|bUܸ"%ʌ|%˞,#gzS1RCѝP 9s^h`ڱ*1FŤ@@;5E;VrZH+w*,8Tq{LDQ1 /Wt w$LF7|L M 6Dkz3I a|[ԩW!~+ Mc4EjPݸ]P I~G:1KbAGhP@ BMIZKh"s$ ):*lSc!kC¶R˺s.-(Dg-@;l@fjI,Ƅ;0ސuv7WM}j u@.a,bh:BR.13*Xg(J;q пa<gt $"dǀ{x !+U Eg8zVu6kw@aN DE֗+ |f(r6蚥! (^!bMnTX>zt'l w %q,Zz(LSd?.!.~eڅ/Ĭ/A.Jyꀼ 9x'\|C;7bPsmCMfgxo\|N)[.*|kCmzr뻣7o?}cHpQFb>[Y>- dExL1AsX#7D!+hBWڰpy-jgx~amtc`TH|eK)/%:wV!k~_&e[a޿YM9 |1ե7UG7\ʵת>2M-^[x>@o0{߇@ 'dC\{Ӓ=6 ,Y4  hs2QL*I i=8"8M^Ahdqz gˈ*ajK,c!xK "@Hy$% R,4p886<71\Gy`Z⓿nBƙpB9Ќ, R̖@ՂtR(KUm@VJບuj_Z)>8=h8?9'*ѭ}r 8a r Wu#52S;<Ѵ<6 x+IbC14@LE\#yKx*,8g03a8=r^{4':Ƴmץ^4}? uggZe7wJͱù\dxugbt"*?ק*Wf9FBq~xuÞ2q݋& 5_yF闲DG,x;hs3{؋sqo?sew4N&Kq@N/g#Qvcޟu(c@U~ߧN_wwle.aznqkr巛O>_MߦWww'/ί QbB&ORU•/]ӗ ߘְ( PE;sVI?}|9-=?ߟҡ=WKA @ Le/Czw> C׋_:yNLG6MUD9o0ouK|3zJǮ=K~ϙT-D=n%V/nM'nOIfi*+X>Q2==f4󙅞ޘ SX2.-G{%:CGt.l 17Cj8?$J)";Lω=Q ~M:|2^0%WۏDsh/"82,y4JސOŌxW0omEh8LQQ };yWBa1֥qT iek[+vB\l Nr8zw]oxQ .9SRk/T{Y+H17Qg$̹of9sUɀ_H^[Q+rrRe *_pSj4g2+բc&H+re{\ᬨ 7mM$Wa='hBuzάg+٧~έq:qJO|kFde)&L.U' R#uω33 &Kxp45vJ)>y s!_#rZu앛xKkSڱ2WJ^qIkl++,dnָ.KƱ]ok&9cW0)R̮=g5c|3T#b3CϮ:b~t{y#Aj?̸&C2%QGps[8a4{SKz kC  չ?"F$fK~C~ 'zz|ΕWn/zۯˬƅZ3J%3~09phW4ܙ# wVxhPX[DIk\\v$zŴg }x\,(Ω\ҹ!Iqf< foS&Oqo)Y5F-z}ZwRm*s8Xt%57Nvuf?+f8^']G09A]l+9tA|;uAngD Ʈo>.86%뢒};Iu}wN1ZoM/ ^2TކwۏA]1ڔYjc;YY͡?y Wr[:d݋Mѫw4yKf`m{􃣚K 퀗k 6s_om"p*ˆH>3Aw5(rzA^Ǘ('dHYDVN |D=D{2 "F@Cqq "zvg a =Aٳ / +cZcVCeG]sgV՞ImSx<ߺ#z$?' lHZnzYz[y쓌b)brK&ђ}Jz-2v,[rg:[3:[\v(#ekT8dԁLG_BD1PqL)@`Sb\g+n| ל"LFUy3O@F%b{=ISox*~|12}_럯txzV' H@A\JƍXs: ť\*qpt+"AJ8cJ.ٌ^yAΙrPܔ"Bi_/s igX@$\3BiE[ | bmOqi|h0< #K&59R2v2 |Umr}0d'f,& %)[<HGi;~ CNU+dJGt4aQȅh%sT :X99w ^; 54Y6 E#4h$K ZQdpacFsO#f GHRLo;peZ<5.!hQ|aWߚG,&x9;%JD0XDhZBiXfX4B!м0I1#pB! $)G[5}h͋2LAupHk`Ku}9% HD$IЈP&)INmœs/!֖sI7.pp 8]a h U<2aOᨐpUS*)l%*c!v5J620,xdfնfKW9sPoTb-'ʯ@btӖJ"i_ iqE #Nܒ#ֲn=>aw@qtGE^ˍ8B:߲`h>|gCsyfҍJ'Sh#/#6d'ZH:)9֨ ,%p}W8+X-|N58hDD 3xc-U,Z l0sMHX6r)6fh;_b9Πmڐ;5θ3踑c~@9U-rEӤ4eIT9SYSauRGAӈh{rz],-$O4cf07Q &~4^(AMJ*Nes.<Ҥ|<S֘eI`sTB ӗvchX J4 (D`ȉ>0Y8J,'9MbYZ\nM-T( |Kd`&zI6,|2J4a5cìzf"HW/׬vĨQhX 2TRQsǗZW\wB8`Keb= ";P1\xY"{ ?)T ~$X`]VZh.b!3%̄J8ZPi l9VX- SʘrV`yLbHu4;nzaQ:@ZSٖ8VA#)ie-v/݈drkionaMlMm ^F,7vPF2-XF>s`O7o׸K8p8.b)%.%  M4mlDH.a,•d)R=ZSLjWpssUnpۢb6+=g܇txn.X)iAwa42-LF`+^~D [NBfӁ#ҝ<@1s4jĢ"MHTջN`%'KjmCYDALsu9`*s [.}[Ƕ9!Zb Ӱ"wN̝]zHw6͕q큦ڿY!6΋7v|j?c\mi,!"Mr\ˁ%46(g)V$JG^}6r;р 8O9ܓ v3ƒ%z4^Fs~J̐s3;BL~쎘 ׋P*d@ @crިYTo AĝWI .eƉaMs7# b;\h% yIʡ<3t. nwHd3q.%"rHVEZр#4 춡C/UȪ4bB7l`6[jn$u4#Ìі(Z#Fs<8ŲdBb#PۼHxg ƠV2N.mge*7T<917By.FJq̛Cu .r}t ki<߯7U\̖WLkؕEXqذ],u:n>bAq : Z[8@ [L@V$4WqN @c:t%`x,içw*X0##S%+%k\43NbSv`t 碩cL76v|ZtD_Ň5NmMtLCrSXU)|tniza>*mݳٿW-xg,+ƹ\TJIyxTHjTՁJX®,(ď*dJ_'0BJkH:je|2k ^#'rNlJ76-`_4E r= d dn޿57$[_i;/}Ux%}de24U{^` $.Tc߿H$(Zf6Kr-Dz3B-%XLau*t 0~V7(|3z7/tJUt= 1r,W?_|X/|T]/yNT+?ESݽ[ACU%QN 6H,'(;l;p=$X!ju|ݣUf kw:GY"%|8 ="8A=َ#h.ɕƈutG: `'hJ4ߎAM#\ ;3+a9v<3:>:,CUx@VhęA~GO$^Nc{nVN𪰢q Odϗ%V &O&JXD~9[0@4P)S0?E!zA"pupn<L ʛJ7W 4!y0$˓ڄpz=j ̩H3j6 O€mAk+8u?<}wBufac'Du|.dr'..1PrT{A.҂0Qlą 0ܓE zŠ#ܖ<'ROMQKLbcNMqc3*L8$(_KP b]ǝI=w4ozC3vUq`sT3 :N}lhGhVJ}Ajv;MD4`za%`UP WԉYl€cq ґP07UAdVzͱ!ZL`%X{BEQ /@pP %,eTİWл'KDk9~B=ʟp v:O_yBW]P$"X 7VܵPU1ǁXoy")+\wj8u;|k(l#:b4 k >*v#y"tT{2%\NhvfaKxld 4v8LC(GNzPZL!EKg$:0$3QЅO@8dվDj49kʀyg;|!ib_2QYJ7X]s=Q?A^" P5L5BSih(< 3E Dnǿ _@Mކmuk$ӫPzPN+5p!F%:X.\|Qb N]kt N+<ZڨD 0lM!sr,rr,\4 PXxOnsJ]\sa0(@)$px0̱ (BvU& I$T(ӡГ?^`WFaJ*`{rCMZg)i2y@[0Iڏ|ʡϱУأ9`V5}T\JR\y:O@`n#lNrC}O㨓N4=82/&Rb6,Ek, '̉DR-`I$7Q dgpDIcxr8GCLB9q'UA0h0,h$AI)Ku``qn0RX~-)‚_MҪn!Y}w =ϹzT*Dmn 裦i$ꖩel)9[Ρ@ EM>cg c:Փ DXT͞fSrAvb`< @g.Ο6?2ЁY%|zl8B3TJ{%*&t6 d((ș #N oͅ9UYsTI}]{'zs(7?(!MG4* (FÝo4\ G~P`: Ma*ѠɵEJfcDTEdc *3갳I iv <@ˣࠟx-Т~f#䶗R5z)`C}\ m~e`i ykAr8|s\XQk4\ &O *秄V9$.pPЩaC"9FʒHLU7-ṯ`<,Wù>zj! }inˍ{HKaxu* izDqQ l+4cqJCT'8̱lhPj/K9w5=_L~kuO^QeиFKD]:-1PX$yףS!sQz|PA5B! Aa$X(5V OǂU^q" dMxnVz,zvaΜU,*%(6#%V{9"Q=BV(lAm{P#ԁE4"Re/ADa=IS P,r.ikDS*K.GL"UU&eَj؛7** ,]}wc/ .DikpM|{+w#U83JuK7u|s;]l?*hUЄM m7/Q +ba0P7/@P(kqm-QOaM!=S~1uLa1X2|`ԢcYzHmg,&|0wJ|CqehSWMZеU⳴&h5CurO3{bXIKdoMհpa70\`H.lb$sOV=L4\̳T*3%ֿ2hl61a]jRX9NQQ/`rBTËLiM$p#;ME JaIw 6njeWUcj!$*Q 8j2Sպ;n 9H'TKRL=ۀ;V^Wp0۟B/0n[C *nl +ʼnyB0L7B^ 5*|&3֢) פhY` p%ˍyUNă=}fybm$}G0Ӫ&o>h@&pe0pY9j `r-`O X@ xPSD8&'NN+s'ˑ.U*{G"O+F^&V=B"ÍS& d8?ANb?ŵ%X p80؜̈́NS~\{鳊=d6tw+va Չx.KIAďd:@Bс7{!`s,TRRDaw ւXbxieFKLNq I 66F/*TW, ,N3&0 )r䓁.^HH1` 2`MMH5ZګI8*)Ν.T/z'a;BiH5rd%`q6RRHݿ1vVhN&o@G pX!-_4qZl4BP"V!ľ7RX!#,"Bdh<_ ֠^BႦ9B β Q]ojڄ+8?|c\PG 'Q^ T@ݖv,vcMi{[TIS {\ǰ7`"Xж cg>e>Hš]e*beDhipH-I&q渢ZCGTjĂ p~O&_RaY+hȆDkM :A!`MpdG ABݭ$EN' ,pXXq lKc¬`;d!I#'B(Ŏv<[aޤ.e?X+9VLC~R[}N9 !P4vQwqKhPDI79L&1N&ȭ%GG'wءm[GRE"\hg]5h/Bssc)OQ痆Ƃ٠4D5P.Wp ]b4)~]f :esTd 2' Ú ME I`(?:hڤ:ND\mTGW܁t  w,!UV%b9 xG_ Í;΀[U"0 ctRw U}G~nǖ† ].ꄗCJfCmrHk\&R敗B P~~[t߂! :2s#kMHc_83\VV=!Eئ0 ?.9, d׺tLF%~LKesbI{G~&?u./b..PQhbx981ؗy3Dxh= V*N@Oce3cZK#hR9ZLdžT%X3 9&>'>9 q&6;FL#uTup'4=uTB9(@AwB_N$K<k(-QVM 75o%()j$nn+ǿxD ASPUNvFp00X4P`A 0M^fQL$[8ilW&.t W-g*g <i4},`2UGSPX9]>J=:ҿaۨĎw ~do|  TPAR xlRqpWzmhGQH Җa k}[NBTE'̆ 4B!Ut-G>#H"{- Z.va̺ONhSz <1O<ٳ5r= ֚FY$l=F#'a`^l=^k9Ӕ _>o6|^MOy&cĦ$6->V`f6MIXd tMid2 Ĕf6'"YW tuiWo̡ٱHWd98, #G=\ÒI.Ǡ( NS%8K'֬ol "Kbцdc)YΠ&9 wӉ˲~Bbg|B'2ޙ> حڒPB2}~??[ G_>'H'.ӽBM-@]NkD5Í5r|;I  6ěcc"+8؈ "r[DMQx@$\I(T l|Oj|Fy5 5B"0 #Cl!j|aj諐PPE*E3v}ܦ[>nǏt j$l|q4 6Bb,l$j %. e#@2 c$ 6[@ 0N 4 .FB͕rpH@p %S:j(n;n …p'4pw@C' z{zO!'PףЭ|Q2,h 9@hp4GE5hf)vKc!N%T$`u"NniФphJQh(jsHO8$`CEl|0dLD/tQaG( a;FM9h(5h( 4D1 4D7P0*  c|C0@7 chgPi,[Ce|u`X٠ǰvs,7`IG 7N(.7LTX(3Cp RH.`8\\,.sa v-rL ?QH@(d̪Xagز^ă )'wWpxFƾ88 (/XCƩpC\, t_Y TF _^#iH1&[ 4D 00Q>FC:L(i0+2 j#мب^D6(-XfWψ+Uw].\e X+Uuኺ5].\EW 3M)ZRBƨ@C|QgT0m6yFe< 3n>W8taY,la/Ϻot&I /3 ; (Ъc{ @8?f*8-9vꅘž823ȅXE p8A)*=% ЉoM# ưa$A+"Fʴ,v K'YdazA$,tSo!$1$pT̅=Tqg’ +yM$Ur7M*X5iT鉂wf͋f&S&aZ% k#[$&&U“Y,@AOGEE1KRLoS1D^e!I ꠶zt*bietWz U4+'I"xd]lqUnSmŅ2M^)k,\!}#ΐ7K"ŃNrx<|Z3i{Sqhx 8g ͺo ](0j5p<VMbhʋXERr! g3R/d󲆴@ND U?=ʛX8Kx8V s@;%bq@ v]ʓãgpqۄDW)(LrVd+7./n\ /)3ƒ/M1,$(X?s OWل7@Ϣ‹iEܙhʛ$$|ys#4q-ymk%͂EИXXl2_pDɜ#GĞ$ҎYJ ,Kp8zH_S=sB˵SN %t"GpL7}ia,WK/RihP~ҽFg ڼycPn~ޫc{QB1J$E*:TAU.DB/,UE(.1Z12E;|/{_ltUcbZbPHDZEo;R-Km3&$j?m'L:&qy 2KMU"Jg\y2>&JO j, Ym6iŠ-IB>Q"1)z*2Q\7cEܚ*ZܙĄϔID0op҆ mƢqT.$Yy,1-dш{]F ~'S6zU<*3W8DJ,ەz (yX:$*"fH'PDE^j-epi-xG^'jHo%qXzXc'Nl:M\|JWho`&vg,܏k9eDYS'U⠫d +83 F9C+.U'5,/KH/H'yXS 9mm1H4Yʟ%>Db.uv(WXN!f]/.pRaPdj 6+Ud-FO!QuAplg&S^< vzhssTVF:7fv&3z떈5rmKUz.8l\#SSoK@LԓSV8ʷ.Nd^aJ^虃@YI]&Hc$-ǃׇ8߀sh*![F_u`s P-Td0+q"rEjLx_S?Biqѽcz.NNxXLw#SLMP"\}}L­CΣR/BV4rB.~Do:C](qjrJ.orI+j1 ىt83Ŭ$XlEW#,dY6 [f'BQ"ImL"hzSqz![xGF Bt7s=͸)!I8>/JIhNZEa8<~Ћ|J}3EtW3dEFL\a@Lq0^0#; %BFC$pbF}s#m?Y~ZFvYni,DIrV) \SJe\kwfY,~IH)2,n +P&*82E?]7^9(:n#1=Z{@ṓ‚eN WOz.96Idty}Ǘ4`̝p(K=IiDs ܮGIJxc.ĞΫƊt+Ȑ7nj c#I3^VbrP^C%Jʫ;!iͻa6mZ׿堺I,u9FXR) 4˶3UaM_SvZ;4ӱ^UICr1#Ѩv<SjD!CGu Is ͺ/AOl'h_, 񿔳9Ɩ;,pfJFԫaXHL-I)"}O=ROY7O!A淨!)`C59,ˢLp,,=r5d5Sи]4r](Sw!h+ީp42-c'?nslכP"(R $ԛ+~>]m<y"B)q؁+WTe(ΐ)eZ@d@H(0װӽ\4– ӌ3Tp)=l!ܣ{tt'{-I-UR!7?pERA"8C3=elNRht;3uz2r v/4T~_RLf2K@Q$Gx$aULa(i7Օ?@θճBpED_cg]> KC}Ƿ]07h58ĸ,NSyhۨť\#^ 0'k:cX\.jlߎ]SRgT?nB XIIy5&/ᡇ1Fc.g/0 (Oߺp,'Nw.,yzc3rIb?ǻϷVMɇ9c%,;gssZH F:Yf6#VJ$79یYf$d @Y浒<ܹʿ^MR!Oo{H[AJގe=΍Va%pOמ tcs<{y\5]:s ;y_a4Ȭ KJ BWXʯax7ϒi %cyzȏFYbB 0~+q"bS]1Φҥǩӵ> Tmr%EYep~Nٱ—4MzRYuDRzJI.5i¹"TԻtAA3UfpnX&1\kkUou^h%ρcU=uFizXY_??AYGsMpq* ԋwOF(Sv*]%B<Зk݆4b=_"up'o<+ס<ᝆ@7<=d$Ry)wݵupqx""uON<wtڐd-ɢ=R*aYv=Ht^O?z|; JHԪP%QAHU"TJWcRϽ@U~oAۏsIņK6iUYU{0:"7ϳn^TsCvvgk}x{F5yMg皜5Ӷw;kM_xQfh/>vЛEtC~{%3XkE=\$#f7WhiȱTsaxYo*RO' zU•3RjF=kti3'W񃖦+z͊9V;C_ʩu-D[-4LHZT%^k_/Y Bt݉:{Z (h/ȓTcmS~v ="X*YG۳5XHڳ꡼h| ۓ)}zGRQrrqw#j` $v*E⍮gWҚ'SuHC' ϝs/eb9u{ 9m սX %UNEjE3.Wo%"˕VZ&O/iΊX&:{ C$P ֱ=eUUaꑭbz\/IuME_mDN.HZJ`4ċҀ ڕ 74,3a'x]9y+b'Ϸ]fx&'bAru!XRW%КF})Љ 1 }3f`MٷE+DcA*A"y 0zޙ^i}NmC!DKiMo +'6=q #MVas^ L:*fṬt; Nc$J`& fiK\AU]q>Q5!*vRqf ().ڧL z+a]b%CRIqQYRˡ(Z9:gZX7; &$w㒬7(*RB'³NOuGBHW "a^C$ˆt@&勃{cPtg#N$m`nd>j=N<\mWzn1wZ#Zk]-/YzdnB"#Og'4K>ʹčg9RQ[hUiQvF\g&9;NV<5,RՌH'l41F*m?O6HZ-(mA{rv=4Vk6Ybnb%P%m_iV(6V@sheۂFۂR+V>iYt,:mx6E"4"6VƈW}~ce}2A2V ƌZl+0V&7?Dӵԣ ^6g #Ar+TzTǴœ#)YQwzՏڥ?Jn[=yuYO 'eKru4iis(.C.E۟@?ܢH1$AhrVTJ*/`tV `rVhB/#[%\ pp]ay=`9k?Y2[UzrTf$<9P3Ҟ(qFz۟wC? ADSuT!kFpXVKtn)NJ({\zXw=(P𑯝 WD )B;:Yf)"ٸL=듵\X^://^˙SrN皍JsJp$r*9DEcKmLo ʛ[|+s$OV`*̕ql\R?05 * Grbn'ÔIy)(?۝ v,!6ڰ [04_t=WUexW$sK%80•՝qT|#7Y̼I:#(<@kV~jU\x\B2f .m\_~ҀQ Pf)LV ki>+ '(w0(wM.rËrzQ. mI6}ɩڇ^=q7U3 ȴi4DUuQ"vkMi`ru0ӕOx%nL~2$777\,C.2Or2ć 5Vy_X=Y^Gœ'N*}P]}w?J0Q^Nʿ< Fc 9Ai?!C`-'6:b^^G}B;zOhS# u>}OBӍ6ƩAT q*qІ88haJ0N1Zo'% M=DdH2SO$g'ԃIfꩉ$3Dz^"L=,d>Ayr~2qP'L' m'}BAyb~q(+·YV*YB$*k|sF7ֽwB^鍀gYji.黓%^Ko4PE\W.sEu+gwGhqBKvF;T$@юI h!|4W$GRA;ݡo:rs<-Q?z'dxB{'dxBv{'dxB{T'bunob:{ M%j*,V{8ba^,E{_K`[EYʋP]u}-3A{:cM~b Ǜ۾ϗ,7Ԣ4RUO)QWl7y2p1+\s/‹K+\o] \#dNqa-cgF ^Tw E%"vQԌ/IhvϷa?9ݨLaC*,YϱU΅xrDzaFONB+"›z4mz!va؊j]Ʈ4j0/x>*1o8&T 5:ҋ Sn5bovifIq68NG Nj%3?:bِ!<,=\f\pc<ݐӖm¢(kZd=ֽ2`Ny0&ė3C+A+>GBN$'KSg6md=2+1v4c^yzcs%ڷZ-В@}XYzDw& \]G7g,IBwBwIBg{ n,X Ƃ n,8BO&y2X~;vp-`I|{I!sἕя,1g+fxG=.to,kd{PC/AQ]97,˖e]{2";Ξ^%{"Ƥ ][=}^D҂C$D`"bV^[AһvjA& JD2,$H䟰>![U`%r+"rSKd4Yv'f*425/ dC]qn {Z^ݨ7MJkf,hx/Rc1#t|UiSzr_NV0B?H->B􁴭 W8+O, Գ}o[cHGЁ$40+Zß5ϥ1-iT-Oy>[P^{Ilިm0jKnÊpRBJ0;KR{K !mrA;㳭BfYG7.vqs!o/3ooQ2%4eqti:X}N\Ɠ8՗۰˲onȱ܎ݘ?vls=x؍<<>en5`Mnv,Nx%3kl;f&*79< NriV׬mLeW"i!["apՒg&D5n;vے]`׻-n+v۞]]b 랺]j׻-uJK|uNJ͸<(d{OfG$< u'Ux7\u.Ca[@W9-aTS5opx?nyw(Ƙ\cL7cL11ӓ1g&nvyxCD7/[k&Ld2/g(p?y̗(LnUXw4Rth>u^bS*|J, ia, .xSȜG؉Y01aZ . Jjc脍*R@V6> 礙i5vQb^;(;84># uF=y{B;渄HXx+v%X T7% 'a-sؔā}Æ; /'~[S*T,\^*nqX>N<.ݭN^:[1kuo)Dc34a7C37CdHj  V!%PR!g+!~~%89Pi#P#}d *>LPQ(T|@C TJT|@ PBݗ;kz}:W}#~o:nKd3Q"w>>s0#KBȢEPQ$xLp;Cy"!=AT>4JxG$&H<z!1CbنLm) `^+N & $u^4H|@;Sd੕3hDgN|eC\q2uK}.8SSiQvͭAa~9gˤ,ej8Ϙ{Z[<~ Mu/vgGAǽm !nO=ҩs_ЦCх }Gחb䏑rp V[ U[ '㪢 NAhm(;d7$pswRnl )C vNJ W{㙉M0 0CYVYٳUQ6;š ֬w-ԙBt,9IHZ.Zu֪˲V]ҭ՞dkեZ+Fr@e3֪kZu X+JGB)Htc3&}MIKZfҀ8m ̈́ r_`ҷtI;dfs]X#KybyAUv5" u,ۥd!&~hJ'ZwejǶkϑ8m}7f{a%g}taZ6K4,N>^ꁲLc;Yp!b:K{Ƣ,p,Il,eDTe-y-iOnj9 |qЇ5=&G=rJ $g@ra sZؙZ"t@N]\:x{< pHȷp(˃;yTб}a@;B)SXE?kc*MLv4fkewH:h:ڪkcdtL٪N27FlUǔ꘲U#jq~բUj_0/LUVk~۪)jaʯZW-ZU #;”_hկZWm#ʌ_0W-~Uhb1B-/7htߓD0]| mR逹aXCz>d;zsQަw{ _DW Pv]z,] 6'l6 l??kˆYg/3k,؟ٟ6]7gSw`jad`ls,a̪b!umkReT?zK,^|eϚL<_9 .O_c吢 0NDH{8FUpTd*ҀYeifݦRLw&wɯںb}%]H~9wOn)1oYKt UOē8v5|nQqwH~ IiL(˜",)-CcBhAm/`g6ih  }W٠}2 lpJV8U6hx_L*gZ^ 3c(Laq*!7MvDDO*?'9Q!JʝT,R]pΦ|ᣈ'~ @Rm!̭uxW[m3'6󢕓em,+idY)I['*a,-iL'J>YV r<,+e2u"7wdodY%dٖAY,[8Y%ɜ,+;^OdY%dJ'˶$0zɲJ3'J:fṊ6d߿΍ƫw +(l?O<(NG7%)}},*yz5]4LUy[ -.^`7OG=ZݿZ8aG.YT3W 篗ܹ>{vۻ~ԵnujiGi㞖8ę8NKę8itZ<.No*R!忸쪚HPNU-QH]EZO*4c;]KVOA?lgYܤhTCnB\I{ho*KВ{renZy I8o+͍?=h- ܚzmZ!BzIYq1-MG1Bei"ߵ-y.mx=jb)k-uK>f<@jbkOQ?×,xyrgɌlȮ >G(`EiT2j,b/r +C}C^@5hn[oۻߊt ҌOHd'$BOHmYZ "RK& +"4 ̭)@{ކo&|b6D'fH++++++-$31 31 31 31 3%gA-y<,tznp~,L2XmyPC5҇`H@iNL?HI(ͩ}l+i:=4r/P+JfVhmr3>iw33n?l4iڳ63~Jqt;P[;:JP|Ez-_􃻁Lmڷ|MS4Vf2u{ ih3;@" Hot3;@kҜ~N"P4iڳ63'IH5rSksq8Zbȼm`ђ5Z3hMv)6!ڡ5X;4}Űg*ms1g.D4&2 *0 S*0 J\ҩ{N,Wa<nySB+PeVҪu"6IۉP$}Y/g'KdҎC&-I[>dҖC&I{>dҞC&-I>dҪ!>db܇LZ!|Ȥ 2iÇLZ!\H/QsyF̾2H~WGț]D"K!o_t y/Y~%Ҙ\Agri#tiC]?lsU.#zcؼ7nmzV|q;޸_o܎7n[&}I_olƆ}i_olcszN ӆ9mzN+ӎ9zNKӒ9&}=ǤþcsLzi_1}=׼|= _msV|=_msܖ|=%_msMzI_5빆}=װ\Ӿk}=a}=т'Dhz_Ov|=ђ'ZDk0 0 þ0 Ӿ0 Ӿļ71Mz|Iޤ _o҆7iכM&z|IKޤ5_obכ&F}a_obכ&}i_ofכf}Y ެ _oֆ7kכfzv|YKެ%_o֚73Lz3̰73Lz3Ӿ̴Rgּ8Jþދy3k{3q}W; _ﵶμ9n{3o[hLc6Uo̤m3Ϩ]3РM3y_y_y_[ ޷6|omz}k֎_[K޷|ozLzLzߌz z zLzLzLzy_7}=_o6|=_ov|=%_o[|oza_7}=ߴ}y_onכmz6|y+޼_oގ7oכ[zsܤ77 zsþܴ77Mz/=KҚ%ҰӺ5.q}WokO _էsy܊w4f^S>3Jh$.05}Լmzi^چzi;^ڎ-zik^jKMzQ_/5륆}ԴRӾ¼0-z|Eޢ _oцh[-z|EKޢ5_oa[F}a_oa[}i_ɼd{2============LzOF}'þޓa_ɴd{2=z}|6|6|6|V|v|v|v||||g޳I_٨l{6=Mzt_/|0~6JvD]CD/X:K룗Vۉax7Lp% ;ޏх AƫXȯ#drw af?Amuw~g~h푹+\G֖Q} ˽B}=g[GÎ3cKNseDp2t0F^,K$ VSK(L?{X|v*tx2NwΨgkS(=B9gh(cieL$S ?oO(3/g S`EТEM5$xjs%4Lmt.LԺ9"G}u~ws^%Y{h{~",#y:rQwmaIkrmm{7,\rL -7*%nNH+qw[{noq}[l/N2'UZD梋r)᥊dt7RJ~Ž,0VKVU4)0]7]8e F0]us.'bwbtZN* G+EXE&B[*aJ&]l֙.V˰..V`2.om즢-~sS*n#E/nlxi}U.tJ|*ϕg,Ukؑ{Mž3Rå0 sʝ3+ɉXTN- k*'59ſ*>g()jOKsP'&Pg{bDwD_TxREk~yN#+#?ұG]QmPSW ɱvf\k'T@592_ĸk_î^ArlmOK =jY+)gm$gm.Ğ?\HPoe $c} &c_fZԋIXӋ1X"Q8{QAӋ]2^T0ɐ^PE9ً &Cz7T5Pou]hy4+:P05 "qC bTUw&u`t`tTtTL͕?^0-U珗KeHj/9'))!)IW~v&Zm&mpf`Yӝc;3u迶>M.0%T]cT$2'$KhQ%TraN%iQJ*S*IK =ײi6Avh;K'vx8 qeY 4R50OtfݨJ.TsZݬ˘Vj.cZIѮR7o>/q^J#i^>Z15Z15Z15 fa, ۚa[0lkm¼Y5 öf5זUb,\{BH% /r$}/UNj1j˳/U[vѺ] ֖X@hNm–´]TBjKT2n@'BmNP(sgڂPݹRv DjP[Bm OO(qT{t$杠;A;A vzBqΡBPΡB4:'(RNP9AKxzBG-9A AG65`ef'` vtq*\RYR/Ebf'+0WYPu4p+k݈^Mvb5T+I}arzDDlrݹd( D Z!+Dj}?$gfS;&_f/&äXŝzs bƕք}Ɲx@*Z05旱zO?ܐ#vzSx3]=Z'۩4ΤQp./o ʳU懆I %mkiy{ Y7i{ Y#쥱SvEj{~kYQp8rkM߿hHzϑr&SkQD5!Lz 6Uڹ@%_eNz[:&do)mK'TvnOebNe.EajY j,G)O_g(7~׮cûSonŽu1J<=GWxq1e X]<;8 N7yNR1Pa9ɍ&̽`UA=&k6pœP}@8oQ"m)|?tTAl(*qtM%C<玴Bނi?36/{)* ⫆qDKvTNVQ}u9nmoߧBT $45)ȗd+1}])G!)!]!9)S&LC0N#*q\9K'nHq|s!MUjǕ? }lyO<-_!.8^(xJ]3%R׀*u s]'Iѕ'qj@\$3;\" Ftx'QHz+FS T3#Hgcz8erj_򙺆|It)_$瀳b@QLnaxqn_38+0IG^;tŹCZ/ÍJdsKD%+*ۤ$VeVNXʬ2Gl.Uti5,B5*pMa( l>zlc',5<ۭ9_ [&~hOۦ %DzNȚc߲Đz'k kn2u<ҙlW.cyH_<e!c1A+݇5 + rDa"J$_I=;5XLNV G 뉀kz0au A%^Izlr _N08 O:2d7,k ҃{a ^@^spBGE JIzR!%}qUL)E4IDŽL]SL wZpiU2 %g*ɵD6|͢K'2YTkc܌зhfsir8-d4YaOlyIwY;;{P>0OeRz'Yt m5+kVNGlenU\ALensZ ;$`(Kv䘓ɜ8@6'S1'߷9+UNPf0nN >杔杨'4 :R+ G3ŧ4d->!k)$ҜJTŧRJŧPp4d->2RKe`: C ]#ଜI ttcYS=J&>{^{k(TΔlN%|r/S{&WB<9"Ro% _׺ yiTDĹU=LzJ3_zB.8q5^\bw,BWt|a륉D]xB 6ɛZyK\s&mϙJ$@/hqHv8a~R@=šMEZv{朋y?[ax+W N~YJx v(UB?5&pDL,OpRE4$ߓfm{v*><>coYN< kh=޺ǻߜv@7zp<䙴-RbRbaͤELyNR19}Sitr#_8w{za GQ7!V執&[:S]- Vt0常*pVqNP+oVS)5K* hG׉τ/Im&꽁,jnӯ,EZ["9&[aE>s+YWowz;$rmݏ a‰\\?_?myn/hqkrsܥENLΦufYEG,J@$é"ØKT+] l خKehխ~2j vù^SV8TzL9vUE7+/~LpwHo5Q, 歵jIu+w[reK'=,wl5ہ#IռwM-S'm]4#47i'I>Sx%x.OF$Ҿ#WPU)t9rWk_:n|"ƫϔƂ.'~ڟB'r2Hd$2$]ME{ҏNx%wo.pxU(L^jB"lrDznu.Vb8yk//S<-0I}xFyȳ(?f{>ַVڊ Ve}jX~ Q҆LKX?˼ %P+FW]qVh͎ᭈxV޾xvJvdcO-Iys~KR9ߖǟtOnKqZѥu}2SG0k]D߁摍TuH^ ɉS2Ep +Zo݋ԦR\+Y({Njߎz jv߶R{"5L:Yy@oWN8|$EHuhrQIΕ8ɹ\MNrjPqP|blp !T<,THqR]LY {^ZTYi{Yˡ !*f]'s*p̏p_x[+|M]۟{,-c8Gq"rd"; vX% a=^Z-SuH9kEyu3Z0Nq6a$u`$u0!%9B(.I}x.I}Y.ɑP]^WцΠ!j@ܹ,{^xƎp,XxOˠXPū968N1}$eql?t|;IRF#inh@$mzA*bscUM'*Y56ʚxUI|)vmU *b>fdKR -i s2ɵOV׹s:UrUv7hlI:h]OkNV:Ea#K^{(53@ t>tM)`>1@ 0 0 0 0 0 0 0 0*#yT6Vo"8Bb,bh~U.>xd-jed")Gb(=a+[ da}n=E=E=ʊ mCm<I .2U b#)vdĽr"/g^Yi뒹ς9lmf{>VQ3KiW(ay}my,GRMXí켴{oQ%Y/撒5wM+(}DD-xF4ѐP:92͙:o!ui$ >7e07j]}}X]uTC7L{puiyO`Ae1m[bcծL>J@דtsk|Cӯ^ia\ѽopٌD'J/pYPMZ]n9vWM-?!(Q8G™#:! s"&؇K((c~XE_\:*q4y)'u=`},)͉,~HіSܬ e7M!+nBV4i YQr)dEMSȊz6M!+mBV4i YQjҦ)dEMSȊ:e6 !G;zHƃ:풻KSKy`Rnӻzzp5F띆wMUy MCH޹lj]@wqH띦+;j\GaOeoƘgƘƘƘǠƘƘƘ'ƘGƘgƘƘƘǡƘƘƘ'U`BViY !dU#U}`BViY!dUU=`BViY!dUU_BViY!dU󗆐U_AV~iY)f՝HSt.@bk}_/}Aо/`px^Pt yKK^0z|`ߗ1X^W (^x վ/W4 ܂H\k} ~ `qdߗ}2Tblp4`8 /1}5} ؾ/fURG}iѴ /c|}@Dˠ& C%ܹ9Ks#^KV `36}_fDhbm'}_X2Z}_/Z}_tMB5Ҝ/gҗ4GqV }_: ^}l>/ Y u@YRߗž/_E::X/ut@2 wt]0!,tt耈5i@m4u@5͹A?& dhu0np2uÒ<pk5v@5HڨCs:;4xCcvh>UuZ;@^hrk>`Ov@ )l@qRsKfܡrz4w;4P@L`!;4/#;4 ;{f0i0)M\;4^l0|tbެ C>(8 JM9C8pPNE=ILx9/ qNֻs%X/gW%tUv*{H=ʾQC&yL1ԒOWSs`ʭ)9x)(90֔;d' B pff։oW "tehYϋѲp^ybj ̴25123&)CiafZ֙C 7XɃk1 ra:ÅUԌeN"r%^%^P%4xoOI["I*9aD iq,x*jTl);foA'[L@U:;rޭ,V8 Hdq,tY^)ET8"?&p %K "ٷG(29S&e mwO]xPmؠy{}^0H 6M+йC8r#Z;< ӑoxcd?p_)@yGKSDby1~]"˒dZS{PIyPpeU#~<3]AW2HeitRisĆ .|YN 2Mh=~d (V?Or lq ē0{tn*w̓ZbkF]%DK3!pf.sqG]#4qzf'C:=o9A],Ɯ_6&Brӝ5'1j7W +I$轰-d!o;H/,\o8[{". G>YVO%t+<s;ͣd*Bg*;`J{1Mӯ_3kpо& NS<9N26ETf Xz4l&9"_)M0Ǿs楄hJ)++ ljR&^]& %30*KO`K}PMc?[^sҗO„OA(O^g:}l;CG$nDAb"bwXȥ(,O5Es#vRcq˂H9(Bh MȓH˽"vΆM>z0'gĝJdņKf ^6k]t2|D&ɓ$\-| 7|l4S nF4!)@/" o}^{xJG4M:wx ,yUri+` ީ>/HĞ{Oi4fp.7wxӪԵ6Q^e<R| v7kwaH4jJ=ᚡ/@Q&g1Ī8C%p]}W$Ĺ,ñ1SMSF"<gN"VQa pߺ#>4U,u-ltz.wLv:QY ɲ"`rd%r9ȿ& "@^$4 ۼ ^[͉f1<3R׷L wKB\4K]# |/|<;QAæ+|BtTLJkx Tnk> د T/M|uKFV7in_"uZ9i_-ksuW&@ߖtZAAءkf&.wεgp mѝN?Mik^67lۆאq>d6)@(Z8^_~w(hxx.hDǖ"D_t sX:H[ݜj#`)Հ4zKv|A+&rs)3D_g] n}L‘OꛡO  =2&:#$}WOE5jHk47$G$~ 4m\2"A6H9>J\NQ68#YH+ɜ4.p)//K){ڀ5ŞHa7*]q~3)*{RU ꊃ0-?m՘AB"c^͑Ӂm]Sw)Acؔ=lVe\%b]<' 9sx@8؎޺an}Ҝߩn |u]a Q⫬}peom*; <X: XPfP)ޛ w|E+`hPE_+v@_v )v%Az*x 6ooޜq8t*_BLIB>_̓DD5N ]1RQar:vh2Ğ6{ "Ҝy>k]ڝ}VgG8w %m r e[r*%*(]v,!0ϧپCJü`%(Ĵ6P+$}u?*g^= tf+2>ezԷe#J;BjglCN3:G?8\b "<~od\B`0{X#5hAV~>ZbᜃLR>(VTwA:)ՍǹiNds8B?WSCx[Q^m.Pfo &j=iO ,7]3,7ý@E;'e*4uUE oBU9 SH՛E M/bATF=AdtټDS#b+Jhbٝ :^")qӦqCphoIH͇Is՜z@oE"}7mD?Ho~LH]?٪ҨZWrXlg3Ca o0%#VY~'2(|u6KgR4-N-C(ikE$UsĖ` 2@Bphɛi%7yh&ݚ桇З$Ga&#c]^Q.BW#/÷з_kq8WO|iS:MK\Eoq:UyqZ@i 3ќv =gv`x6w:+^ pOku<_5?!P`P-#su'ez6 R1[8#ooEՋfS+벎 #* ~&UnH[[й!z&\KD})^%AtS,$ĸUCOo| pԈ<O-GT\؈rˡK*vI2¯7\$$/^x9JP%`@W>7xm|*8Ajơk?SE3N wVtMvn0'/NL}p i8>M_(:s^e;ہ#w,x4s/tޏ99tSr3RĐ;w̑96儒cO)@8$d,qAfʝ ebOl 6 _j%p%X»_mξE94qR.)0q<-Ugo{_R[ns46Pϊ剻㗚?dHOvSG+`dt*|e`<7(ST̙V]<{Zbsm 8Q315ģKu#qދq6}&&s8?xy 0x:rN{pRK煋l_!j>"qq V-RU"yD4ĤY\;$wLFۂ yҏfTù?OE݄jISeS*J1Xxngﴤӎ$]Y64p&TtJ`UEaPžoׂ9v=,Nr/G5|>fP;<ћϽpmy tBʋ\$gHoe!lۻ}ۛ Z70F,Jni6'6VnN%u1+R Z8hʗˑ9OcSF&~>RHh҇TȬR=B/YД'y \£*u ݪZG/L6jU9l{-@ ( ]E%m@渝a2yn*EËۊ.'tƦ~M.$TJoaAovD'}JTV—硥1tWyS2Dn4iytguZA#М&'KtFEO/1-98)1RaO'ҒNoA1Nj! a.WxFn*dծ`ΪE"o/^~ E/SQ?j-^, y"@Zal/!(d.rqFNa;yKG0Oˏy8e{l31vfXhV{|4Ȱ;3|%Ͽ⧑(z(Utn-*SGHOJ<+̰zI.ORB{C֊@Aj=GeG "e,` ʨTAd>7̢⹏0Mp̄$Fl'%&GǙ#Tk`ݟQFNiNq/B'd~gF^?cE?vd)=lY g|/՗r]to3z٘C]NHA|q`>9{I?u.%j=&`?ׇit$rp4enXq" _ ѪDF /ufhtݳoh!kʤK"X2ISYOZ 3yͣB„JCds]G^ХiLIR4"hTo;ݎeb1UPhT~4ſG=IR VN-r,9n5cS>Ef."G iST&I4ڡhSdJh Sw-Cs,81dŵ}`hvAI*KSv/a2ힽ{wvү7y_y`\)sWi0 > dDk3lWzfƳY^M-} ,+u qv*?hc| xѲ䑕EOtft< JRH޽-5*\QlG@Ooe$:nT60T{&', -Ğ0TIϚثc[? m0 >;f? 07Y^LJMBwg,ExN6fb*-D}Wc u҇:īurc/"ӎIƕ>_48sy1xyB>SN|QEzABoyz{1ΦUmM`yt1 זcsc%{Cv녇q/7 FTwN}!]~7MފMG PUw/b{;w$$2{6 S N<磜?`*Htxa4aIHW7q) ceA #dR1翕cO\]?zC3w7$|=+B#m>LLӍ(i/mW)Bc\#~'\!Nul/Rr »Kw4`먐9B&~;4dH[Ꮔ,?рik kL3 +dL[w4`6>mv;_!󔎶oh4uq, hh4]WȤu2q H.=u޳K)?m!T jEO !ɂ4;O߇8tT:(t؎)9|t]^55{hۤ˃av䮾 2}*b*$E # {g@\fvD2R#n W }X/^VMKsK䈟aW>sSi\aB5W;f?"瞀O# qNjo:G;'b$ݲpjL7~{vuu9/H&g'oyˢlSMKYjBِfskdt>VI|u=e2rqn#=fp7gma?|Y951\Oo??٩j # HZ:ُ[ % f?=}_ٜ?XOEn CWeJ8/iRnQ{*V 먷;KCq4:yӼr3rr W{j!b᷋}gv?$Fs~6d7٬܎}"%p~W) Ȣ坜pWzoaM.XIPHa,d5ǽC/%O0ql{r+Q?%:kuu[/ wa`xW x&G )CG!~a'DBgc8r{{ y㭋 x"{a0h p$m+)nsn[{,ꉹ廟bc0>{䩐a\K"٥_PRh G_4UNx~~,> A,tpk\yy ųUPp_d$Vͳ8¨bgnWY2{Nm">w"ھ0Ͽo\!B;;/2>@z- VUE D5~pg܌i&8 T`h?U彤2;;u] WB9 }a,#mFsL|Nvţ_ÂOD32H h@CNΒ ϗ\?J\3ĽQ1x>HVv@AZx9S)WN"8r|g;mSKGTӔS0mS4Na5*}J+ ;CgHq "·X|>9<>I&{>  x$@ÿ2g`Y%HQwP_!S%˽H؁q}DP?_1)FB;փP󷭨Pӏa|^F򫝌n]ꊾ <֏&(yrȟmx%=u5Gh'܃GacRMto?{Q} Woq?^YMˁo? !/ ~~b u{ib /[.KpW9Iió}$xJHҐsz)|G'ȵbI4t O%]o!.L"Zf݊AZ)Br> oY1>.vԷ.3^xᓗ$A*~_:Uױ;}:Cb>RԂU2ҒjJ2Q1Lٷ];-z1C^5Ǯ߇o;ZDDw`SÈQ%Ounҥg2q~D3.RhNC\RrƜ *2򶞔 *Sk6X$ e u6Q"\4RF/MNWoM[ Md =F& ;0ZzPῆ<_8ty7,?qiaT+t~5?;|mi}Ϸ2}~篖Uzp3pd&eȂD93@@Fp}ȏz?77yt˾ xj/ntJn\oN#~:(_ߎòjh򧷟?~_G_Z~Oo&w/mu.]ՏK\O?{sus5_=:WBjzWOoXS%Ż]_^^t8Nz[;ßzklAt-_޼y?Cޯ7$}5zbMUx/\TҔjWu~7577C?o\a~+^ܺn|?ivư){/%xݫ}: {~}o}P_mK{jï~ya{uÏjlwû_>jHGCm_|r.ǯ>gMӽO˃Z~ӹ^to.OWW|ԃG{Qǹ6071{zCm;N*W+o\.v/kxW~RKk_޽:z]݇[S =Y!;ݗOwoџo0x珷֣T/3?{ݯ ?r.ooGkqmcx?,{qz[ ȟ9|[vJe/17_]]^_\t(#? Rt;uo?H>VGzoes}ݕeO7q;xtX=꼹w/nIBԹ9\#7鏍HE>VqM*4'Z?^ox7WԜU׹\^tSvopXTcuPIW7v.z6{ruҗϿ8 `T~Zcǻo?|8zAk\~+S0;Ni5߉x:P/ٱ=9M~ip9U`5SK)7jyӽym|?/QO:R)k]RCQ1jʽ^~¤p뀬[U'jնyU k7^¨5]U{^O5%Għ{f/޽֢|:_it.`4?~h;zFLBvmKW>xP~~a"VyK; X Oa?ys~ Z;Nqq~Riv![l$jzawpwngؑo"`y9X0-w///kͷqM<dzrnls+0ޱ~U_>{/|ylG}L._,˿ܧ5&wir ,H$^If_ut XkV>BI:Aó:7 Tv:S)հw>,yW7A.CyJ^s GI3A纑 7PlZ=IKЭuZU"w'_^ ӗ•J+F݋~@[϶{#:<Ҟu.z-ґf򦙫u]d̪Fz}^oup;mJ7Mْj45-&+&vq3|gA楹@>^N^IFš?^l%q-U*e`+5g5T jnlU=ņe/ybI$4mFv%đ]&4:z7-iBy,~>^DM v`PW7hXڷ|#Qe\%׊(Ql+ Fm+ \]42B^ V撧{~[zw]cU}?I,Xunǚ~3zSuK= <\uZKEV{9^2U ;'wu%g}(ښ\]hMjiY.^U@^ďqM{Yj=q b~W;ny?;p]_]q2*ӬZ:?~vΔh/cMJnIcKdmjat}qumтa*{ՂD. )$MAME6ѐzhG]\POT ԫP_&p߹6/uMvM^975:W &QۯpHޗHo?^w'ţUD Q(;JMFpdߎnR׫bKIœ ~͢-R(oPv͕ueE;}1nW^atqN&W=UO) _h]O ;7aHusJ^iY>ϭ]ݫw*[|=A=}=:z!{Cz5<CNW5o~-ǺE:!jPQ脈sba:MZ#P@4=b^ɮ?wuԿYmUvTY#OjMmONsFf FۅNvOvG޽@E~$$plQko8D_ERs'Ycqv2wR~%-oԂs~xTs'D;_uNWWFJjUky˃oZW3ձqFnh'ogFٹ!?<^r/G;{;Z[6kPpnraqV˽smhPfW0vvb0]:jD»U=nR̦ͫ[xt'خRNnu>E국97;?7vohy Uxḉ)ҝeM?HltыBFGwñ4{[夷S*jԬ{v_W5^#ᢴ#5;7]jbMZsӥFZLh0x}dӥ~ʊhՄ9m4JUh&M/4'WpdKkܤ)߼t\ ~ n ^O=ݍwRG5j"6¤lves ajOeԭw~vM,4lgW*yvNqxr3TSri'q høNn?w g߸&%n;?ko;M4ƙ ^)~f@Mz=7lgVi_gf*Q{\17ˋﭡ>S40+B^sبnjH=//kFZ 'm&[W-*vsOF{D{ڹ'щ$^]7k}-'-ZX6Аsn9nM^*ݖ# ;q-NI(8eQs@ǴB97:řNt={F+OO"X3F'[9];'xx[5ߝ˫zC;glֻYغOKL^$iv}~\k4bne8.btwoZfi?f3{4L)5i;9NL_J]Pei"j~\mZrlo;^۵G$4jFG{1П\ȭ]M?ﮰ:{9ډ1vkup8;5,.i η [1@;{rWBK3V6/;Xw^o{LÜmFcڄ{+ :C i& ]g@z3*4^5):G7:w6:niPw}YS(`./pJ{T]l@[tr/9mﻗϨ;}\׍b_3Qл\5u$^?N*9SƬGQF] Q TFvlн8oj'Sջh@J9ﺪF#㮯/a,؛oAK&vjFUXzшo\MZ麶n+winyx'ָ퐖5w{]qw!<|ky?'RszԾ䖾^H^׺= R sTHޠVTK`p,U-uOԆ%&-uU?5-6[jiәs[t'Q s[mK׿ngW-&X^2Yvz'Ca}yq*tF"I?+Z}3'q:Riؠd-%lyx^9@+'oЩ돟۬Q3+,vI+*V Nž=v nKޒOu1h6rйin @uewww_NKv|\cy^c)vN\V=x[M6|;^(t/ղ}e ;XUگaO 9ڹ\ ⛄ϯ}:}_s~E!ίϠ[{+A(\5ͮG~ Hѩ:"TItpLuRf jwR8#tp.FTjSlЀ~)HTFӹS?6 BXn֊œpT_rvuϕb;hcTT&Ve9pu|ן+iJ=cG=[#3z${zQ4(A&a&6L;էM֕ lǘoLvEikc`Vm"}<ٗ IkLK J>6u'yE ;^ ppVO֍Oڠ> TvM[O/n]^[םFm$}-[ TBϯUk^Iy!Wἂs49LS4A7é6*#pPםFp:W5ߜjpbvŹW}'GD*-[ʻ\]芾{nѸr:gn9a='g.W)7_\4NBa=y2=9{SvZ[M)it>e?N :N^Nē0ہ#۩="NE^o?8gP/X:MKД~14ܦ|5"݋FnTJ8I.7MV G+V?ࢽ5sяj-=pw>^{MR;ntgH]j^5 t d'Y?~:+CSOiP7޼lPvݯ8&~\+d`or=^?@լ D~9hSV^h ۛto sF͇|o=Ӻ~T(d/zZM!]5Y>gU.sN;LSO;]ރv"nZܪuܗ75_1v#RIOcc/ xS>sv۞;doUcRɘjIC&т\ j]WV׃^ a U50>%]lIpXD_KscٗqX=jxrb^CD҂!n:M m ?n\zo?һ"8Joӷ,/ R[9Zs~OZv^(kV)7F~͙:Uw0/g:T2sA9LSA97d9gCSYo:7܍bG*Wύu΍^E;7 z( 1΍4΍ktڍ/P)0뷷0c*R9!G:,Qq}(v]-@ ]$zŏ a. wǼXg$DwR}?JF:瓆F#/D ]SilOl&"v9ͯ5 FjS7˯TwQ,&"ufzK}a9v5d"v[SoaZa7F(:7YQ#wA=Fmqtr9ugLhYv?GJ4u;]lzuX<=cI;Dzwl@²r9;Kʅ`Zם )HPi7z(k-h-sE\J)iy%Rq % ;Rzc^PsI hl2叔爝n_~GDRqv' ޛ%۫ntrKlwQN.͹z ҁy}AQxla 3ęjz{ѯH$6)T朖j*8,]T- \ _ay t$nUb4x?nit=RJL틥hJʗqX &flfnup>6V{zNIP_gWy%^5)B9n<%|zwf]]|Wtk>vJZ>t:*5ϪZ1 ;怸|NZGBNzkq.Hv.H{Vv.G9_6an=<۰Ig{$=hz_9~ni u%j}%j+zꑉ{Z5FI`)TWu/&YObE0^]׵J!wZoVᨛ~5^Zt:yH=)B;wxxsFzs^ck߫J/V>q&Vapŕ.J_;Z6{2t^oݞ\o,V7}y=?ΏCۚ޿7$W_yg'p(z'£wۭ#t'IS%{q^ UYPfV.YyyIk Gqd"34_tQ}ZVQbEtBjM ˟.qlʲ*&rTx ӅyjP`[l>.o_n\Vl.MVB#h?_vW)?t&[!NMuΠ2w> v ɥB$YR%OT .J;,AǃC08DugrTM\z2Ϳ!NZ1TyeSL۬^BqL SKjN&rM&_^"lYAԾّ WG ĽAoj#Uo#J.!wDfku˛b[7n R4: x_gs<[d94ƞ.$/6]6+ԜA/ZixS]GVwWex4Y%~FT>šJEU凁+@hD*wWrT9*4SikuC2vZFm2=[_$*}ͱ$nX-)cuVe&cݱO~]-bw&*_RuǶ8ݱ5qW\傐v.MvŮ򵩦j76D۲H&[" M%zJ@MWl@qSdǿUTã^@D`pjU1Zm'-$i92{S ˍKmE a x;0m%,Gag/eCm~sV^odo$}6C=wpph4`tpS !{=5E1)V7.h@潟F+C5x/˟W8ٺkcD̲)蚲dj1ôDO8G]G6r5(Xư3r5tpX뱴2v HOY.P7^p0]D׈0FfnJJ6o]sţ P0_NjР !ȥ_0>o#2@E٦ui;i:Uin_2Er*\iU˴y ,x~{/ Q˞/_(6yW=䮷-.ovךJ3 LK`>,*lk.w_o_z&UaͥVw4Zbqh? mb~J}N> 0ifCI'n7^bT4:oeqA,n=#GXq+h[w=?0cp2wp!Xm,di9V~j[׆[o^2BۮK7f_[A@\B44kHG-YqY|t>1AWNgZАlU[scjmElU[D3mk xs6nk2٨v'Lܝ[+{`5?`õǮoEM SV@{SoI&~}?Į~y-x;Ex-T%Xil!V$98-$őB9)  A"fP\Bi@Po@ W@s4fXα @Nwf@Խ|#b1`p,C?)1HNSx5<턥@]7{ňpjƾӾ(\.ڪAơc~P2lZLx=feC>]kB{~i:/uDhkXhApKj9 + h+KN@w5>tDVۈ- +e862mef)&&iW1jpտ:rxIи?0Z:箯lKD8c:\:b#W` " nY/!u oOd|4Y Z΄ UV9] F692!ySvJ- zQ+hP4G0yg?jKRef@gv /Hxb,eQcX|~/\@h/?*gOŻ;Vo F6QYhr 49MG q6Ljt"CS<{"zГH6O.5C G h27 ;W\,Cٝf/ %,:ُami*+^=RC_}( 97g|Z=G óu ڇv\"6J5V|'Ta9_2,M򊜑# ~mA{MmD~&N'P%j d?-r$ܧq\hxCT뗔9':eSpJʜS$eθ)slCE\2X'DxtFhS].].P (S4$a=鹉V1c䃇}g.G:ӌF4UoEUmkN%.Sg"MU {aOC8Oty{z^(ϑ;G/YRg+y&x4% 3€_0ސȯ5&?;+9^VJxqt&4r(7 Ήs)8QJ4J(x(C6 cr/*-#ኘUBi&PN˙W`h$Bi#;>lj l_0VI} ՞ &22\5輿~>:8QWvR7hzsݠAnƹi6ُ wkhYɉ#cHǐ'ϞH|"p{ aH 9T$F;c5G8yCHxu,JM염Wh&t#y]MKp>U?R\X‰ԍEHo T9>.0##]w̩1T~j(Svh&K?Oˑ&1?U G:)V`tնUl Ǖ@oyZ0Bx x9ooO3ׂ\`#5pՄ` T|s rn: C+W|到,ŕ#8t񚦢kFWkE,^;#GuxADN([hѹO1G1񕚸Wx"UDe-Z$N"ZR(Em@4b8[\xEV5 P~ul>_༿M, p=5S:Ly]`YPqQAdW"␌r ǀnΠ31 $E7#j7"6eč8U&!Nrdܧ8/$zG:ӦTGOtDVH9'D{thR3R)8Ξ:zxH3rD-7raE~GYP7~b] ެ N4D%7eO3,"Wj, :w$HJ#_(Awة0VʑT ᩰBVDDUkM", eZ E'#BRˈVၕ( "F%@IytOm[PڶX %QY=IJ;jU K߷}w2 .-s f!7u0?s\20q7uy^6K+gm^sQ^c&Q5h8q&+dZ | )Nɶ}&S?wnhN٩p҃7 ՒZ'&P* HUN ȟ .Ԕay?&mYpb*G OXS5:w gZ."#dD0gse ib?*FV!s𠼸ʉ9jZ_i7Ki* 4UˍVm-(U}B~37HxP!Uw2k2pEZ4-"+Ϙow iYQ '#BH9̲E/piCL>d\ģ{ MA9 7XVu4_wρȯ-7\UvToVڿ_}q5FՕ\,ߝfo$ sXv )mRUXi#g9&sO\2Nl@i^c|r-{'}*tr@%!upe'LA$g bk\nj{5c D\d&ᴜbJlMZ0s@BD dgr/]?;IK_zIG[AMQA--J_lmG?e82ioZ5's/Ÿ4&{()xO`;N>a Jq05ꇦK/7}؎mZ\ßS 1_nVM6/gk,Mȑ;>{ 5wlb& &c(}-|@|Ԁ[/g g(.'Z:wK^k[ }'ğ#Phq#0Z,ޥf4r"\}TF7uc {"4SwBn7z#l!,c`Z6Kh M(u.0U(FupTГP-ԁPL\ԉ$t9t?03TdMe@\pZ TsHϏd@=T?@[) sphPMKzRF1S*$Y^{,}+FhDL<&_KQM@;6,e9 ʦAF]g+a)*i€댃[ΫuEM O3l--YP@@ll IjAB`/e)oAha9wFUzy`l_jD~) G ;ž7)`©$Mtv; M">1z0FgR.ԁٖ>JT”z,qRtap_; ʮ7b, b,縬j&kȑ5V1j&uii9ܧ؁m|_;&ph) $dnzdƈ;4Z|CC. %,l8m[ G[%lyWpF>0+p0MρJp@r{qhU l.:Q jw609e3E+Iw28Kç"~ƀUX3-o|/ C(*lr7>x{7; ,uJcN?7J͛ KԈ*7!UJN>W9/wm"'S8x}%VtUD7@5s1|r& tUCvɂU 4u$|3G8ISǙwbp@/BPLk P$Y#d1vO=~xHCd #r$e'MQE07COIPѕ&_*YoʥI"Jh*Ť$c]x6gPc2֪e<^B渙gڏȿy:7sݛI/&ӴgWje5"xy g-8?ġی>/%i"fLҿ٬Vf| oAԲ=R -9 -i˭_Ky<2d4<#G&;c 5iWp rG&N˛rςf˚V/},.4֘[QpY4٧0\XF/^aaV rZV+9OOG.\3UEkNs)ISvtK,/p%iEU^68:f*qJp ׁiGJl.=TcF2.frJL  7`N(ZUk^LńGqZ[ٗRQegEաlo OkR_<;5H")ͅAD˶ ]䕜4Y^h[8Pە촽25 f]u!,A|W*'*^l,^/3di0geBFjVMB ]5mul{wΦ Ђwn!V$~Ο{N^&cF4 19#GBL:clVЎKxNm=hnW5q7~ xg̈́~2ytѭZʪwBT*nRwY> AQe64[ŋ=_,JDJߵ%]wdULILbOȴ߫ND[Cq6h@i}\3 SHI^UHXrDR-⮶i^\aryJr-^D rȽaEu \M@}J1ZE/֦^\Pۥcx[Ylpa ܧ`xpCP* [ŏ><е@(?x5''b񱅍5.БzO(aVL:' iD0 i GXةUwbo,f=6b~u*B7Kcb +jav߾%ف96}'VJZ#i9=v^0zFԪ6Dmtf*PwklVIxYt; i#7H'RRsLK+pt+m ^ULj\ `U-Յth򶄘o<'mU1J0XҤ0 r4e*\`F:<#GGB4*F`:pN4J#8Ӏ1sh&~7A.jLM[bY<5 # ;etDO!V,fweL, e)jEX1,f˧T+]a7 =MDL{t&[a$Uy5(׮o`l%U$Eal4N82ҶmJ;I;9̎ZB9oi8~$b+$SRa,JcEN"髿 [w(uBb덡EƋo_77Z9 m&TW8Z%!}Z V6-'5*L@ m\RnnGWS(U8c1q7s5WAYyp)1E3Ux\ -~K:L|XZ 1tkRmu6[$&:6g(j=xt\ =Q/:`]EU} mSr g&0:*iRȿ=j-<Ȓ>ųM0-(Kr(7t]v-EF;)h"+dH":-cuJ]En8`8n-AwhH6!Ępr; w$=BhQy;6D]T08l6*O$*O&[bo*.&JBƂt a)8AB5 wW.6w'|J|KSqn'^nJNL :3rdPyOuB rdOMN=qH@}p4 QҊ“U(@iwFDx9r‡ItةRM1\p]G &gܣ AdҔ,POIrd.#g:2 &hDV*0\O"J# iJ,OIsQ#XvSURtXZp)')@n{@ڶg@ 8%MNˑNWbn[L`c [ tZpk]F|Z5nOMOˌd\H2QV~&G\SK*,^pooubВVCi3+_5t 7o|l! *t.!{(A)A\zݼ_[BL`n`vf/RUrIp9kܧ:p`p\)h$3Gu;[RbfK<6vt7ۇږp3(d+\;_(_INFaQ"*r_".MBǢHFSd*.4_C+دAoO֟K3rShl#oo{uI}Nl:~'uGdi9cisɈ6\a!J )M )KղPG!34YGqF6YG3&S'1~SQ4ə1/hW}cX % ^z jo/q!%Pڿ_2 #[?rtϏcsI::{DZ o|k+/y6h\ u`CTIOdyjj) ܷ[Th֊ eך4YXxFt@pk͑4ٵfT]kQ\]k0nTk[2tHn;_[&Yڜ4LڬȤRO%Sӆakd4%(%AFfOIHL.m᮶IuUd$I!8 M}t4V@Ĺ4YA|Fl vShv`AA+|5% |: %ɒr$ܽ́b:<;x/8;in+mpIfri挜w+?4rjpMd;o˗ 珫qE&r=ppM%*Pr&9Nˑ!9?cVAIqI 34!#RH\ &=mNPJ??&;&$9&Iɑ?!I~dvJҟSxs?qA*W,IB0h]˜ JHzDrt)G0P@ON`7*JgKh-}8?Р![ϨkvI 0(/"n:i0՝׹ˣ02MtI5V4ɖrFd0ƀE. R@ i NE 2\d B ~IK.m,#2GMXP¼gFX&AQDZeig,8c q-m5BK2OKN4YFdho) Z7eY\ຉiHU4xEڷٚKeg2.*8d6ep7,[mOļ"mײn}H\ggH4Y}N,6c.)L7\.}!E.\ͨh=5lLCC[i@⮘е:\fD UǑლEEGбA-^+f9k-EUjx69D٩6o)/? #ٓV`WKmஶ!I+/6E^ԷLߖ,I.JaYMQ7AyWFvl:7rt9[Qڼ,c!"&d]NIv۶KfsiPdۮ4ٶ뤜)R4Ѷ<f`lv-G{`&w fw$Mٝ#cE6$ˏd;-j濝eYmqe&\/l("^XUUYQ6,w +֐>E^ )w\gDCIJhHKGm̌dxH" 67dM>oMuÅk!M3W41=ҥQk_p=٭k4S6gB޶9fgvwxYKg.yQy>IT򬚡 Re[2~| X?B5S)j 10J,_E15fT8,sʍ'D0Uh_gHQ\ǯA.WJZnmpu$q0yXƯIXIF]m*ͽӱoa+ֲUnĒ122rT C4IqFTȤdAt]䒒\RCol0ɞػr64!V0#ᏟA-feNzƶ7++ !YWi.6]K+4ˣv-;n~m+жZU$TU*េ \)=zOW{T k;2G U2F| ~%ё4ItN?6T_,w0QI$g*\Sq nd ?R l] O~H1;LI3r$Qy LA~Ry%Tj z!Z<]rewmϏdK"WKn_?(GgI'3Q-MD0B2u5k1OD-T,8fU͊]bq[! Z!ES%:R0K9Q)a"uˆ$nÃW~MMu(NIM$qyH&KN&&TP>&&C_g[>jvNSr0&+R&-'thHhiZ:=/aZk?J%C>_ *ҮubB&4Xy-K*6IQ"o9mIt>fKfB;+~uwѸ3 `c5H. .RȦpOL2d"/cPt .\/t'L"5{diD%jJz֤[Mma$7u'Ȧi㌜@ \p>r=Zvd;B,eG>c\G>Nm dU9%MϜ#gc,)gLYhvB^ ?$Y*׼8qY=P󶤞Ci߀sOSv:rg"NJ%hM3ツqUm?JNH#̑Ճ0+g( b`i)ZJ [,ެa2e?eb˥iuF}8D2T RSuNv 3,=0@j]d9%M2#1vdi3c_y>ļtKek(6m}e{/mwbmNS1yI/DG*fDesVD6ə:c9;PGja jI4<D>yUf/p%TĢ*4;_=~zTh)1d"r@bkduެ~]\gvBv)Р'RVTM=|,Q]*{ H|݃.GsUUed]q7$y +`iv-&ȑv]1d܎gL IdXog\yv~.n i%wbNYow,M۝3!;vfHiyָOdKs-> 9 _z)ޤjziv4Yo7zZͅ>P&g`xO7M3#Xd= 絟Os+'wb7 V#@#p91@1# @C.hZƠ#Yǟ-d\ql| D R+l dҧ[a "4^E*r+!i+uQg.`Wܣ3/o mդQ$u;+ZVu`k12,crʊgP*,>RۋeeFkw>/wb3 ?&TIPCRlX`CNYk^(YŬl mlH{e\R `׵ O`!dKj3sEHȮ,"z]Yri錜eX&0&#ƺb/hqhԶ Vo_R;S1KAᠿI;`AI8sr$2.nR9JaeCfBE D5BAcfss0EQasQ/:Y6D66I~LF1GE]Eh} {3(\@D]pBrFх: ? PexګCe#b߅eRScsq_"{(~uϚt{ EdCDʘ8)El=8!<4e;Ux٬PҠRIwWJg~BUQ:2wWr<pI#{ n (#5{fW$]&P1F?{L* -AQQ2&Ҵvd Ld4d U buy8 SaJ*!0qzձ]kz^E,j+@Xz`?> L_=B!ګ70z<f;{%\v܈;PVaDy},h -!#%.J>T6:5yl^RBc!<2j;n) t ebTn7P7QT$^?Dݏ@/vj w,≺K*ۮlb$nI۷_ezo϶kC)*a4dVqC3U*-ǎ U2,RL:#cR|Im>\FU Zb~hi]Ţo ?uYXY^Kau>?|6Jdy 0qcҝ:I1ҝ:3 N~v7i#h8$ں;*4s,!n`zno7sYj(!7Z\_4 i`tl9EaoC@\Z7Ӥ4"J;ސۀIEg ҡB< gIB\ͺm;`ƌЬei֟eXYo#yOBwWO%Y@ 5nQ[M*8^V{v>8V{P|ŔҌ2§>O^ G^.JfEyl*WyXݧ:(% YuV*bFVֽTk# wJ%;wI^x]DVrLeN_0[ Re8}* rE'&Y髬@do#Y;LB҃~.E gwLWm± `MUU"LU?VI1*83 i~ UOW uWٖ^߲_MB#T5M[a9x띒U)YvJn";%7pWF)ٱLU%Qb3M,q9_vdmTڥ?OaUz"o ׳|.;{^)L[ `(Y.[3%M0o̴5-Ȗx'1D!DTd[I%p{ї FPGԫ rkE/woYz,m XhB|]@pJ0mY9CTeQxw& 95mdv1IM?'E.,%5IN^ɶai lk([b2Q mǓ)|[JY#֬)T2&SLVU|+IMN)UٟAO.F})j|(?4+d˛v1͉+I7a.D9-oᡊd˛3is˛_h @"V}C#Pnt Jgtt;5Cq8/>ajm0>K\CӪ$i[װ,lQi!uɖbdK7SlQ#YN}ݖoA' ڒ# <8 ONG<$J$?jcZIrR{tЮ|Y;L෉ne&Yl]akQ֟.=uYR1Q\6ufB=dmY:'ƓP7e p-<Qԣ2{|1WxfكI"Sfa2OD {H |\C>8&CC1mxNv! Pk_!4 0MRnLSMT6;)S3cH5 Q3Iʡ d&0<yx@{(1634Tԫ#4eԫL{+LRԫ>4yjtٺ޺IȒMS ?#otUf~>^&Х8M!=w8/[M7hd$Txz[_SB`Ǝ("Bd,P>=>*qR#m_C?, C?/"̳8d!/&L=J_tG0}v=qoTVqL>eR{Ƨ̻ûGC~FWiҷ/Otw}BƻH_W`IESC0۬K#CC9D|sc67GWWsG(EX'$OB;Uin!.vFgw΅,UbNl7_Yo+Dn=} ׯDbD{VJ2<E72r=a 76Y*D;K%hgqKGYz6ϒLۣLon7ؽx{^%h{NuK"7ϒLyY#{?>LYG̞8Bl}KRG24vt30Q)e*)Ew0|9]>?uK^&-mto lau\]UOb1C %:l` ̓ݾSsזɯI0-~vavKO (GynS)Z2lA8__Y7Yчlgl᯿C'q\.HCr7.͡OCg+裣9" "D{$Tǵ3uڷ _d;lx70wq;:] qqN{H\x"J?Y#^|g@ pEaĽ>v>RTF˪'mmV4(Ă͡Ds'i@9Bu⏺IC? Yk-`Xc.y +7U(}^ΊxHФb!qyB.+~z8T'mwmh)X|XaD3 8ᛐ')^Z1'È:1T~]Ӹ#-.Ȫ4:^Ȫ,T5Re">*=u^2^!x}Ec# 8&Q'IW҃x=nl N}*c U.:9Z(xSʃ UIEңf-v+d\/E|7{>Y}r0^yOq[/ݪj? /%wʋq; 0XESb4|SE7!h Iiz=4-,XVX~O L ~a255D V; pPu|%3MD6KnnpH[ pmP4ǯ,vzT=}&z]I^ (i׈tI5蟤KoAJ Z"JiIIQHVz˘xiOׅ_SXeQC덹77֐P3½;7r'Fn(^̬,mE>ؔh:8"" )B^vR*kV ~~o] t$ vCFKVm_+YRXx Lu4x=TT*2be)ОT!OV YlJTSs 7,Z"O, :o#7KSm#Y-SrٕaTۼvo-NT%OWHjq-{Ȍ%7 ʔ67Y b$ ?\#A Re&b(t ,yuB3v`;ح`v ?*|b>xWEM+RܖDj 7:<:5hGY0w s쿹?tUS?,a_%Hh(nm>C^+^}>#jdgȡC+IwB&AR}s$TmޠNOċ28eeM(^}ØNF~C>!5JKȺ3_h疦}6$-^)NS=9Y9Jry_#u1})U9EPv8Ͱc'gq3a'75MͩM :EqfoIՕcM#',QKR;ٖP5zGJk\ XZڅF+{$HCVc1&hgWŊ:A;*^;g-f.迼Myzk?xEo6~vxy_|:NB \ӷAղ4D?R@xQXZ_놩enh.Kb u8-fΨGH9㝷\Ak,꼡. $:UHhޫ>XڐR}9<6QVZꙁ)jr4EM.FTs,~Qg?mOl!42gQ+hO(mrJ| [D[])1wz'2a֏>U-jب;@2>u0cL3uſ &6 .p4 `3Vv0azRr\P%]2WQ*ۻ#Ls'>tfk[&w'PyExFVQ潆i$Dd[JEEO?s:slĚf!C,ރaDC n==$ǒ+`F SoV>W+KsZxݒ=bI4 -]%/Dnyڅ9?ihTļVK+%O>x{wfs flmz]hn?^kh+ ۻzĕ ǢX4ނ6V"z WpۗDCj4:/8c-y Nߢ}'[ٻ+riO_ 1]@ S%S<k?{4!^ގUt @l h EE*wSھ>IYrCNR@q>[Nϭl'%l{v8t$tu7pJRjMj'Ӳ p-; H_-rnM̵hllkf: KhCv^۲l+~/J=XXƗCSU@e`b4H;"J8'M-Q}˨@\±nWp֪leGoԇLc-yA Wi(w9f1utn٬},8Hgϔυꊬsմ}Iz:qF$m mk ˍ f5]$Ӕ]oW-4"IHGRBw2z ti5bTZ*QSM-dk/p%R>US-cXcu-皇TJ()f _'x <-}{x7xo~t5eR.剶Ak,y5Rs7o*shpk_~f?<_§gV.m2 "iƨ*ݹi0RCM$.P#jZд:5m򱎍V7M ;thD+\d =C&S~_)H߃H?dI%kng7eHm4KRG[&4$A:eܞu\2#[~a-qb 9us" S˝E} C?{Kͣ4#Q/%ca6p"il/6q{j]c.@y _BxZh}2vn܇|!q٠1{{o1N<Κ9/5OșndU|H}viK*w'*Ds+::9Ў\kMC-ݱC^#YzA4Ͳ6F)%y<˂3lȒͪ еSN{4lu5}i(H{r\q֛h-va^q4r\GL^ m#ϡwb#>+4&|~n:_x(H֩5UvDjXъhRɈKK\S[rrTo2{Z_77w9G &,OKwKՊaokN/a/Hۗ qSZ^ndNGbaxgţi4xA4ADS2DڋY-SlÂ8ZGl7YsEٺ<2 ï̑/㯏 0f|;>O'Z7 *z-zE-JWl`ѳ٬rPn?aƏu ]}-[\Tt Ŧ_wKIC/v*a^zzyKnc܇D{}F&> r<@$ӵң~Ctgy;VۆC9g2ZXh{r?9S̉!4 )T)t&┴uZv(,A )wԏ~J}׻ǝŸ,yfCfg# Jr.kQapecdz,q' za aPih+UL4(etu_="?$iBkqWXXfyWlEM]Uf[njb,3{JW/;ގ(WItȻOHcZ7hWw.`ӣ`Qh2Sݢ k_mӼ֋ PLl 6}!ꐖdž$ݑd8^jKUYmbhq = ɖטn0mG#6C-̜PvkuU9]n<E}i&eYY|VLH0!2Ot&wC-!`^&>ҙHS4H~oΧnFsQycզUTu2y͈V~.^9-:|:z_4}1?z.ϼbz_,}q/73rvY#柼Ogo6˛y7 0KӂVC˶_ ,~5J0#.zE-p+l^v; 'd_/9ìGp qp:"|Z0+__Ĺ<4$?mK ެ0*HOG da%w`H>.%4wydn3 9]5MOOz;MxG4UiWyNXyPcYdp/CoBhSq}Ǯ0O1 ݗKvC(v|_~#"/RJ))(GT}kt1j-^܀2Eʃiiu[GPˊAj͑4G};/zpat't'@MSq!rśݯ>~}\悿Q YxY'?uW 31v|/bþ_D}@×*&m%+.oے.0:x.zMQѭ6mE[oa.07Eqhn 7t )ȰnjN*mHs>/`687_F绞۹ľpxKqƛ >,—Hry0Miv{ih~[y~`bxS8,5𜯗Q^e/Y絟* /|IhtpK~+o?gQVJ՜>c仅GA· %U20ɋE a綡f"FPVm *Qk?5}DeS`O$mCce<+!xC sIAKJ FwZRetwD>k*о _6UR|AChdOa^NzT׊4L><+.-cS5t (yn~Fa윇#"[r& > _0:ĵ[b=-?|b~խqmAMIS4"fB.Jۍ6q*owO~J)%m/:y8QiӇm„]m/1KBGHDռHmC葐м+ѡQw7):PEqK!=SLT/u㷋3gc'n~vJH3laB9`'cڳa+RH9q9vf&n>xoy8y^Qf -)%*~g'~]/{vns#3zm@FVȪ]O-icSoE)M ߐE7w7pyF/)u9LUKΞm2ŎHNg=xSOGX/ -lYGXNTݣp@AG#tFG:kZnjO@\BU=B-Tv4zV߽QNx?¢׋Fw{c]1( YC>xP:s;ҲBq +hN(73 )d YS:B9J#f5C BMTՠƘ4/ʞX݀K"@Y,5AWɒc̲,av}5"eI< ͷrh=}"v9ib{]kZG̟'<$Ƒ:q:\ddz2ͣ'-s~DO zF2ѠݟUթg΍l4\\5wAPAͥ, <t>Nj0oZATky/sTy s@q>YUFAFD^6eO^.9ğD?o]b,+||rh.Gnw ]/:m֜:Lc-E,$ܻ1-=rZαmr6O b'|?7{~jaHe,S oJ΃oqN;m@Z\Ro愩Bu~tI Q׵qk<%f@ueNjݦB|Ϊã(ww}V8] Sĕ(͉djCfv*=~ʓGz-?1ZR:dًޒ5/pjK843?:/Qe\<5e=dy1+bfi+)Tϊܑi]]d3azƥYNfDI}u-!6o}"_,EA@^<)},6bA1nP`ج价 f㈆]W=Q!q< Y.dVIZ^NXgo+e;j~O.Eё:ˍ~WDR\ֿ= ?0'e\(Bf goLo73U)%BH_)\+1]w%fĹ Ў2hKGU$Xʖa?4{1Ǽ7 y6hgVE7Zm7⌫)zu w [m5e*/{{ jEsM^y 0xVVwW6=MwH8%u-y)3rPF;ZJNS+;,b};7S`Sȶh>Ĵ ǒR&?ϋVʡKviao[`]Z2YLh.mf7 bX4zYvvG~=NN0ʡə}_q}>l{| ҴEŝ:b4w[i:wmDu8WaK֎}skў6PSQݺ}ryU, 4uA{*F] WA-Fa"\ٍw{-Ug^?x{=oyK缘]y{KcN064G9/,Thy!H=yaI6t~M9/4՜؆X׼Cے27074f %/5esnyi출r ?ҹͨ9/ۢ8ҹߕ39/[s^ª9/vc'⾀Z΋[`=r_.9/w39/`xrΣ\uy4ə ;r^\r^`I/2G2^z9/[%8 wK}q,/:bI}w8EL}n}.8z#O~Z4=_!(_!(_Ŏ,==W!̴!_"(_ZmUl5a& 3V(=NYaL8e )ee/AS cirV(rVƤ®5&6'MԃƤƌV[גBrK Ar[ a9ZVʢ5i$I+᧒VO&W]Tj/LҊ{RҊ_X=iŽ kY+լz AbMexFkZq9ݳVsRu5msjO5m/tڊ_0%c0%GaJ={"ǾO+i ^'K1̼e-×p-Hz n1l6!)~mLH˵N‡߶Od j} 0I;7 gz =?G+Əte Se`(ՉULzc\M?o'"9HX:Ł?f~I2F| mMC=τDnl}N(4^?Eoi|2ŇnV_v;|^U0sǢzw=mDfh2h̢gRtOj;muaox^4X|ú_-‡.{z~WUy,{ms*a e,ٻ܀wbsy,{8烳j寧jVptjBw9nesx~7m;d\ȧdjf~1;:;uY:=h[`KD1/ͲCK2c 3dAذ>Kx@R|Rܡm2[3sX{9s4[\]ezu"W^xOSԒe9.647] :QЁmF< (5z#:^GOƽ:6ۣu3ǹ>/ }ٳ1i߈?v&v]k)«'`.Մ:M{oz$3|⟙IGrV/3Qm QM.qu_jNeuO&z) C?B'B>,qpu(Q(086f u߫M֭/cy]] JZWW>N6$I/@\g f2iک 1CD$;[ yU0]k@ZfY:9Ρs9cD-wSTd:T˥sXOM{BL2fP?>Ğ.sMt=[wH 7#=xdQG9σRi?N#Tףq}cq>vnӀ9~+߾ M8o82RF?B%͖^Dv?&s2(kD SG*<=-YQ|PUy.!<?cZiFYyQ:x=j,W!5U+C=*B|YTmyTukoJJUtuտoV;ٝ{=~GQK@ Mۡ۲;u԰,q4IPlES@16˄h-(j,bMEJn!NUR8y6A: R5;{{8'4f j2FM_;/&`z^A՞YT)`"( (dS5i^"dI5`ip,)QTSy׸Xirruzf_m՝~ {p@^g*dg\g`i9 Bu\/ܓCSzV2ƑrYr7. 嘬,'è1GdZ$ju5JԲj3WZ`uESSVE!P xg6Ȟ c.Y\n"gU4 t8li&3Ѫ{Jb)K;Y{pnYC(Z{(AAQKg3c^KXa`Y.af)brfIC@NYbو qK%D+͐02"(ҢPX-jS-}/-7}\Z 2D,3Xe+h\u2=dc r AkKVW_[`Q_~E]^Wxf%! :\:NyY@Zlu?NVo^Aq4fu٩Vi3D>  bd j@n|L!KHēC49ϔg]fdbgWozE`#ՏVGNSlWN`:7IDI4J<GUJ5k߁GN{xFlOf0\̺59 8at&Ta\ck&3c XēzaB p/~= /I~=E,IB-$⇇1HU7N4tfvD/~ƛW}e]+al{/vUK=L & qO\6e _&*Y%D=,):QNfi@ ͻ3EFП\[^cLjH ĿCi"bvɆh%X=od9)}qQnc`Sw4n(`^:~8!;% oo6hrC  m*<5t7tMVoח8Ztc7D|\eH#Ł[t ]0HY]0O]߅]!Levˆюq_BK&]PaY!訬A P}"GʶYlK2m@X3\[lm;eSoes#KhȯE@LDžQ5gwaIwYa/n3$nyi6syf&,B{y\N9n$D rBٚDQy@=n_aC>Lѳ 0s,-nom<<{Ӭ ylT"kF+7  sd]:§s !RnC+?IdCX6rv;klqZM1NBzY%W+vs G(۽򃓧߆.KA)ޭ{Ml@p8<8w_oIPrmӝ37sKFa3;OnL1D+FdZXdjӜ;eorbٗKw.ufoa?d_(a#ٞx5v䈥~hWWaTf^VuFk Nf]ap^oMMnRj堯wRsyvYP3DOΘAp:tаaEbei "Cjx3D'*Аm ]5]5 ~ 5y[" QwC$ 7Y{h1$@lQ޿,z!# Ha0e9SowZ*$u57f۔7e!fp#<*ia4nptve-JU@BBgȉWhs;|eZdO HXˀSI: 09 ׎r2"9zюä0 y_?ҫ!fAoE1ʼnI썡?8ecf.,*+`14ʔOD iȲѥv,pQlv(uE֞*Jl}X.cb&} 0ZooXh9=gXWix:{1); 2=~iF|g~FÌ'ZV󭠼x00}&1a X:sYl`V:] }n$y IfJL"l9$W7Sq=?!=+5g2i&1\eQy:3=@[S46K=YnX&i -HJ4Κ2pX %bmU^\"fq‹[^&)M"jkU5TU~6L̕ M6⟳JQ)n˶,!vX_^Xp.2/ؿDz}()LAD2L2%`ѭu_dSR YWlzCr^`G.U5 ewej{Mz/Qm T*X 40Nkk3b(>ǫkizq&g"ٽϥSaז?gIZGn=F^8E@D'2$e;Z@ cSV1EXw@z4|d^: W}ɞxK㨌U@+Qʮ$pcy`E=+R;;4Oa8j %c߽ᷛ?2mH9<(x_2ٶ.éV M8 {fRԐ~xtgמe 5x/tU&s[ko!yZNwmn4Iuoь2PMu#y'B_e! ˒i|څafEw'ǘ >Qtf@@Q+ț;2458 MTu7͂U>q;愤<&T^vosr=m Jk;yRVig:RԸ{~T3DޝKwJ(汆F:]qg5pcPgdJ#Z=t/%TG%pPmkS:jef:lҤH8fIvS&ut `f:D$q2}NJ7 AX)tN$O44mC/Im.@q!.ل!r &=Y  A j8M5#\ "obQS 6i#^m2q@L>1Yj) ƭ)ryxW۾8[cPLw{q&wYƁ-]d1`8_Eɲ9Ϝ%| \dK,YO5mch,14%aT Oi YA6 KlKզ6Ouaf!:x&|~ u\Pj4!2#āV|/jwOq/3g'_y?0iUXb8q%!x2 $D싉g?{ʻR!<%l@60(+Dbm@uMvZr1P}5Bt.AON lN|Jr3k("B 먚AJDw~Jk rk*Pra3xqq67~_nBg?UG^Fw*2IeY(  OTօ-cRZ4Ij }CVGF=ۮGؚq rao E4f:Mޣ҄Ij1S N*ǒ4E"$fa#ĚybW_r&fHIp\iPEJؖ0M\y-[tޤ 1([Xo$m X3g%&sWY/g߲ć eo6&-l%,f;hn0yg?$+ 'El\Mױ5\NN/nݿo'6`k@1~UJ<뿿c FCL.;L,c2xOq5jmVY-Si[ :ʯj[8IXg0X6JCa]am(LW|ǼFrYO_~Ǝej93*#3iܻȝWd;y7v6#w=[t +),'s.~#?rJmE쿵$6@9ucY$ԋ\@k/a=@KKe0bVM`܇g{8{j6swE-VEmDI4~fdX[x 4H3B1Ȫb0NɡFஎyH?fq\ =_4$dN'rv/q_jnino_\֛N/*gt\K1e*OƧ ŴMi6N]X=[B,(BM#>1Eu\gz{8*B= qYM2NuA{fH|t`PCL$up P4^ubh <HAk:L7yZ ^w C4,${m}kjchK׎mܿ_]=YlѸ3&ߵ۵<< l[_r೉,öoEл&YDkI&dmI6{m,}/~J%9^:s#+_KGYzucYH8ժ C"`[0{P: {h10zU/*ϑm @NQUC0<{>Yދñ Tׄ*&CP(+kr*d̕5A]GlKn\Yx.!ZpW+nfҲCn!(Bi`S Ww=ݐF>xEͦrph֢4 .""kuw\#"Z D TZvɮ_Ҳެh]'QudwS2J1 :  ;3B @S 󖈬c5t\6:.ykj84?U i$rK|Vme!&bC(2Y)~]*|` Rմ@T\-՗k~E]Cq@8̫13Uğr՗2 I Ow>(xM=DV]#{+<=-b*˓KGrA :Ɠ>`9\?p+! ƻ]]$z|BцP.u "ں!BCqW YhiiLO?QqkϽ5E(=.+Q)BMc, JYd@Jk)SB/{?+NjEYYor}T:iה,‰%LU53agVM4p?Ə֚ c[L,kscPZ=MÂ9FgЍ'[Jm}2h{KD2ku(VG׬댵 jʠtjôOSXnk-?VUG貚m=OirB6҂?Qq:6^`T6TE ۚ 5q.NZSkZ7vXgTtl) =VEodù 5`v#`;*ky Om/'Z1eh̩Go$SGc2 qB$k;foDeM yG O&x- Y]dA`-5BN6JvbL5 z,Hz+5}Z˂!pQ4@#Zn?{Mkw 1.xG1|/="O L F]XN6>>^u?Zü#θ?<.GGVuf>nVm쾍y]QfVW9_q-$~;8|&P2vĤp8o3b z+vЪLfu!]쿋OYނxHxhs$\z'-#FhnXj3h'k7и+:;, 0l#Y} ?E1qJe!8Fٝ"SKE޲C ՝oD2Lk8Z0~ u+KUT^2~VGdr)Weh|~vAӄ^V#!#si/QmesD*|2;R#%xހ%m[AU926Rl& whߙX?7P=>sA?7oy0VgSEYd=bD9?{Y͊_–:ٞb7sE&GyeUCHSd o"RŅ0wB{Osc}[kkB[dٴҳk:]PMhVgoAԔCL*=gSiW6Xl*CVȻ @2ig\}Usli' -/0Wpm+$9h\j3``= MFP%}x?,^4ɺ@7Db7¹&s,zoeoqч2wj4"1SflH?_ˈ,Okw3USpmPPqןk=2FMzCq] :ڙ҂W L{ ,Nx ~fIz;%8cMљٺ{N 2 2qkLQ[7z]H,>mcw16Uv)ԍ4_&΍my8q})WWZ"=E<5C-@k%gTKmu"C-ʇ!;+~,]] w`o1 v" N` J4&HP^r] | ,\M@/0v[-XT-p>H .{v2EZѭ޽ )[?4_Ҙn FcӕBFk̪"Eҫ(f([ PRHE;a;$wPwzMѺ3gUw//}zru_9Ҧl^̴) 1k;I/m':<[\ S&ٰ|yO՜CVY@4ZkGo yCԸY dhu{nQ"5ʹ^F[;zOx)Z6 u%"=O(&4Eae6bI5fu(.`?[J= z^НfeGve95+R{l;\22z/|\HCdž73| jaY!0[۷?X6&|"|H\s2;T0S8U[z!aEkH؝o$Aߐpxׄ:<g|^F7 emJ$3Hҁ:n/),֘=%YB@_1V*}uo6֚=1`gCE~E&qH'5TV=`_W:CCz3@ṿ=dTϠ30e^ko)GӍRcRa^uUɌeok. _n\^n@iȼxҐ5=wqFR?<4brMbeo6<gM'P%@(@7k5}ruK1r0'We$ }re 'wHcar߰1X@ wxh|䛵R}`m"wep zd{BwfY/ ?}#WWN( ͸)5ѕ O]Uf惰^ ֊;DT fnY "vr!O(2]-d/]MSm\ s&z,9Hͥ%MUKm^̤uec(osq"m- ;+BlӇI,ţh])"9i3VfE(W]k{,h6f{E]SkK =XiK0ݭLdؒ 'ZGʲ!`h|hD J hB0D'#5?o~H+^i*K;)dmƔ0 Z(*褆 "nKU@o q,J8!Zv"p G2&nEfqdo8wy|Im^@Tu0?qͳ KPlmLnQ;3O]Ӱv# ഥ8^oJ@$wԠ qt:0ZlX|^exC#EMH/Gq c4;<*|- ~'lڕzjȵۈ{,7ld|=r}uvXg/>H]|=YPChnp5v1,iNKSk^d - <ôdfiXy|WSsT9Pk۠N/L:5pRNc9Rd!-!; _B`ܶwX;uMK[#*P`E0ggUL$L3b+ť Jeヵ'Nw4`&g 8S4ͣN03@Dz?x / @zoM5`B?y .c 6[p Xb|l5V1,xE=MEX&WV&|kH<hwxElb<2*D6._߇*,-wA7 Fi^!^wux,~ZUovWWS7vNKK*Eۡ I1T ~;IL(\pTMw~z|Ļ_ unl"!ǹɑ[㯩 n2kg$mmV+a16Ҁ>Ze%AL r)8HM)c7D_RJ\t>N` SS|LRWb/P h)D8yB--EiQwaIV+!wRB2@H=Z:ffǖ_.2 Wud-x gpmؑP e]eOfOn"3{[ vSj`ЮS$~mV΋-"/o޶dZ1*]s8\1]Sxvaӂ^ "s;`(Yš1G8vT\6!qa*"Ddwm{w.75o!Rm}Im2~Yԗxۦ؊ʫ=MkW %"L&)Bq0<Do$QE}00g@h(: ?J5V߾/)zh(o3s@xگoф&x h@I\2m(NպD8>|oz_n晙v̺8uZLΩòͤҘ0-c+D=0&ahvTPncxDH͌y0.D|';Lǎ24Pc2Ua=r )tHPy҈+ꇳj em Lǎ" 9hZ7rgǎmh+DyK8E`11^b?ۧfA츰sDt&4 'G!%<SJ6aEz) m_ +=VZkCwaF/a1'z-V-\۠<~6r]j4$@Vow((Y.kTWhd$죢M٪6U 04HabP#]QCHFp-=$T GL᪬-p2fʓvl2s4JNv!z. b sU:[) Q Mwr s]՞Aݛ )جy[<ӽ40ڠGExcGy{۹Z/GXir)WW~u8dY لCLBj@7¦J$^\ qTfQт7hrrEU蠟G^yG%$^wyrKz]_і\]ޜbTx}lM)ٍgoy8YfS0AbUr;_J1Z0-1C V4]@h1洆Ltpsd&@zebXXf:lV2&\g Wc omàn~mVѶvU;Skg1ΒU[s{l6ݷx 4URa3 so;c1$S1DL"So͏+ڹ3ݦ2L"l++I#LV}4o\rՍZE;ttpkL_Dwyx\2y:15_h//nuSzSVlږ[m//f^q@W@R}gY6+K5] ^|]9L%ێYN;yfIOl Fc1~3 &@w.3T.vvtNA (NL&dyd-(N}s*GQr 96@@>-t)@6k.yl5`~-/ʹOH;Jrenai6 [xU#㣕|OcF?5V8_)dLLrzarRaaL%R{A @kEX̹n SSA]^NtUm = { opU"^]1M@8oCZl/ Sۄ?X6N #l.6ր:0S 8@Kq-VB2ݛ1'١gJoʛ(tRGxB8 P?2_pA[Knh8J0XoAD>-sԀ95$5s0ażSC鯍(J؉,8UNq8x1^-Cfҷ[f!e;waIzC@8O76>o 9U6*fC(&j;A^Ӡ" Aw68Jdк2@/1 Ef0H{6I, pN 2A/ #0<;Ÿ;<_zCl[E*$ /ً׬2;y吮ã~*{}aN^&%!ϏTuRs;,a !2]c :4Ѻ\՟@[#I3zOHK hF'S ,_ Y-{?˒sWdڈ-,GqF!~ufZS~]wQRUeGfh/o}R5,/ m_S) B?k]?)-͊rQeqϭ,!| 0,X,PoH$W^EDqV?{z4.֧N#v:ZUo'I_Nw<9m3ݝ,},YPe^s~/m mtۦan}JW4G4)Y'~Ʌl9}j"D81xz| wA;QaE!qy4hE?'bUM+:!.mV![?DgVGsZt+_̶{ez?}f[y埂33u֝h3'+8sxgNP-789DhV` aЬe+'Guz}%~"4+zf8MzKdh`{cۘ2Wōyl{ "wf8H sڼboc~ AMifnk.tkR8hW.Rd?z=!ϯ:zxB2h7M4IƝ;xGMxf1N5:IyI: {*1ATf.3|37HA LdzzwF {ӧ8.$%^5#+Fr]]?t1e߽kweeN!"זƗ߻~,+ju㇇4䬅)..#-pJU!*쫗Vf^,rcP: y *H 0|$<&)MW _$}IHX?6&F, ]rf@xaĠmXyD_f,YT]=xˎbdƒhmZtLwJVWv/Wjyso9!s[fIY^J a[_$ kSقԽL=&a+EI]}/÷le2%roUˈi@ Mr Ups XU=uEC=Qz8`J&B+2­ѕ b+-!-QKE4`Ŷ(KstgpP2hQuIl mlc(k2¶Q2dO֓ 0@N`o{A9(!|X7YxvDWd̃6B8BGћpLj1 L~L)BM=݊*<\;n3xLӇ'R7!NV_a6}/o5vۜG鸬)])lS55$p̝MAg;/I> |%/0w_f+ٌ;]Z[?ldmEۂ`@;KGc&9x5߬q ˫Ãf[ZI?ه$ᘚW] `tc,̊|hAvW%/6}w|)BkafV 0dOxfY;B30(:?ŏO8Y`/NuwHj9'cYa>SVC,0yr]IQc4 9 }%l 7 )[6BΜ,oՔ?/IL, S15nVeOyjö*2osK"z5 9r>$gt#L lWf&/arx":PZ~'?a+ޝ 9a|_ p޽ ;WAĴ{u Oph|X Gp>Y*+\֭.K.-ʯI$BllWģ{F~]}]ůOso˕M/HoQyq8t.t}bMW9}лLKoϕ͹x ,I| і21- MW1\yȎkpi#˴,]i=/P^ /Ӳ[tM}UI.c ,6; yggNEY\gA|3]MłFAG8 *JJ'O;>!j4.9n~+:!yB*u?͂[;&O4E<ƃ7bYDLU C9:|v%$C@|;B?q#FX" g)Оy߉xEawz=&f ~dp=_|"=gn؛W6î䜉w稓я ⤙n q^6ȸi4DB(@}E\P]t )WCWut1Ւ0P\f65ܜ#({L]7vS8#t/FdL9u9\Jհ!v4< #K+=*DžDm6a|h@QY!5bsB;K$ TDvl9WWT *PhVfc l!KU'ZUT`O~ Pz5qtQ݋t&C;pɲf#@`Zp5,`J/w'4+N NT nZSh<)b3@wȪ,ϩڱ5ƺG*:/"h3d^im˼IC*w# !M =n<\"@ '%ܭE|s֙j'uÌ@['|/4#aZu*pj˝䬚D(զ;Ƀ/4a3]8*<1JR2GQKSWѓE*ZI#{d6_PO`Qu qa8Gw&h+^0a,GQQ~â1xVfM^WmLH+S:G]Qm̶&^RW@3s+7ZMutt-}İaf>9A:v{TMkOGuG1 _S} MJ7 `ʗğECP @znb15D _wc.CP!*-ǁ6l( + 8y MI޵xz2n!T" +'xu@xu-%KER zYՉ\AUڍoVn_Nœ?ޅeۋs$s`NǞT '?5:4[z/a <+a=xGT9i' ]ey ,`*b^\8 W /~ 7NG^l" |ur7ak,QWbnC׿u:}-љ#E2jRv u@a8.8rwvש~_\,>﵄]I DmiXʐ~'#qn6c}ftzG<썄sOd"1va*12QD:ŢP)`0:LE;9HiO4eSU2ri XI*IyN8.~D#[VX !v񖷗F-BO8ɓݷR Zt#t !z ;D蘃lX4b0;xp@t.w,=YQdžGrOx9zt@au:fX8ZwπO߅&aw?]Ͱn  FNrU vm_aAgYޱhJj2 V! eDʵe t0}R-c|3Y_ܱ4K|з;l`fXVδ’,W o*H{eyK;y뼩,wWg74LG l3-?1 #!D8CҌrbI$%E/RUΪ 86lTYj?S/Zqri[maDB/hT 3UγE,V-E[2oP]huƨy;C?X6K| 0>,D:swR>ik|6 $$92B,3JEN 6 ̅soN2s+o3r@YwK|N -tX^fac83ZSf`:59|Ŋ\-˳Ѿsf{Ǚܹse胐A۪>@%G6A'aHm"\8A 􈟛} 6LEԪsRȍ=~܌dy!ש^I[5$z7sOnJJ:e֠ݶV̨D&}a.c9J:;I wRg5xDn>Dh@75*pٜ93] 2U`+;H8̲5My8ebJ&"  4t;n2ծBp>gqod*s+T[̲u66ۥPk +c (y2uX޶ꔱL@{)bԟgKe65ٹF] >Y&Uus:Be<26?1=Fڅc_8P8(ċ F%^8t\6kjnv 4OTRaohp!D MA=mW@C>: wKS~KV"^ELn~*~'I._SʷΩ?mc Ow N;#Y }DNB=+y=PC=O0 0S m*]KS k`csVƊW[,M9&Wa Ȣ*ijN*7ENZ9znCq!p? +/,}x,%nhL:ɖh ?6PF)<4: @K hV~=/?m"x_Ih~BҥOރ?vG,nWfm0q]IyLgo}{Vl6 Z3 FjFS`a7,h)x$iQ| )Y4K-;S5'b퍛C``YTdv6B8BGћqwLqw蘃Zs.)j'p 䧜_pe !Tç<:ӄY<,pCwqMV=$$UQMR{2U@K7å-G~/qV>t œʩgFMUcK+otN+(mK-t=bܡs2qYuo+;DDH}T~"pS`:NTb:tM6c.f8!egK`슈k1{jpMG&^0d;yhCz/6)gh #,I2JwM ro4MKeZn<ɦ*2dX#M}/9̜wfv狷g]. mVL[he BhTYuȹ!]kx~VNbdPJftЌN;}x 0, ^XOZY徬34ck=ͽ,b..OP':a=krA9swRA]@Z?P//M `wc0!;!s٘14etK' MMjr~{1\Y8Wʏ=![g΂ģu BkOLͨI;: 3` t0SlUAl^Fz<AZw|!#, ~wѺ 7!MN@»6#dzv7"VyDד bda ;3;ִYyUZfbӆh Vi;]'&c,z񗛐U*CVb<<(TZ~P(Zϫ{EVyZ }9py޽*?V_aw\KFQ a#5# ׵X̙GgSî3ӈYڡRIP3 J?Mo;X:%0ݫ伕υ 鐐3^j E]J k_{$-rF;$$^n-朁QU-O)ݼ#NW_?XG+!M ֭JS%0: `15[waIHl˩8>nVm83y#eAt_0u@QÕfeL\_AEv^/W Q gn-;Sѿ:Z>a,Z;9T[_:\f `@[=l|!㥘D+W5F2>>ܚ4B@4<shV 1M;#X^6hpܛ`J @[i0MNИspo_=W ya%&/,E ‚v`[hw )/ LFYKJFq'e}_#mWIJp+2HF_]ހ]QyQꭋV !5 ٥;mGK"l\f'$ݏ5k 151.]Fpn~T񰓈tٖsKr8|]Yle/ǝ'߈g?O HrLJ]$q^wcfTyR'f[F߽>!0oq:,=l7xÐRCp2L4cޗJ0]y9;К3):e˒nR07+9" tG}b;eրtlF>WQ'۩5Dc!#Ju4ZޜPdYpOnE`E8>>]P$i5 qy|kF}} ڨk5IOèVME7HC'Մ+zE詰րS}f<kc;%蹘P}mM򄿦C5'-3aC[e|jZ皓sŅDB\|-7Wa6L$\98\v~1&qR(0owV#fQO/pa);1+`(z~8!6Lm!ߜwm<΅d3gvCC$G= h0Fxx/)}L2ۊ׫a Or'd6Ą+2׭6D-%@?<4w괍~jvkhz,׹G@D%8פ<12Z rTʎĞ6hVf81˔mW㻥|%ځ kIB" R弙 >^q)Q+yL ș :`g: {0Xp!`:zC!]Ѭ[ _CÌX(?еԧY' 9ΰڲ{ɰ5$%q:/ޜ4 TI1Ar/`L<\} ޟ Yaۈ·x/Hx6ɹ/ MQЋ,g.KŁnQK޶NRPeaT>Kb7ϥ) V0 -n-# nz!}tiFp}Twh"љ|D%_Y=5oѫ') y'A.x0m$a{H#Etm_oDq8ȗt>^w8,3_elXMxV@RϴUŎbOxVLt ) jlٽdLIг+ݦ5羖zȜU_Xn*Qc3WX~hQB%p, WQjyk' [?0DB/;7~q|}}%gȳRN(Cm[K"P'%quŅxb<UJK(2ާ'j!mvBT׫E)qR4C4O#y*,/+a IvZ̢iG3"CO+4 53PQTM-iAuSa, 5U25A0„Ֆ c( [A?_eiNӅڒ{ ZyiT M}dc #t,Q\c@3 wܪ* 7ў 8SmB߹*#pUe i GϠD#^)m~h/S(A[c'TΑ7ԁ1d;oލn̢{fU-Pa1a 6d:M :Ks<5U6d:Ke dQR'ڐYDnJOu!< <2؃lgXz}[(ߤ߲S^) |.(_蓲 مWQ6O0F٭Rr?1yST}#4n@~`VJ˓Fyc<,nXLIޤh`WdDi]9glwFEԘ~}?J8*Zp&mZ_5Q؝=M l9):bŜv"l8vWJ>jwD"! !6ϣؖW3z ɀ )*W8:9jߕ@Y]e{u\ 5눒\BOHs쇷?H?%YE*K>B`pnk4n̽g Je&Gc7οl62q?rAg!a[ FOEclu-b:@ s=>V*l/" l/]~.%:us=ĶBF@IWӸb-Q՟SorJ{kc/ x;VEd^D_(cs̢ qLaX4UeI/[tN=1zѶ9l9WIO_f9î1ϗMkz%^/F Ǒ sa^DE/ˢp!}#;;󣇰m[1'5w/54?0,2,2,2,2,2,2,2)0%davix-R_0_5_0/dist/abi/check_abi.sh.in000077500000000000000000000011621257152637300176170ustar00rootroot00000000000000#!/bin/bash set -e CHECK_ABI=abi-compliance-checker LAST_ABI_XML_FILE=@CMAKE_BINARY_DIR@/dist/abi/abi_checker_last.xml LAST_ABI_DUMP=@CMAKE_BINARY_DIR@/abi_dump_last.abi.tar.gz echo "Generate new ABI dump...." $CHECK_ABI -l davix -dump $LAST_ABI_XML_FILE -dump-path $LAST_ABI_DUMP echo "Compare to previous ABI dump" shopt -s nullglob for i in @CMAKE_SOURCE_DIR@/dist/abi/abi_dumps/*$(gcc -dumpversion | sed 's/^\([0-9]*\)\.\([0-9]*\)\.*.*/\1\2/g')*$(gcc -dumpmachine)*.abi.tar.gz do echo "Scan for $i with $LAST_ABI_DUMP" $CHECK_ABI -l davix -old $i -new $LAST_ABI_DUMP echo "Scan with success" done echo "Finish !" davix-R_0_5_0/dist/installDavix.sh000077500000000000000000000250151257152637300172340ustar00rootroot00000000000000#!/bin/bash # # Script to install a given version of Davix # created from the xrootd similar script # # Syntax: # ./installDavix.sh [] [-h|--help] [-d|--debug] [-o|--optimized] # [-v |--version=] # [-t |--tarball=] # [-b |--builddir=] # [--dvxopts=""] # [--vers-subdir[=]] [--no-vers-subdir] # [-j |--jobs=] # [-k|--keep] [--bzip2] # # See printhelp for a description of the options. # printhelp() { echo " " echo " Script to install a given version of Davix" echo " " echo " Syntax:" echo " ./installDavix.sh [] [-h|--help] [-d|--debug] [-o|--optimized]" echo " [-v |--version=]" echo " [-t |--tarball=]" echo " [-b |--builddir=]" echo " [--dvxopts=\"\"]" echo " [-j |--jobs=]" echo " [--vers-subdir[=]] [--no-vers-subdir]" echo " [-k|--keep] [--bzip2]" echo " " echo " where" echo " : the directory where the bin, lib, include/davix, share and" echo " man directories will appear (see also --vers-subdir)" echo " The default is ." echo " -b , --builddir=" echo " directory where to build; default /tmp/davix-" echo " -d,--debug build in debug mode (no optimization)" echo " -h, --help print this help screen" echo " -o,--optimized build in optimized mode without any debug symbol" echo " -t , --tarball=" echo " full local path to source tarball" echo " -v , --version=" echo " version in the form x.j.w[-hash-or-tag] ;" echo " current default 0.2.7-3" echo " --dvxopts=" echo " additional configuration options to davix" echo " (see davix web site)" echo " --no-vers-subdir install in instead of /davix-" echo " (or /, see --vers-subdir" echo " --vers-subdir[=]" echo " install in / instead of" echo " /davix- or . Has priority" echo " over --no-vers-subdir. Default =davix-." echo " This option is on by default." echo " -j , --jobs=" echo " number of build jobs to run simultaneously when bulding;" echo " default is + 1." echo " -k, --keep" echo " keep the build directory" echo " --bzip2" echo " use bzip2 to manage the tarball (when extension is .b2z)" echo " " echo " When relevant, the script uses 'wget' ('curl' on MacOS X) to retrieve" echo " the tarball" } cleanbuilddir() { if test ! "x$KEEP" = "xyes"; then if test ! "x$BUILDDIR" = "x" && test -d $BUILDDIR ; then rm -rf $BUILDDIR fi fi } DBGOPT="-DCMAKE_BUILD_TYPE=RelWithDebInfo" TGTDIR="." VERS="" TARBALL="" BUILDDIR="" XRDOPTS="" VSUBDIR="davix-" MAKEMJ="" KEEP="" UNZIP="gunzip" TUNZIP="xzf" # # Parse long options first other_args= short_opts= is_short="no" for i in $@ ; do opt="" case $i in --*) opt=`echo "$i" | sed 's/--//'` ;; -*) if test "x$short_opts" = "x" ; then short_opts="$i" ; else short_opts="$short_opts $i" ; fi; is_short="yes" ;; *) if test "x$is_short" = "xyes" ; then if test "x$short_opts" = "x" ; then short_opts="$i" ; else short_opts="$short_opts $i" ; fi; is_short="no" else if test "x$other_args" = "x" ; then other_args="$i"; else other_args="$other_args $i"; fi; fi; esac if test ! "x$opt" = "x" ; then case "$opt" in *=*) oarg=`echo "$opt" | sed 's/[-_a-zA-Z0-9]*=//'`;; *) oarg= ;; esac ; case $opt in builddir=*) BUILDDIR="$oarg" ;; debug) DBGOPT="-DCMAKE_BUILD_TYPE=Debug" ;; help) printhelp ; exit ;; jobs) MAKEMJ="-j$OPTARG" ;; no-vers-subdir) VSUBDIR="" ;; optimized) DBGOPT="-DCMAKE_BUILD_TYPE=Release" ;; tarball=*) TARBALL="$oarg" ;; version=*) VERS="$oarg" ;; vers-subdir) VSUBDIR="davix-" ;; vers-subdir=*) VSUBDIR="$oarg" ;; xrdopts=*) XRDOPTS="$oarg" ;; keep) KEEP="yes" ;; bzip2) UNZIP="bunzip2" ; TUNZIP="xjf" ;; esac fi done if test ! "x$short_opts" = "x" ; then while getopts b:j:t:v:dhok i $short_opts ; do case $i in b) BUILDDIR="$OPTARG" ;; d) DBGOPT="-DCMAKE_BUILD_TYPE=Debug" ;; h) printhelp ; exit ;; j) MAKEMJ="-j$OPTARG" ;; o) DBGOPT="-DCMAKE_BUILD_TYPE=Release" ;; t) TARBALL="$OPTARG" ;; v) VERS="$OPTARG" ;; k) KEEP="yes" ;; \?) printhelp; exit 1 ;; esac if test ! "x$OPTARG" = "x" ; then noa= for a in $other_args ; do if test ! "x$OPTARG" = "x$a" ; then if test "x$noa" = "x" ; then noa="$a" else noa="$noa $a" fi fi done other_args=$noa fi done fi # Fill empty fields with any non-prefixed argument if test ! "x$other_args" = "x" ; then TGTDIR="$other_args" fi XMK=make WRKDIR=$PWD if test "x$TGTDIR" = "x" ; then echo " Install dir undefined!" printhelp exit 1 else tgtd="$TGTDIR" TGTDIR=`(cd $tgtd && pwd)` if [ "$?" -ne "0" ]; then echo "Install dir $tgtd does not exist, please create it first." exit 1 fi fi if test "x$VERS" = "x" ; then VERS="0.2.10" fi echo "Version: $VERS" if test ! "x$VSUBDIR" = "x" ; then TGTDIR="$TGTDIR/$VSUBDIR$VERS" fi echo "Installing in: $TGTDIR" retrieve="yes" if test ! "x$TARBALL" = "x" && test -f $TARBALL ; then retrieve="no" TGTBALL=$TARBALL fi if test "x$retrieve" = "xyes" ; then if test "x$TARBALL" = "x" ; then TARBALL="http://grid-deployment.web.cern.ch/grid-deployment/dms/lcgutil/tar/davix/davix-$VERS.tar.gz" TGTBALL="davix-$VERS.tar.gz" else TGTBALL=`basename $TARBALL` fi fi if test "x$retrieve" = "xyes" ; then echo "Retrieving source from tarball $TARBALL" else echo "Building tarball $TARBALL" fi # Build dir if test "x$BUILDDIR" = "x"; then BUILDDIR="/tmp/davix-$VERS-$RANDOM" fi if test ! -d $BUILDDIR ; then mkdir -p $BUILDDIR if test ! -d $BUILDDIR ; then echo "Could not create build dir $BUILDDIR, exiting..." exit 1 fi else # Builddir already exists, exit echo "Build dir $BUILDDIR already exists, exiting..." exit 1 fi echo "Build dir: $BUILDDIR" cd $BUILDDIR # Retrieving source ARCH=`uname -s` if test "x$retrieve" = "xyes" ; then if test "x$ARCH" = "xDarwin" ; then curl $TARBALL -o $TGTBALL else wget $TARBALL -O $TGTBALL fi if test ! -f $TGTBALL ; then echo "Tarball retrieval failed!" cd $WRKDIR cleanbuilddir exit 1 fi fi # Untar tarball if test "x$ARCH" = "xSunOS" ; then XMK="gmake" $UNZIP -c $TGTBALL > "$TGTBALL.tar" tar xf "$TGTBALL.tar" rm -f "$TGTBALL.tar" else tar $TUNZIP $TGTBALL fi if test ! -d davix-$VERS ; then echo "Could not find source sub-directory davix-$VERS" cd $WRKDIR cleanbuilddir exit 1 fi cd davix-$VERS # CMake or old {make,configure} ? if test -f CMakeLists.txt ; then # CMake: check if there XCMK=`which cmake 2> /dev/null` echo "XCMK = '$XCMK'" if test "x$XCMK" = "x" || test ! -f $XCMK ; then echo " " echo "To build davix cmake is required: " echo "you can get it from http://cmake.org/cmake/resources/software.html" echo "or from the software manager of your system" echo " " cd $WRKDIR cleanbuilddir exit 1 fi # Check that we can build this version #if test ! -r VERSION_INFO ; then # echo "VERSION_INFO file not found: this davix version is probably too old and cannot be built by this script" # cd $WRKDIR # cleanbuilddir # exit 1 #fi # Create build directory mkdir build cd build # Configure $XCMK -DCMAKE_INSTALL_PREFIX=$TGTDIR $DBGOPT $XRDOPTS .. # Get the '-j' setting if not specified if test "x$MAKEMJ" = "x" ; then MJ=`grep -c bogomips /proc/cpuinfo 2> /dev/null` [ "$?" != 0 ] && MJ=`sysctl hw.ncpu | cut -b10 2> /dev/null` let MJ++ MAKEMJ="-j$MJ" fi # Build $XMK $MAKEMJ if [ "$?" != "0" ] ; then echo "Problems running $XMK $MAKEMJ ..." cd $WRKDIR cleanbuilddir exit "$?" fi # Install $XMK install if [ "$?" != "0" ] ; then echo "Problems running $XMK install ..." cd $WRKDIR cleanbuilddir exit "$?" fi else # Old {configure,make} # Check that we can build this version if test ! -r configure.classic ; then echo "configure.classic file not found: this davix version cannot be built by this script" cd $WRKDIR cleanbuilddir exit 1 fi # Configure options if test "x$DBGOPT" = "xRelease" ; then DBGOPT="" else DBGOPT="--build=debug" fi CFGOPT="--disable-krb4 --no-arch-subdirs --disable-mon --enable-krb5" # Configure ./configure.classic --prefix=$TGTDIR $DBGOPT $CFGOPT $XRDOPTS if [ "$?" != "0" ] ; then echo "Problems running configure.classic ..." cd $WRKDIR cleanbuilddir exit "$?" fi # Make $XMK if [ "$?" != "0" ] ; then echo "Problems running $XMK ..." cd $WRKDIR cleanbuilddir exit "$?" fi # Install $XMK install fi # Go back where we started cd $WRKDIR cleanbuilddir exit davix-R_0_5_0/doc/000077500000000000000000000000001257152637300140325ustar00rootroot00000000000000davix-R_0_5_0/doc/CMakeLists.txt000066400000000000000000000012241257152637300165710ustar00rootroot00000000000000 file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/build/html/") addDoxyGeneration("Doxyfile.in") SET( l_doc "${CMAKE_CURRENT_BINARY_DIR}/build/html/") install(DIRECTORY ${l_doc} DESTINATION ${DOC_INSTALL_DIR}/html/) # install examples FILE(GLOB man1_page ${CMAKE_CURRENT_SOURCE_DIR}/man/*.1) install(FILES ${man1_page} DESTINATION ${MAN_INSTALL_DIR}/man1/) FILE(GLOB man3_page ${CMAKE_CURRENT_SOURCE_DIR}/man/*.3) install(FILES ${man3_page} DESTINATION ${MAN_INSTALL_DIR}/man3/) davix-R_0_5_0/doc/Doxyfile.in000066400000000000000000001454451257152637300161620ustar00rootroot00000000000000# Doxyfile 1.4.7 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "davix" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @VERSION_STRING@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/build/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../include/davix/ @CMAKE_CURRENT_SOURCE_DIR@/src/ # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.hpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.man *internal* *neon* # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH =@CMAKE_CURRENT_SOURCE_DIR@/src/ # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = NO # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO #e XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO davix-R_0_5_0/doc/UML/000077500000000000000000000000001257152637300144675ustar00rootroot00000000000000davix-R_0_5_0/doc/UML/davix/000077500000000000000000000000001257152637300156025ustar00rootroot00000000000000davix-R_0_5_0/doc/UML/davix/128042.diagram000066400000000000000000000000171257152637300176660ustar00rootroot00000000000000format 74 end davix-R_0_5_0/doc/UML/davix/128170000066400000000000000000000057741257152637300163040ustar00rootroot00000000000000format 74 "davix_core" // davix_core revision 1 modified_by 42 "didi" // class settings //class diagram settings draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default //use case diagram settings package_name_in_tab default show_context default auto_label_position default draw_all_relations default class_drawing_mode default shadow default show_stereotype_properties default //sequence diagram settings show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default show_class_context_mode default show_msg_context_mode default //collaboration diagram settings show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default show_msg_context default draw_all_relations default shadow default show_stereotype_properties default //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default //component diagram settings package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default //deployment diagram settings package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default show_stereotype_properties default //activity diagram settings package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default show_infonote default drawing_language default show_stereotype_properties default end davix-R_0_5_0/doc/UML/davix/128170.diagram000066400000000000000000000427261257152637300177050ustar00rootroot00000000000000format 74 classcanvas 128042 class_ref 128042 // DavixContext draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 511 145 2000 end classcanvas 128170 class_ref 128170 // DavixInternalContext draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 630 166 2000 end classcanvas 128938 class_ref 128298 // DavixGate draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 221 70 2000 end classcanvas 129834 class_ref 128554 // DavixHttpGate draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 207 197 2000 end classcanvas 130218 class_ref 128682 // DavixWebdavGate draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 201 331 2000 end classcanvas 130474 class_ref 128810 // DavixS3 draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 311 127 2000 end classcanvas 133162 class_ref 129066 // NeonBindings draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 728 240 2000 end classcanvas 133674 class_ref 129194 // DavixRequest draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 49 121 2000 end classcanvas 133802 class_ref 129322 // DavixHttpRequest draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 24 231 2005 end classcanvas 133930 class_ref 129450 // DavixWebdavRequest draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 24 324 2000 end classcanvas 134314 class_ref 129578 // NeonSessionFactory draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 712 306 2000 end classcanvas 134826 class_ref 129706 // MetaLinkBindings draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 716 369 2000 end classcanvas 137002 class_ref 129834 // DavixDavFileGate draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 386 67 2000 end classcanvas 138154 class_ref 129962 // DavixRequestStatus draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 30 404 2000 end classcanvas 138282 class_ref 130090 // DavixRequestSeqStatus draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 19 499 2000 end classcanvas 138538 class_ref 130218 // XMLparser draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 729 429 2000 end classcanvas 138922 class_ref 130346 // DavixParameters draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 630 105 2000 end classcanvas 139562 class_ref 130474 // DavixDavRequestStatus draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 18 562 2005 end relationcanvas 129962 relation_ref 128682 // from ref 129834 z 2001 to ref 128938 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 130602 relation_ref 128938 // from ref 130474 z 2001 to point 313 121 line 136106 z 2001 to point 255 121 line 135978 z 2001 to ref 128938 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 131370 relation_ref 129322 // decenter_end 426 from ref 128042 z 2001 to point 369 184 line 132394 z 2001 to point 336 184 line 137898 z 2001 to ref 130474 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 131498 relation_ref 129450 // decenter_end 554 from ref 128042 z 2001 to point 260 184 line 132266 z 2001 to ref 129834 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 132010 relation_ref 129706 // from ref 128042 z 2001 to point 434 184 line 132138 z 2001 to point 433 348 line 132906 z 2001 to ref 130218 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 133034 relation_ref 129834 // from ref 130218 z 2001 to point 255 320 line 137130 z 2001 to ref 129834 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 134186 relation_ref 130090 // from ref 128042 z 2001 to ref 128170 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 134442 relation_ref 130218 // from ref 128170 z 2001 to point 694 256 line 134954 z 2001 to ref 133162 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 134570 relation_ref 130346 // from ref 134314 z 2001 to point 694 324 line 134698 z 2001 to ref 128170 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 135082 relation_ref 130474 // from ref 128170 z 2001 to point 694 383 line 135210 z 2001 to ref 134826 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 136234 relation_ref 130730 // from ref 133802 z 2006 to ref 133674 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 136362 relation_ref 130858 // from ref 133930 z 2006 to ref 133802 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 136618 relation_ref 130986 // from ref 129834 z 2006 to point 93 220 line 136746 z 2006 to ref 133802 no_role_a no_role_b multiplicity_a_pos 80 209 3000 multiplicity_b_pos 189 230 3000 end relationcanvas 137386 relation_ref 131242 // decenter_end 478 from ref 128042 z 2001 to point 453 183 line 137514 z 2001 to point 438 185 line 138026 z 2001 to ref 137002 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 137642 relation_ref 131370 // decenter_begin 208 from ref 137002 z 2001 to point 382 88 line 137770 z 2001 to ref 128938 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 138666 relation_ref 131626 // from ref 128170 z 2001 to point 694 446 line 138794 z 2001 to ref 138538 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 139050 relation_ref 131754 // from ref 138922 z 2001 to point 618 148 line 140458 z 2001 to ref 128042 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 139690 relation_ref 132010 // from ref 133930 z 2006 to point 3 353 line 139818 z 2006 to point 4 568 line 139946 z 2006 to ref 139562 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 140202 relation_ref 138538 // from ref 138282 z 2001 to ref 138154 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end relationcanvas 140330 relation_ref 138666 // from ref 139562 z 2006 to ref 138282 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end end davix-R_0_5_0/doc/UML/davix/134698.diagram000066400000000000000000000032711257152637300177110ustar00rootroot00000000000000format 74 classcanvas 128042 class_ref 128042 // DavixContext draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 540 213 2000 end classcanvas 128170 class_ref 137002 // DavixFileObject draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 279 185 2000 end relationcanvas 128298 relation_ref 145194 // decenter_end 575 from ref 128042 z 2001 to ref 128170 no_role_a no_role_b no_multiplicity_a no_multiplicity_b end end davix-R_0_5_0/doc/UML/davix/134826.diagram000066400000000000000000000014151257152637300177000ustar00rootroot00000000000000format 74 classcanvas 128042 class_ref 137130 // RequestParameters draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default xyz 302 189 2000 end end davix-R_0_5_0/doc/UML/davix/42.session000066400000000000000000000010261257152637300174330ustar00rootroot00000000000000window_sizes 1600 844 677 917 674 96 diagrams active classdiagram_ref 128170 // class diagram davix 919 650 100 4 24 0 classdiagram_ref 134698 // DavixFileAPI 735 539 100 4 0 0 classdiagram_ref 134826 // RequestParameters 733 539 100 4 0 0 end show_stereotypes selected class_ref 129962 // DavixRequestStatus open class_ref 128042 // DavixContext class_ref 129322 // DavixHttpRequest class_ref 129450 // DavixWebdavRequest class_ref 137002 // DavixFileObject class_ref 137130 // RequestParameters end end davix-R_0_5_0/doc/UML/davix/cpp_includes000066400000000000000000000003441257152637300201760ustar00rootroot00000000000000// "a type" "needed cpp_includes" "vector" "#include using namespace std;" "list" "#include using namespace std;" "map" "#include using namespace std;" "string" "#include using namespace std;" davix-R_0_5_0/doc/UML/davix/davix.prj000066400000000000000000001176231257152637300174440ustar00rootroot00000000000000format 74 "davix" revision 5 modified_by 42 "didi" // class settings default_attribute_visibility private default_relation_visibility private default_operation_visibility public //class diagram settings draw_all_relations yes hide_attributes no hide_operations no hide_getset_operations no show_members_full_definition no show_members_visibility no show_members_stereotype no show_members_context no show_members_multiplicity no show_members_initialization no show_attribute_modifiers no member_max_width 127 show_parameter_dir yes show_parameter_name yes package_name_in_tab no class_drawing_mode natural drawing_language uml show_context_mode no auto_label_position yes show_relation_modifiers no show_relation_visibility no show_infonote no shadow yes show_stereotype_properties no //use case diagram settings package_name_in_tab no show_context no auto_label_position yes draw_all_relations yes class_drawing_mode actor shadow yes show_stereotype_properties no //sequence diagram settings show_full_operations_definition no write_horizontally yes class_drawing_mode natural drawing_language uml draw_all_relations yes shadow yes show_stereotype_properties no show_class_context_mode no show_msg_context_mode no //collaboration diagram settings show_full_operations_definition no show_hierarchical_rank no write_horizontally yes drawing_language uml package_name_in_tab no show_context no show_msg_context no draw_all_relations yes shadow yes show_stereotype_properties no //object diagram settings write_horizontally yes package_name_in_tab no show_context no auto_label_position yes draw_all_relations yes shadow yes show_stereotype_properties no //component diagram settings package_name_in_tab no show_context no auto_label_position yes draw_all_relations yes shadow yes draw_component_as_icon no show_component_req_prov no show_component_rea no show_stereotype_properties no //deployment diagram settings package_name_in_tab no show_context no write_horizontally yes auto_label_position yes draw_all_relations yes shadow yes draw_component_as_icon no show_component_req_prov no show_component_rea no show_stereotype_properties no //state diagram settings package_name_in_tab no show_context no auto_label_position yes write_trans_label_horizontally yes show_trans_definition no draw_all_relations yes shadow yes show_activities yes region_horizontally yes drawing_language uml show_stereotype_properties no //activity diagram settings package_name_in_tab no show_context no show_opaque_action_definition no auto_label_position yes write_flow_label_horizontally no draw_all_relations yes shadow yes show_infonote yes drawing_language uml show_stereotype_properties no class_color yellow duration_color transparent continuation_color gray note_color blue fragment_color transparent subject_color transparent usecase_color yellow package_color transparent component_color green artifact_color green deploymentnode_color gray state_color yellow stateaction_color transparent activity_color transparent activityregion_color transparent activitypartition_color transparent activityaction_color transparent parameterpin_color white font_size 9 diagram_format A4 mark_for_import classview 128042 "davix" //class diagram settings draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default //collaboration diagram settings show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default show_msg_context default draw_all_relations default shadow default show_stereotype_properties default //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default //sequence diagram settings show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default show_class_context_mode default show_msg_context_mode default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default show_stereotype_properties default //class settings //activity diagram settings package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default show_infonote default drawing_language default show_stereotype_properties default classdiagram 128170 "class diagram davix" draw_all_relations no hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default size A4 end class 128042 "DavixContext" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" operation 128042 "clone" public explicit_return_type "" nparams 1 param out name "" type class_ref 128042 // DavixContext cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end classrelation 128042 // relation 128042 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 128042 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 128170 // end classrelation 128298 // relation 128170 o--- a role_name "" multiplicity "*" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 128298 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 128426 // end classrelation 128554 // relation 128298 o--> a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 128554 // b parent class_ref 128170 // DavixInternalContext end attribute 128042 "internal_context" private type class_ref 128170 // DavixInternalContext cpp_decl " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " java_decl "" php_decl "" python_decl "" idl_decl "" end classrelation 129450 // relation 129194 -_-> a default cpp default "#include in source" classrelation_ref 129450 // b parent class_ref 128298 // DavixGate end classrelation 129578 // relation 129322 *--> a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 129578 // b parent class_ref 128810 // DavixS3 end classrelation 129706 // relation 129450 *--> a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 129706 // b parent class_ref 128554 // DavixHttpGate end classrelation 129834 // relation 129578 *--- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 129834 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 129962 // end classrelation 130090 // relation 129706 *--> a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 130090 // b parent class_ref 128682 // DavixWebdavGate end classrelation 130474 // relation 130090 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 130474 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 130602 // end classrelation 132266 // relation 131242 *--- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 132266 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 132394 // end classrelation 133162 // relation_ref 131754 // end operation 142250 "CreateFileObject" public explicit_return_type "" nparams 1 param in name "Uri" explicit_type "DavixUri" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}const ${t0} & ${p0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}const ${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end classrelation 146858 // relation 145194 o--- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 146858 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 146986 // end end class 128170 "DavixInternalContext" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 128170 // relation_ref 128042 // end classrelation 128426 // relation_ref 128170 // end classrelation 130602 // relation_ref 130090 // end classrelation 130730 // relation 130218 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 130730 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 130858 // end classrelation 131114 // relation_ref 130346 // end classrelation 131242 // relation 130474 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 131242 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 131370 // end classrelation 132778 // relation 131626 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 132778 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 132906 // end end class 128298 "DavixGate" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 130346 // relation 129962 -_-|> a public cpp default "${type}" classrelation_ref 130346 // b parent class_ref 128042 // DavixContext end classrelation 131498 // relation 130602 -_-> a default cpp default "#include in source" classrelation_ref 131498 // b parent class_ref 128042 // DavixContext end end class 128554 "DavixHttpGate" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 128938 // relation 128682 ---|> a public cpp default "${type}" classrelation_ref 128938 // b parent class_ref 128298 // DavixGate end operation 128170 "createRequest" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end classrelation 131882 // relation 130986 o--- a role_name "" multiplicity "*" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 131882 // b role_name "" multiplicity "1" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 132010 // end end class 128682 "DavixWebdavGate" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 129322 // relation 129066 ---|> a public cpp default "${type}" classrelation_ref 129322 // b parent class_ref 128298 // DavixGate end classrelation 129962 // relation_ref 129578 // end classrelation 130218 // relation 129834 ---|> a public cpp default "${type}" classrelation_ref 130218 // b parent class_ref 128554 // DavixHttpGate end operation 128298 "createRequest" public return_type class_ref 129450 // DavixWebdavRequest nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end end class 128810 "DavixS3" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 129194 // relation 128938 ---|> a public cpp default "${type}" classrelation_ref 129194 // b parent class_ref 128298 // DavixGate end end class 128938 "DavixGateFile" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" end class 129066 "NeonBindings" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 130858 // relation_ref 130218 // end end class 129194 "DavixRequest" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" attribute 128298 "context" private explicit_type "DavixContextInterface" cpp_decl " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " java_decl "" php_decl "" python_decl "" idl_decl "" end end class 129322 "DavixHttpRequest" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 131626 // relation 130730 ---|> a public cpp default "${type}" classrelation_ref 131626 // b parent class_ref 129194 // DavixRequest end classrelation 132010 // relation_ref 130986 // end classrelation 133290 // relation 131882 o--- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 133290 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 133418 // end operation 135338 "executeRequestHttp" public explicit_return_type "" nparams 1 param out name "" explicit_type "DavixRequestHttpStatus" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 135594 "executeRequestHttpSeq" public explicit_return_type "" nparams 1 param out name "" explicit_type "StatusRequestHttpSeq" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end end class 129450 "DavixWebdavRequest" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 131754 // relation 130858 ---|> a public cpp default "${type}" classrelation_ref 131754 // b parent class_ref 129322 // DavixHttpRequest end classrelation 133546 // relation 132010 o--- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 133546 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 133674 // end operation 135466 "executeRequestDav" public explicit_return_type "" nparams 1 param out name "" explicit_type "RequestDavStatus" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 135722 "executeRequestDavSeq" public explicit_return_type "" nparams 1 param out name "" explicit_type "ExecuteRequestDavSeq" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end end class 129578 "NeonSessionFactory" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 130986 // relation 130346 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 130986 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 131114 // end end class 129706 "MetaLinkBindings" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 131370 // relation_ref 130474 // end end class 129834 "DavixDavFileGate" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 132138 // relation 131114 ---|> a public cpp default "${type}" classrelation_ref 132138 // b parent class_ref 128682 // DavixWebdavGate end classrelation 132394 // relation_ref 131242 // end classrelation 132522 // relation 131370 ---|> a public cpp default "${type}" classrelation_ref 132522 // b parent class_ref 128298 // DavixGate end operation 128426 "stat" public explicit_return_type "" nparams 1 param in name "st" explicit_type "struct stat" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}const ${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}const ${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 128554 "opendir" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 128682 "readdir" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 128810 "closedir" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end end class 129962 "DavixRequestStatus" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 133418 // relation_ref 131882 // end end class 130090 "DavixRequestSeqStatus" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 140202 // relation 138538 ---|> a public cpp default "${type}" classrelation_ref 140202 // b parent class_ref 129962 // DavixRequestStatus end end class 130218 "XMLparser" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 132906 // relation_ref 131626 // end end class 130346 "DavixParameters" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 133034 // relation 131754 ---- a role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 133034 // b role_name "" private cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 133162 // end end class 130474 "DavixDavRequestStatus" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" classrelation 133674 // relation_ref 132010 // end classrelation 140330 // relation 138666 ---|> a public cpp default "${type}" classrelation_ref 140330 // b parent class_ref 130090 // DavixRequestSeqStatus end end end package_ref 128170 // davix_core classview 134826 "DavixFileAPI" //class diagram settings draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default //collaboration diagram settings show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default show_msg_context default draw_all_relations default shadow default show_stereotype_properties default //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default //sequence diagram settings show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default show_class_context_mode default show_msg_context_mode default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default show_stereotype_properties default //class settings //activity diagram settings package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default show_infonote default drawing_language default show_stereotype_properties default classdiagram 134698 "DavixFileAPI" draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default size A4 end class 137002 "DavixFileObject" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" operation 142378 "open" public explicit_return_type "" nparams 3 param in name "mode" explicit_type "Mode_t" param in name "parameters" explicit_type "DavixRequestParams*" defaultvalue "NULL" param in name "status" explicit_type "DavixOperationStatus*" defaultvalue "NULL" cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}const ${t0} & ${p0}, const ${t1} & ${p1}, const ${t2} & ${p2}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}const ${t0} & ${p0}, const ${t1} & ${p1}, const ${t2} & ${p2}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 142506 "read" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 142634 "write" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 142762 "close" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 143146 "stat" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 143274 "isOpen" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end classrelation 146986 // relation_ref 145194 // end operation 143530 "pread" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 143658 "pwrite" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 143786 "clone" public explicit_return_type "" nparams 1 param out name "clone" type class_ref 137002 // DavixFileObject cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${t0} & ${p0}${v0}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${t0} & ${p0}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end attribute 134826 "uri" private explicit_type "" cpp_decl " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " java_decl "" php_decl "" python_decl "" idl_decl "" end operation 143914 "exist" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 144042 "copy" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 144170 "delete" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 144298 "setProperties" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 144426 "getProperties" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 144554 "vread" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end operation 144682 "vwrite" public explicit_return_type "" nparams 0 cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_def "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " end end end classview 134954 "DavixRequestParameters" //class diagram settings draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default //collaboration diagram settings show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default show_msg_context default draw_all_relations default shadow default show_stereotype_properties default //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default //sequence diagram settings show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default show_class_context_mode default show_msg_context_mode default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default show_stereotype_properties default //class settings //activity diagram settings package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default show_infonote default drawing_language default show_stereotype_properties default classdiagram 134826 "RequestParameters" draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_context default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default size A4 end class 137130 "RequestParameters" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " java_decl "" php_decl "" python_2_2 python_decl "" idl_decl "" explicit_switch_type "" end end end davix-R_0_5_0/doc/UML/davix/generation_settings000066400000000000000000000306371257152637300216110ustar00rootroot00000000000000 cpp_default_defs cpp_h_extension "h" cpp_src_extension "cpp" java_extension "java" php_extension "php" python_extension "py" idl_extension "idl" cpp_inline_dont_force_incl_in_h type_forms 15 // uml cpp java idl cpp_in cpp_out cpp_inout cpp_return "void" "void" "void" "void" "${type}" "${type} &" "${type}" "${type}" "any" "void *" "Object" "any" "const ${type}" "${type}" "${type} &" "${type}" "bool" "bool" "boolean" "boolean" "${type}" "${type} &" "${type} &" "${type}" "char" "char" "char" "char" "${type}" "${type} &" "${type} &" "${type}" "uchar" "unsigned char" "char" "octet" "${type}" "${type} &" "${type} &" "${type}" "byte" "unsigned char" "byte" "octet" "${type}" "${type} &" "${type} &" "${type}" "short" "short" "short" "short" "${type}" "${type} &" "${type} &" "${type}" "ushort" "unsigned short" "short" "unsigned short" "${type}" "${type} &" "${type} &" "${type}" "int" "int" "int" "long" "${type}" "${type} &" "${type} &" "${type}" "uint" "unsigned int" "int" "unsigned long" "${type}" "${type} &" "${type} &" "${type}" "long" "long" "long" "long" "${type}" "${type} &" "${type} &" "${type}" "ulong" "unsigned long" "long" "unsigned long" "${type}" "${type} &" "${type} &" "${type}" "float" "float" "float" "float" "${type}" "${type} &" "${type} &" "${type}" "double" "double" "double" "double" "${type}" "${type} &" "${type} &" "${type}" "string" "string" "String" "string" "${type}" "${type} &" "${type} &" "${type}" relations_stereotypes 5 // uml cpp java pythonidl "sequence" "vector" "Vector" "list" "sequence" "vector" "vector" "Vector" "list" "sequence" "list" "list" "List" "list" "sequence" "set" "set" "Set" "set" "sequence" "map" "map" "Map" "dict" "sequence" classes_stereotypes 14 // uml cpp java php python idl "class" "class" "class" "class" "class" "valuetype" "interface" "class" "interface" "interface" "class" "interface" "exception" "class" "class" "class" "class" "exception" "enum" "enum" "enum" "enum" "enum" "enum" "enum_pattern" "enum" "enum_pattern" "enum" "enum" "enum" "struct" "struct" "class" "class" "class" "struct" "union" "union" "class" "class" "class" "union" "typedef" "typedef" "ignored" "ignored" "ignored" "typedef" "boundary" "class" "class" "class" "class" "interface" "control" "class" "class" "class" "class" "valuetype" "entity" "class" "class" "class" "class" "valuetype" "actor" "ignored" "ignored" "ignored" "ignored" "ignored" "@interface" "ignored" "@interface" "ignored" "ignored" "ignored" "stereotype" "ignored" "ignored" "ignored" "ignored" "ignored" cpp_enum_default_type_forms "${type}" "${type} &" "${type} &" "${type}" // in out inout return other_cpp_types_default_type_forms "const ${type} &" "${type} &" "${type} &" "${type}" // in out inout return cpp_default_h_content "#ifndef ${NAMESPACE}_${NAME}_H #define ${NAMESPACE}_${NAME}_H ${comment} ${includes} ${declarations} ${namespace_start} ${definition} ${namespace_end} #endif " cpp_default_src_content "${comment} ${includes} ${namespace_start} ${members} ${namespace_end}" cpp_default_class_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " cpp_default_external_class_decl "${name} #include <${name}.h> " cpp_default_struct_decl "${comment}${template}struct ${name}${inherit} { ${members}}; ${inlines} " cpp_default_union_decl "${comment}${template}union ${name} { ${members}}; ${inlines} " cpp_default_enum_decl "${comment}enum ${name} { ${items} }; " cpp_default_typedef_decl "${comment}typedef ${type} ${name}; " cpp_default_attribute_declaration " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " // multiplicity 1 " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value}; " // multiplicity * a..b " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${multiplicity}${value}; " // multiplicity [..] cpp_default_enum_item_declaration " ${name}${value},${comment}" cpp_association_aggregation_declaration " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " // multiplicity 1 " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type} *> ${name}${value}; " // multiplicity * a..b " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${multiplicity}${value}; " // multiplicity [..] cpp_aggregation_by_value_declaration " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " // multiplicity 1 " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value}; " // multiplicity * a..b " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${multiplicity}${value}; " // multiplicity [..] cpp_get "get_${name}" inline const value_const public cpp_set "set_${name}" public cpp_default_operation_declaration " ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract}; " cpp_default_operation_definition "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{ ${body}} " java_default_src_content "${comment} ${package} ${imports} ${definition}" java_default_class_decl "${comment}${@}${visibility}${final}${abstract}class ${name}${extends}${implements} { ${members}} " java_default_external_class_decl "${name}" java_default_interface_decl "${comment}${@}${visibility}interface ${name}${extends} { ${members}} " java5_default_enum_decl "${comment}${@}${visibility}${final}${abstract}enum ${name}${implements} { ${items}; ${members}} " java_default_enum_decl "${comment}${@}${visibility}final class ${name} { ${members} private final int value; public int value() { return value; } public static ${name} fromInt(int value) { switch (value) { ${cases} default: throw new Error(); } } private ${name}(int v) { value = v; }; } " java_default_attribute_declaration " ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type} ${name}${value}; " // multiplicity 1 " ${comment}${@}${visibility}${static}${final}${transient}${volatile}${stereotype}<${type}> ${name}${value}; " // multiplicity * a..b " ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type}${multiplicity} ${name}${value}; " // multiplicity N java5_default_enum_item_declaration " ${@}${name}${value},${comment}" java_default_enum_item_declaration " ${comment}${@}public static final int _${name}${value}; public static final ${class} ${name} = new ${class}(_${name}); " java_default_enum_case " case _${name}: return ${name}; " java_association_aggregation_declaration " ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type} ${name}${value}; " // multiplicity 1 " ${comment}${@}${visibility}${static}${final}${transient}${volatile}${stereotype}<${type}> ${name}${value}; " // multiplicity * a..b " ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type}${multiplicity} ${name}${value}; " // multiplicity N java_get "get${Name}" final public java_set "set${Name}" public java_default_operation_definition " ${comment}${@}${visibility}${final}${static}${abstract}${synchronized}${type} ${name}${(}${)}${throws}${staticnl}{ ${body}} " php_default_src_content " " php_default_class_decl "${comment}${final}${visibility}${abstract}class ${name}${extends}${implements} { ${members}} " php_default_enum_decl "${comment}${visibility}final class ${name} { ${items}} " php_default_external_class_decl "${name}" php_default_interface_decl "${comment}${visibility}interface ${name} { ${members}} " php_default_attribute_declaration " ${comment}${visibility}${const}${static}${var}${name}${value}; " php_default_enum_item_decl " const ${name}${value};${comment} " php_default_relation_declaration" ${comment}${visibility}${const}${static}${var}${name}${value}; " php_get "get${Name}" final php_set "set${Name}" php_default_operation_definition " ${comment}${final}${visibility}${abstract}${static}function ${name}${(}${)} { ${body}} " python_2_2 python_indent_step " " python_default_src_content "${comment} ${import} ${definition}" python_default_class_decl "class ${name}${inherit}: ${docstring}${members} " python_default_enum_decl "class ${name}: ${docstring}${members} " python_default_external_class_decl "${name}" python_default_attribute_declaration "${comment}${self}${name} = ${value} " // multiplicity 1 "${comment}${self}${name} = ${stereotype}() " // multiplicity != 1 python_default_enum_item_decl "${comment}${self}${name} = ${value} " python_default_relation_declaration"${comment}${self}${name} = ${value} " // multiplicity 1 "${comment}${self}${name} = ${stereotype}() " // multiplicity != 1 python_default_composition_declaration"${comment}${self}${name} = ${type}() " // multiplicity 1 "${comment}${self}${name} = ${stereotype}() " // multiplicity != 1 python_default_operation_definition "${@}${static}${abstract}def ${name}${(}${)}: ${docstring}${body} " python_default_initoperation_definition "${@}${static}${abstract}def ${name}${(}${p0}${v0}${)}: ${docstring}super(${class}, ${p0}).__init__() ${body} " python_get "get${Name}" python_set "set${Name}" idl_default_src_content "#ifndef ${MODULE}_${NAME}_H #define ${MODULE}_${NAME}_H ${comment} ${includes} ${module_start} ${definition} ${module_end} #endif " idl_default_interface_decl "${comment}${abstract}${local}interface ${name}${inherit} { ${members}}; " idl_default_valuetype_decl "${comment}${abstract}${custom}valuetype ${name}${inherit} { ${members}}; " idl_default_struct_decl "${comment}struct ${name} { ${members}}; " idl_default_typedef_decl "${comment}typedef ${type} ${name}; " idl_default_exception_decl "${comment}exception ${name} { ${members}}; " idl_default_union_decl "${comment}union ${name} switch(${switch}) { ${members}}; " idl_default_enum_decl "${comment}enum ${name} { ${items}}; " idl_default_external_class_decl "${name} #include \"${name}.idl\" " idl_default_attribute_declaration " ${comment}${readonly}${attribute}${type} ${name}; " // multiplicity 1 " ${comment}${readonly}${attribute}${stereotype}<${type}> ${name}; " // multiplicity * a..b " ${comment}${readonly}${attribute}${stereotype}<${type},${multiplicity}> ${name}; " // multiplicity N idl_default_valuetype_attribute_declaration " ${comment}${visibility}${type} ${name}; " // multiplicity 1 " ${comment}${visibility}${stereotype}<${type}> ${name}; " // multiplicity * a..b " ${comment}${visibility}${stereotype}<${type},${multiplicity}> ${name}; " // multiplicity N idl_default_const_declaration " ${comment}const ${type} ${name}${value}; " // multiplicity 1 " ${comment}const ${stereotype}<${type}> ${name}${value}; " // multiplicity * a..b " ${comment}const ${stereotype}<${type},${multiplicity}> ${name}${value}; " // multiplicity N idl_default_enum_item_declaration " ${name},${comment}" idl_default_union_item_declaration " ${comment}case ${case} : ${readonly}${type} ${name};" // multiplicity 1 " ${comment}case ${case} : ${readonly}${stereotype}<${type}> ${name};" // multiplicity * a..b " ${comment}case ${case} : ${readonly}${stereotype}<${type},${multiplicity}> ${name};" // multiplicity N idl_association_aggregation_declaration " ${comment}${readonly}${attribute}${type} ${name}; " // multiplicity 1 " ${comment}${readonly}${attribute}${stereotype}<${type}> ${name}; " // multiplicity * a..b " ${comment}${readonly}${attribute}${stereotype}<${type},${multiplicity}> ${name}; " // multiplicity N idl_valuetype_association_aggregation_declaration " ${comment}${visibility}${type} ${name}; " // multiplicity 1 " ${comment}${visibility}${stereotype}<${type}> ${name}; " // multiplicity * a..b " ${comment}${visibility}${stereotype}<${type},${multiplicity}> ${name}; " // multiplicity N idl_union_association_aggregation_declaration " ${comment}case ${case} : ${readonly}${type} ${name};" // multiplicity 1 " ${comment}case ${case} : ${readonly}${stereotype}<${type}> ${name};" // multiplicity * a..b " ${comment}case ${case} : ${readonly}${stereotype}<${type},${multiplicity}> ${name};" // multiplicity N idl_get "get_${name}" idl_set "set_${name}" twoways idl_default_operation_declaration " ${comment}${oneway}${type} ${name}${(}${)}${raisesnl}${raises}; " uml_get_name uml uml_set_name uml end davix-R_0_5_0/doc/UML/davix/idl_includes000066400000000000000000000000421257152637300201570ustar00rootroot00000000000000// "a type" "needed idl_includes" davix-R_0_5_0/doc/UML/davix/java_imports000066400000000000000000000000421257152637300202170ustar00rootroot00000000000000// "a type" "needed java_imports" davix-R_0_5_0/doc/UML/davix/python_imports000066400000000000000000000000441257152637300206210ustar00rootroot00000000000000// "a type" "needed python_imports" davix-R_0_5_0/doc/UML/davix/stereotypes000066400000000000000000000044111257152637300201130ustar00rootroot00000000000000 package_stereotypes 6 "facade" "framework" "model library" "stub" "toplevel" "profile" -_-> 3 "access" "import" "from" end class_stereotypes 19 "actor" "auxiliary" "boundary" "control" "entity" "enum" "enum_pattern" "exception" "focus" "implementationClass" "interface" "@interface" "metaclass" "stereotype" "struct" "type" "typedef" "union" "utility" ---- 4 "list" "set" "vector" "map" ---> 4 "list" "set" "vector" "map" ---|> 4 "{complete,disjoint}" "{incomplete,disjoint}" "{complete,overlapping}" "{incomplete,overlapping}" o--- 4 "list" "set" "vector" "map" *--- 4 "list" "set" "vector" "map" o--> 4 "list" "set" "vector" "map" *--> 4 "list" "set" "vector" "map" -_-> 4 "friend" "from" "import" "instantiate" -_-|> 1 "bind" end use_case_stereotypes 1 "realization" ---|> 4 "{complete,disjoint}" "{incomplete,disjoint}" "{complete,overlapping}" "{incomplete,overlapping}" -_-> 2 "include" "extend" end artifact_stereotypes 7 "document" "file" "script" "source" "text" "library" "executable" -_-> 4 "deploy" "manifest" "import" "from" end attribute_stereotypes 4 "list" "set" "vector" "map" operation_stereotypes 0 state_stereotypes 3 "machine" "submachine" "top" activity_stereotypes 0 flow_stereotypes 3 "interrupt" "multicast" "multireceive" interruptibleactivityregion_stereotypes 0 pseudostate_stereotypes 0 stateaction_stereotypes 2 "send-signal" "receive-signal" parameter_stereotypes 0 parameterset_stereotypes 0 activitynode_stereotypes 0 activityaction_stereotypes 0 activityobject_stereotypes 2 "datastore" "centralBuffer" expansionregion_stereotypes 0 activitypartition_stereotypes 0 pin_stereotypes 0 component_stereotypes 6 "buildComponent" "entity" "implement" "process" "service" "subsystem" deploymentnode_stereotypes 3 "cpu" "device" "executionEnvironment" classview_stereotypes 0 usecaseview_stereotypes 0 componentview_stereotypes 0 deploymentview_stereotypes 0 classdiagram_stereotypes 0 seqdiagram_stereotypes 0 msg_stereotypes 0 coldiagram_stereotypes 0 usecasediagram_stereotypes 0 statediagram_stereotypes 0 activitydiagram_stereotypes 0 componentdiagram_stereotypes 0 deploymentdiagram_stereotypes 0 end davix-R_0_5_0/doc/UML/davix/tools000066400000000000000000000104421257152637300166660ustar00rootroot00000000000000// 'tool' "the executable" "displayed string" {target}+ tool "HTML documentation" "ghtml" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn tool "HTML doc. (flat)" "ghtml -flat" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn tool "HTML doc. (svg)" "ghtml -svg" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn tool "HTML doc. (flat, svg)" "ghtml -flat -svg" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn tool "Generate .pro" "gpro" Artifact tool "Import Rose" "irose" Project Package tool "C++ utilities" "cpp_util" Class tool "Generate XMI 1.2" "gxmi" Project tool "Generate XMI 2.1" "gxmi2" Project tool "Import XMI 2.1" "ixmi2" Project Package tool "C++ state machine" "stmgen" State tool "Use case wizard" "usecasewizard" UseCase tool "Check-in" "file_control ci" Project Package tool "Check-out" "file_control co" Project Package tool "Deploy classes" "deplcl" ClassView tool "Global Change" "global_change" Class Project Package ClassView DeploymentView tool "Uml projection" "uml_proj" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue Project Package ClassView davix-R_0_5_0/doc/man/000077500000000000000000000000001257152637300146055ustar00rootroot00000000000000davix-R_0_5_0/doc/man/davix-get.1000066400000000000000000000071771257152637300165730ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-get.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-GET 1 "$Date: 2014/05/24 $" davix "download tool" .SH NAME davix-get \- Download tool based on libdavix .SH SYNOPSIS .PP davix-get [options]... url davix-get [options]... url local_file .PP .SH DESCRIPTION \fBdavix-get\fR is a tool to download resources from HTTP, Webdav or REST compatible services. .br The command supports the protocol Http (http(s)://), WebDav (dav(s)://) and S3 (s3(s)://). .br .PP Target resources can either be a single file or a collection. .br In the case of collection, all sub-collections will also be downloaded. .br .PP davix-get is powered by libdavix. See libdavix(3) for details. .br .SH OPTIONS .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and Davix command line tools info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_PATH\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E CRED_PATH\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP \fBDownload content and print it on stdout .BR davix-get http://example.org/dir1/dir2/file1 .BR .PP \fBDownload content to a local file .BR davix-get s3://bucket.example.org/collection/file2 /tmp/file2 .BR .PP \fBDownload content to a local file with VOMS authentication in a Grid environment .BR davix-get -P grid davs://grid-storage.example.org/dir1/file1 /tmp/file1 \fBDownload content and print it to stdout, using a OAuth token .BR davix-get https://example.org/dir1/tmpfile -H "Authorization: Bearer mytoken" .BR .PP \fBDownload collection to a local directory .BR davix-get dav://example.org/dir ./mydir .BR .SH SEE ALSO .BR libdavix(3), davix-get(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/davix-http.1000066400000000000000000000063441257152637300167660ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-http.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-HTTP 1 "$Date: 2014/05/24 $" davix "HTTP Request tool" .SH NAME davix-http \- HTTP query tool based on libdavix .SH SYNOPSIS .PP davix-http [options]... url .PP .SH DESCRIPTION \fBdavix-http\fR is a tool using libdavix for HTTP query executions .br It can be used to interact with a RESTful webservices. .br .PP See libdavix(3) for details. .br .SH OPTIONS .PP \fBRequest Options:\fR .PP .RS 2 \fB\--data\fR .RE .RS 5 Content of the request .RE .PP .RS 2 \fB\--request, -X\fR .RE .RS 5 Request method to use (ex : GET, PUT, PROPFIND, etc..) .RE .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and misc info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_path\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E cred_path\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP \fB Execute a GET Query in HTTP .BR davix-http http://example.org/ .PP \fB Execute a HEAD Query in HTTP + TLS with User auth .BR davix-http -X HEAD https://login:password@example.org .BR .PP \fB Execute a PUT Query with S3 over https and a basic content .BR davix-http -X PUT s3s://bucket.example.org/mifile -d "Hello World" .BR .SH SEE ALSO .BR libdavix(3), davix-ls(1), davix-get(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/davix-ls.1000066400000000000000000000070331257152637300164210ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-ls.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-LS 1 "$Date: 2014/05/24 $" davix "listing tool" .SH NAME davix-ls \- Listing tool based on libdavix .SH SYNOPSIS .PP davix-ls [options]... url .PP .SH DESCRIPTION \fBdavix-ls\fR is a tool to list resources in directories or collection with HTTP, Webdav or REST compatible services. .br The command supports the WebDav (dav(s)://) and S3 (s3(s)://). .br .PP davix-ls is powered by libdavix. See libdavix(3) for details. .br .SH OPTIONS .PP \fBListing Options:\fR .PP .RS 2 \fB\-l --long-list:\fR .RE .RS 5 long Listing mode .RE .PP .RS 2 \fB\--s3-listing:\fR .RE .RS 5 S3 bucket listing mode - flat, semi or hierarchical(default) .RE .PP .RS 2 \fB\--s3-maxkeys:\fR .RE .RS 5 Maximum number of entries returns by S3 list bucket request. default: 10000 .RE .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and Davix command line tools info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_path\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E cred_path\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP \fBWebDav directory file listing .BR davix-ls dav://example.org/dir1/dir2/ .BR .PP \fBAWS S3 bucket listing .BR davix-ls s3://bucket.example.org/collection/ .BR .PP \fBLong listing with WebDav with VOMS authentication in a Grid environment .BR davix-ls -P grid davs://grid-storage.example.org/dir1/dir2/ \fBLong listing with WebDav + TLS directory file listing .BR davix-ls -l davs://example.org/dir1/dir2/ .BR .SH SEE ALSO .BR libdavix(3), davix-get(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/davix-mkdir.1000066400000000000000000000061051257152637300171100ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-mkdir.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-MKDIR 1 "$Date: 2014/05/24 $" davix "listing tool" .SH NAME davix-mkdir \- Directory creation tool based on libdavix. .SH SYNOPSIS .PP davix-mkdir [options]... url .PP .SH DESCRIPTION \fBdavix-mkdir\fR is a tool to creat directories or collections with HTTP, Webdav or REST compatible services. .br The command supports the protocol Http (http(s)://), WebDav (dav(s)://) and S3 (s3(s)://). .br .PP davix-mkdir is powered by libdavix. See libdavix(3) for details. .br .SH OPTIONS .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and misc info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_path\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E cred_path\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP .BR .PP \fBCreat a directory over WebDav .BR davix-mkdir dav://webdav.example.org/dir/directory_to_create .BR .PP \fBCreat a directory on a Grid Storage with VOMS authentication .BR davix-mkdir -P grid davs://grid-storage.example.org/dir1/directory_to_create .BR .SH SEE ALSO .BR libdavix(3), davix-rm(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/davix-mv.1000066400000000000000000000061051257152637300164240ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-http.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-MV 1 "$Date: 2014/05/24 $" davix "listing tool" .SH NAME davix-mv \- Rename tool based on libdavix .SH SYNOPSIS .PP davix-mv [options]... original-url new-url .PP .SH DESCRIPTION \fBdavix-mv\fR is a tool to rename/move resources with HTTP, Webdav or REST compatible services. .br The commands can rename/move resources and resources containers. .br .PP davix-mv is powered by libdavix. See libdavix(3) for details. .br .SH OPTIONS .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and misc info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_path\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E cred_path\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP \fB Rename a resource over HTTP .BR davix-mv http://example.org/rename_me.txt http://example.org/thanks.txt .PP \fB Move a resource on a Grid Storage with VOMS authentication .BR davix-mv -P grid davs://grid-storage.example.org/dir1/dir2/move_me.txt davs://grid-storage.example.org/dir1/move_me.txt .BR .SH SEE ALSO .BR libdavix(3), davix-ls(1), davix-get(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/davix-put.1000066400000000000000000000066671257152637300166270ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-put.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-PUT 1 "$Date: 2014/05/24 $" davix "download tool" .SH NAME davix-put \- Upload tool based on libdavix .SH SYNOPSIS .PP davix-put [options]... local_file url .PP .SH DESCRIPTION \fBdavix-put\fR is a tool to upload resources to http, Webdav or REST compatible services. .br The command supports the protocol Http (http(s)://), WebDav (dav(s)://) and S3 (s3(s)://). .br .PP Local resources can either be a single file or a collection. .br In the case of collection, all sub-collections will also be uploaded. .br .PP davix-put is powered by libdavix. See libdavix(3) for details. .br .SH OPTIONS .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and Davix command line tools info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_path\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E cred_path\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP \fBUpload local file to a http server .BR davix-put /tmp/file1 http://example.org/dir1/dir2/file1 .BR .PP \fBUpload a local file to a Grid compatible storage .BR davix-put -P grid /tmp/file1 davs://grid-storage.example.org/dir1/file1 \fBUpload a resource to a OAuth 2.0 compatible service .BR davix-put /tmp/file https://example.org/dir1/tmpfile -H "Authorization: Bearer mytoken" .BR .PP \fBUpload local directory to a http server .BR davix-put mydir http://example.org/dir1 .BR .SH SEE ALSO .BR libdavix(3), davix-put(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/davix-rm.1000066400000000000000000000062201257152637300164160ustar00rootroot00000000000000.\" @(#)$RCSfile: davix-rm.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH DAVIX-RM 1 "$Date: 2014/05/24 $" davix "listing tool" .SH NAME davix-rm \- Deletion tool based on libdavix. .SH SYNOPSIS .PP davix-rm [options]... url .PP .SH DESCRIPTION \fBdavix-rm\fR is a tool to delete resources with HTTP, Webdav or REST compatible services. .br The commands can delete resources and resources containers. .br It supports the protocol Http (http(s)://), WebDav (dav(s)://) and S3 (s3(s)://). .br .PP davix-rm is powered by libdavix. See libdavix(3) for details. .br .SH OPTIONS .PP \fBCommon Options:\fR .PP .RS 2 \fB\--debug\fR .RE .RS 5 Debug mode .RE .PP .RS 2 \fB\--header, -H\fR .RE .RS 5 Add a header field to the request (eg: -H "Depth: 1" ) .RE .PP .RS 2 \fB\--help, -h\fR .RE .RS 5 Display this help message .RE .PP .RS 2 \fB\--metalink OPT \fR .RE .RS 5 Metalink support. (OPT=failover[default]|no) .RE .PP .RS 2 \fB\--module, -P PLUGIN_NAME\fR .RE .RS 5 Load a plugin or profile by name .RE .PP .RS 2 \fB\--redirection OPT \fR .RE .RS 5 Transparent redirection support. (OPT=yes[default]|no) .RE .PP .RS 2 \fB\--proxy, -x URL\fR .RE .RS 5 SOCKS5 proxy server URL. (ex: socks5://login:pass@socks.example.org) .RE .PP .RS 2 \fB\--trace\fR .RE .RS 5 Traces specific scope(s), options include: .RE .RS 8 file - Davix file interface .RE .RS 8 posix - Davix POSIX interface .RE .RS 8 xml - XML parser output .RE .RS 8 ssl - SSL and certs details .RE .RS 8 header - HTTP queries headers .RE .RS 8 body - HTTP bodies .RE .RS 8 chain - IO chains info .RE .RS 8 core - Config and misc info .RE .RS 8 grid - Misc info from 3rd parties .RE .RS 8 socket - Socket info .RE .RS 8 locks - WebDAV locking info .RE .RS 8 all - Traces everything .RE .PP .RS 2 \fB\--version\fR .RE .RS 5 Display version .RE .PP \fBSecurity Options:\fR .PP .RS 2 \fB\--capath CA_path\fR .RE .RS 5 Add an additional certificate authority directory .RE .PP .RS 2 \fB\--cert, -E cred_path\fR .RE .RS 5 Client Certificate in PEM format .RE .PP .RS 2 \fB\--key priv_path\fR .RE .RS 5 Private key in PEM format .RE .PP .RS 2 \fB\--insecure, -k\fR .RE .RS 5 Disable SSL credential checks .RE .PP .RS 2 \fB\--userlogin\fR .RE .RS 5 User login for login/password authentication .RE .PP .RS 2 \fB\--userpass\fR .RE .RS 5 User password for login/password authentication .RE .PP .RS 2 \fB\--s3secretkey\fR .RE .RS 5 AWS S3 authentication: secret key .RE .PP .RS 2 \fB\--s3accesskey\fR .RE .RS 5 AWS S3 authentication: access key .RE .PP .SH EXAMPLES .PP \fBDelete a file over http .BR davix-rm https://example.org/file1 .BR .PP \fBDelete a directory over WebDav .BR davix-rm dav://webdav.example.org/collection/collection_to_delete .BR .PP \fBDelete a resource on a Grid Storage with VOMS authentication .BR davix-rm -P grid davs://grid-storage.example.org/dir1/dir2/ .BR .SH SEE ALSO .BR libdavix(3), davix-mkdir(1), davix-put(1), .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/man/libdavix.3000066400000000000000000000015661257152637300165030ustar00rootroot00000000000000.\" @(#)$RCSfile: libdavix.man,v $ $Revision: 1 $ $Date: 2014/05/24 $ CERN Adrien Devresse .\" Copyright (C) 2014 by CERN .\" All rights reserved .\" .TH LIBDAVIX 3 "$Date: 2014/05/24 $" libdavix .SH NAME libdavix \- shared library for HTTP I/O .SH DESCRIPTION libdavix is a C++ shared library for high performance remote I/O and resources management with HTTP Based protocols. .br .PP libdavix aims to be a complete, reliable and performant I/O layer for Cloud, Grid and Web storage systems. .br It supports the protocol Http (http(s)://), WebDav (dav(s)://) and S3 (s3(s)://). .br .PP See libdavix doxygen documentation for more details. .PP .SH SEE ALSO .BR davix-get(1), davix-put(1), davix-mkdir(1), davix-rm(1), davix-ls(1) .BR .SH LINKS .BR http://dmc.web.cern.ch/projects/davix/home .SH AUTHORS Adrien Devresse , IT-SDC-ID, CERN davix-R_0_5_0/doc/src/000077500000000000000000000000001257152637300146215ustar00rootroot00000000000000davix-R_0_5_0/doc/src/example_code_snippets.cpp000066400000000000000000000453251257152637300217100ustar00rootroot00000000000000/* * Example code snippets */ //------------------------------------------------------------------------------------------------- // Davix::Uri //------------------------------------------------------------------------------------------------- //! [Uri example] Uri myuri("https://johnsmith:12345678@example.org:443/myfolder/myfile?type=personal#overthere"); cout << "Full uri: " << myuri.getString() << endl << "Port: " << myuri.getPort() << endl << "Protocol: " << myuri.getProtocol() << endl << "Host: " << myuri.getHost() << endl << "Path: " << myuri.getPath() << endl << "Query: " << myuri.getQuery() << endl << "Path and query: " << myuri.getPathAndQuery() << endl << "User info: " << myuri.getUserInfo() << endl; /* Output: Full uri: https://johnsmith:12345678@example.org:443/myfolder/myfile?type=personal#overthere Port: 443 Protocol: https Host: example.org Path: /myfolder/myfile Query: type=personal Path and query: /myfolder/myfile?type=personal User info: johnsmith:12345678 */ //! [Uri example] //------------------------------------------------------------------------------------------------- // Davix::DavFile //------------------------------------------------------------------------------------------------- //! [DavFile] Context c; DavFile file(c, Uri("http://example.org/dir1/file1")); //! [DavFile] //! [getReplicas] Context c; DavixError* err = NULL; DavFile file(c, Uri("http://example.org/dir1/file1")); std::vector resultVec; resultVec = file.getReplicas(NULL, &err); //! [getReplicas] //! [readPartialBufferVec] Context c; DavixError* err = NULL; DavFile file(c, Uri("http://example.org/dir1/file_to_read")); int number_of_vector = 2; DavIOVecInput input_vector[number_of_vector]; DavIOVecOutput output_vector[number_of_vector]; // Setup vector operations parameters char buf1[255] = {0}; char buf2[255] = {0}; input_vector[0].diov_offset = 100; input_vector[0].diov_size = 200; input_vector[0].diov_buffer = buf1; input_vector[1].diov_offset = 600; input_vector[1].diov_size = 150; input_vector[1].diov_buffer = buf2; // execute query file.readPartialBufferVec(NULL, input_vector, output_vector, number_of_vector, &err); std::cout << “Op 1 read ” << output_vector[0].diov_size << “bytes” << std::endl; std::cout << “Op 2 read ” << output_vector[1].diov_size << “bytes” << std::endl; // do things with content in output_vector[0].diov_buffer etc //! [readPartialBufferVec] //! [getToFd] Context c; DavixError* err = NULL; DavFile file(c, Uri("http://example.org/dir1/file_to_download")); int fd = open(“/tmp/local_file” O_WRONLY, O_CREAT); // get full file file.getToFd(NULL, fd, &err); //! [getToFd] //! [getToFd sized] Context c; DavixError* err = NULL; DavFile file(c, Uri("http://example.org/dir1/file_to_download")); int fd = open(“/tmp/local_file” O_WRONLY, O_CREAT); // get 200 bytes from file file.getToFd(NULL, fd, 200, &err); //! [getToFd sized] //! [readPartial] Context c; char buffer[255]; DavFile file(c, Uri(“http://example.org/dir1/file_to_download”)); // get 100 bytes from http://example.org/dir1/file_to_download at offset 200 file.readPartial(NULL, buffer, 100, 200); //! [readPartial] //! [getFull] Context c; DavixError* err = NULL; DavFile file(c, Uri(“http://example.org/file_to_download”)); std::vector buffer; // warning, this operation has no size limit regarding the content file.getFull(NULL, buffer, &err); // do things with buffer // ... //! [getFull] //! [get] Context c; DavixError* err = NULL; DavFile file(c, Uri(“http://example.org/file_to_download”)); std::vector buffer; // warning, this operation has no size limit regarding the content file.get(NULL, buffer); // do things with buffer // ... //! [get] //! [put fd] Context c; DavFile file(c, Uri(“http://example.org/file_to_create”)); int fd = open(“/tmp/file_to_upload”, O_RDONLY); // get file size struct stat st; fstat(fd, &st); // execute put file.put(NULL, fd, static_cast(st.st_size)); //! [put fd] //! [put buffer] Context c; DavFile file(c, Uri(“http://example.org/file_to_create”)); char buffer[255]; // fills buffer with something useful // execute put file.put(NULL, &buffer, static_castsizeof(buffer)); //! [put buffer] //! [put callback] // data provider int myDataProvider(void* buffer, dav_size_t max_size){ static dav_size_t content_size = 200; if(max_size == 0) return 0; else{ char my_useful_content[255]={1}; int bytes_to_write = (max_sized_name << std::endl; } pos.closedir(fd, &err); //! [opendir] //! [opendirpp] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_DIR* fd; struct dirent* entry; struct stat info; fd = posix.opendirpp(NULL, "dav://example.org/collection_to_open", &err); while(entry = pos.readdirpp(fd, &info, &err)){ std::cout << entry->d_name << “is ” << info.st_size << “bytes in size.” << std::endl; } pos.closedirpp(fd, &err); //! [opendirpp] //! [mkdir] Context c; DavixError* err = NULL; DavPosix pos(&c); pos.mkdir(NULL, "dav://example.org/collection_to_create", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH, &err); //! [mkdir] //! [rename] Context c; DavixError* err = NULL; DavPosix pos(&c); pos.rename(NULL, "http://example.org/myfolder/old_file_name”, “http://example.org/myfolder/new_file_name", &err); //! [rename] //! [unlink] Context c; DavixError* err = NULL; DavPosix pos(&c); pos.unlink(NULL, "http://example.org/file_to_delete", &err); //! [unlink] //! [rmdir] Context c; DavixError* err = NULL; DavPosix pos(&c); pos.rmdir(NULL, "dav://example.org/collection_to_remove", &err); //! [rmdir] //! [open] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_FD* fd; fd = pos.open(NULL, "http://example.org/myfile", O_RDONLY, &err); //! [open] //! [close] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_FD* fd; fd = pos.open(NULL, "http://example.org/myfile", O_RDONLY, &err); pos.close(fd); //! [close] //! [read] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_FD* fd; fd = pos.open(NULL, "http://example.org/myfile", O_RDONLY, &err); // read 200 bytes from myfile char buffer[255]; pos.read(fd, &buffer, 200, &err); pos.close(fd); //! [read] //! [pread] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_FD* fd; fd = pos.open(NULL, "http://example.org/myfile", O_RDONLY, &err); // read 50 bytes from myfile at offset 100 char buffer2[255]; pos.pread(fd, &buffer2, 50, 100, &err); pos.close(fd); //! [pread] //! [write] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_FD* fd; // create a new file and write 200 bytes from buffer to it fd = pos.open(NULL, "http://example.org/myfolder/mynewfile", O_WRONLY | O_CREAT, &err); pos.write(fd, &buffer, 200); pos.close(fd); //! [write] //! [preadVec] Context c; DavixError* err = NULL; DavPosix pos(&c); int number_of_vector = 2; DavIOVecInput input_vector[number_of_vector]; DavIOVecOutput output_vector[number_of_vector]; DAVIX_FD* fd; fd = pos.open(NULL, "http://example.org/myfile", O_RDONLY, &err); // Setup vector operations parameters char buf1[255] = {0}; char buf2[255] = {0}; input_vector[0].diov_offset = 100; input_vector[0].diov_size = 200; input_vector[0].diov_buffer = buf1; input_vector[1].diov_offset = 600; input_vector[1].diov_size = 150; input_vector[1].diov_buffer = buf2; // execute query pos.pread_vec(fd, input_vector, output_vector, number_of_vector, &err); std::cout << “Op 1 read ” << output_vector[0].diov_size << “bytes” << std::endl; std::cout << “Op 2 read ” << output_vector[1].diov_size << “bytes” << std::endl; // do things with content in output_vector[0].diov_buffer etc pos.close(fd); //! [preadVec] //! [lseek] Context c; DavixError* err = NULL; DavPosix pos(&c); DAVIX_FD* fd; fd = pos.open(NULL, "http://example.com/myfile", O_RDONLY, &err); // position cursor to 200 bytes offset lseek(fd, 200, SEEK_SET, &err); // position cursor to current location plus 100 offset lseek(fd, 100, SEEK_CUR, &err); // position cursor to end of the file plus offset 200 lseek(fd, 200, SEEK_END, &err); pos.close(fd); //! [lseek] //------------------------------------------------------------------------------------------------- // Davix::HttpRequest //------------------------------------------------------------------------------------------------- //! [HttpRequest] Context c; DavixError* err = NULL; HttpRequest myrequest(c, "http://example.org/some_useful_stuff", &err); //! [HttpRequest] //! [HttpRequest uri] Context c; DavixError* err = NULL; HttpRequest myrequest(c, Uri("http://example.org/some_useful_stuff"), &err); //! [HttpRequest uri] //! [HttpRequest::setRequestMethod] myrequest.setRequestMethod(“GET”); //! [HttpRequest::setRequestMethod] //! [HttpRequest::setsetParameters] RequestParams params; params.setUserAgent(“MyAwesomeApp”); params.setClientLoginPassword(“my_login_name”, “my_uber_secure_password); // ... myrequest.setParameters(params); //! [HttpRequest::setsetParameters] //! [HttpRequest::addHeaderField] myrequest.addHeaderField("Accept", "application/metalink4+xml"); //! [HttpRequest::addHeaderField] //! [HttpRequest::setRequestBody] // from a string std::string content_string myrequest.setRequestBody(content_string); // from a buffer char buffer [255]; // fills buffer with something useful myrequest.setRequestBody(&buffer, sizeof(buffer)); // from a file descriptor, at offset 100 for 200 bytes int fd = open(“/tmp/myfile”, O_RDONLY); myrequest.setRequestBody(fd, 100, 200); close(fd); //! [HttpRequest::setRequestBody] //! [HttpRequest::executeRequest] myrequest.executeRequest(&err); //! [HttpRequest::executeRequest] //! [HttpRequest::beginRequest] myrequest.beginRequest(&err); //! [HttpRequest::beginRequest] //! [HttpRequest::endRequest] myrequest.endRequest(&err); //! [HttpRequest::endRequest] //! [HttpRequest::readBlock] // read max n bytes to static buffer char buffer[255]; myrequest.readBlock(&buffer, n, &err); // read to dynamically sized buffer, with max size n std::vector buffer2; myrequest.readBlock(&buffer2, n, &err); //! [HttpRequest::readBlock] //! [HttpRequest::readSegment] // readSegment calls readBlock repeatedly until n size is read, or end of answer char buffer[50*1024]; myrequest.readSegment(&buffer, n, &err); //! [HttpRequest::readSegment] //! [HttpRequest::readLine] char buffer[255]; myrequest.readLine(&buffer, n, &err); //! [HttpRequest::readLine] //! [HttpRequest::readToFd] char buffer[255] int fd = open(“tmp/myfile”, O_WRONLY | O_CREAT); // with no size limit myrequest.readToFd(fd, &err); // with 100 bytes limit myrequest.readToFd(fd, 100, &err); //! [HttpRequest::readToFd] //! [HttpRequest::getAnswerSize] dav_ssize_t size; size = myrequest.getAnswerSize(); //! [HttpRequest::getAnswerSize] //! [HttpRequest::getAnswerContentVec] // into dynamically sized buffer std::vector buffer1; buffer1 = myrequest.getAnswerContentVec(); //! [HttpRequest::getAnswerContentVec] //! [HttpRequest::getAnswerContent] // into static buffer char buffer2[255]; buffer2 = myrequest.getAnswerContent(); //! [HttpRequest::getAnswerContent] //! [HttpRequest::getRequestCode] int code; code = myrequest.getRequestCode(); //! [HttpRequest::getRequestCode] //! [HttpRequest::getLastModified] time_t last_modified; last_modified = myrequest.getLastModified(); //! [HttpRequest::getLastModified] //! [HttpRequest::getAnswerHeader] std::string value; myrequest.getAnswerHeader(“Content-Type”, &value); std::cout << “Content-Type is ” << value << std::endl; //! [HttpRequest::getAnswerHeader] //! [HttpRequest::getAnswerHeaders] HeaderVec headers; myrequest.getAnswerHeaders(headers); for(HeaderVec::iterator it = headers.begin(), it < headers.end(); ++it){ std::cout << it->first << “: ” << it->second << std::endl; } //! [HttpRequest::getAnswerHeaders] //! [HttpRequest::clearAnswerContent] myrequest.clearAnswerContent(); //! [HttpRequest::clearAnswerContent] //! [HttpRequest::discardBody] myrequest.discardBody(&err); //! [HttpRequest::discardBody] //! [HttpRequest::GetRequest] Context c; DavixError* err = NULL; Uri myuri(“http://example.org/myfile”); // Get request GetRequest req(c, myuri, &err); //! [HttpRequest::GetRequest] //! [HttpRequest::PutRequest] Context c; DavixError* err = NULL; Uri myuri(“http://example.org/myfile”); // Put request PutRequest req(c, myuri, &err); //! [HttpRequest::PutRequest] //! [HttpRequest::HeadRequest] Context c; DavixError* err = NULL; Uri myuri(“http://example.org/myfile”); // Head request HeadRequest req(c, myuri, &err); //! [HttpRequest::HeadRequest] //! [HttpRequest::DeleteRequest] Context c; DavixError* err = NULL; Uri myuri(“http://example.org/myfile”); // Delete request DeleteRequest req(c, myuri, &err); //! [HttpRequest::DeleteRequest] //! [HttpRequest::ProfindRequest] Context c; DavixError* err = NULL; Uri myuri(“http://example.org/myfile”); // Propfind request ProfindRequest req(c, myuri, &err); //! [HttpRequest::ProfindRequest] davix-R_0_5_0/doc/src/mainpage.hpp000066400000000000000000000114011257152637300171100ustar00rootroot00000000000000 /** * @mainpage Davix Documentation @author Devresse Adrien ( adrien.devresse@cern.ch ) Developped at CERN (IT-SDC-ID) Official WebSite: Here User Documentation: Here Mailing list : davix-devel@cern.ch

davix API :

file / object store API : Davix::DavFile
posix compatiblity layer : Davix::DavPosix
http request layer: Davix::HttpRequest
main header: \ref davix.hpp

What is davix ?

davix is a library and a set of tools for remote I/O on resources with HTTP based protocols. It aims to be a simple, performant and portable I/O layer for Cloud and Grid Storages services. Davix supports: - HTTP, WebDav, Amazon S3 - SSL/TLS - X509 client auth with proxy credential support - Vector operations (Partial reads, multi-range, single range) - Metalinks - Redirections caching - Webdav parsing - Data management operations ( mkdir, rm, stat ) The Davix targets to: - Be simple to use for simple use cases - Provide the needed features for High Performance I/O use cases - Be a data management swiss knife for HTTP based data stores

Examples

Query basic file metadata

@code{.cpp} StatInfo infos; DavFile file(context, "http://my.webdav.server.org/myfolder/myfile"); file.statInfo(NULL, infos); std::cout << "my file is " << infos.size << " bytes large " << std::endl; @endcode

Create a directory

@code{.cpp} DavFile file(context, "http://my.webdav.server.org/myfoldier/newfolder"); // creat directory file.makeCollection(NULL); @endcode

Get a full file content

@code{.cpp} DavFile f(context, "http://mysite.org/file"); int fd = open("/tmp/local_file", O_WRONLY | O_CREAT); // get full file file.getToFd(NULL,fd, NULL) < 0) @endcode

Execute a partial GET

@code{.cpp} char buffer[255] = {0}; DavFile file(context, "http://mysite.org/file"); // get 100 bytes from http://mysite.org/file after an offset of 200 bytes file.readPartial(NULL, buffer, 100, 200); @endcode

Execute a Vector Operation

@code{.cpp} char buffer[255] = {0} DavFile file(context, "http://mysite.org/file"); DavIOVecInput in[3]; DavIOVecOutput ou[3]; // setup vector operations parameters // -------- // execute query file.readPartialBufferVec(NULL, in, out , 3 , NULL); @endcode

Random I/O in posix mode

@code{.cpp} Davix::DavPosix p; // read ops fd= p.open(NULL, "https://mywebdav-server.org/myfile.jpg", O_RDONLY, NULL); p.read(fd, buffer, size, NULL); p.pread(fd, buffer, size2, offset, NULL); p.close(fd); // @endcode

Manual HTTP query:

@code{.cpp} Davix::HttpRequest req("https://restapi-server.org/rest") req.addHeaderField(...) req.setRequestMethod("PUT") // .. configure .... // // // execute your request req.executeRequest(...); @endcode

How to compile

- Davix Dependencies : - openssl - libxml-2.0 - Doxygen ( optional, for documentation generation ) - Davix Portability : - Target any POSIX OS - Ported on Linux > 2.6 , Windows with Cygwin, OSX > 10.2, AIX. - Packaged on Debian > 6, Ubuntu > 13.04, Fedora > 18, SL > 5, - Compile : - " 1. git clone http://git.cern.ch/pub/davix " - " 2. cd davix " - " 3. mkdir build; cd build" - " 4. cmake ../" - " 5. make " - Generate doc : - make doc - Compile and run unit tests : - cmake -DUNIT_TESTS=TRUE ../ - make - make test - Compile & execute func tests : * warning : functionals test needs davserver and a valid credential - " 4. cmake -DFUNCTIONAL_TESTS=TRUE ../ " - " 5. . ../test/setup_test_env.sh - " 5. make; make test" - make RPMS : - ./packaging/bin/packager_rpm.sh ./packaging/rpm/specs/ ./ - mock -r [mycfg] RPMS/davix-[...].src.rpm

Play with davix command line tool :

davix has a set of command line tools for testing purpose and demonstration -> davix-ls: file listing -> davix-get: download operations -> davix-put: upload operations -> davix-http: low level query composition

TODO in Davix

- WebHDFS support - S3 ACL support - CDMI support - X-stream mode support ( metalink multi source download ) For any contribution please contact us on davix-devel@cern.ch */ davix-R_0_5_0/include/000077500000000000000000000000001257152637300147105ustar00rootroot00000000000000davix-R_0_5_0/include/davix/000077500000000000000000000000001257152637300160235ustar00rootroot00000000000000davix-R_0_5_0/include/davix/auth/000077500000000000000000000000001257152637300167645ustar00rootroot00000000000000davix-R_0_5_0/include/davix/auth/davixauth.hpp000066400000000000000000000066661257152637300215100ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_AUTH_HPP #define DAVIX_AUTH_HPP #include #include #include "../utils/davix_types.hpp" #include "davixx509cred.hpp" #ifndef __DAVIX_INSIDE__ #error "Only davix.hpp for the C++ API or davix.h for the C API should be included." #endif /// @file davixauth.hpp /// @brief Authentication support for davix /// support for client cert x509, login password, S3 tokens namespace Davix { class SessionInfoInternal; class DavixCopyInternal; class NEONSession; /// @class SessionInfo /// @brief server related info class DAVIX_EXPORT SessionInfo: NonCopyable { public: std::vector & getReadableDN() const; private: SessionInfo(); SessionInfoInternal* data; friend class NEONSession; friend class DavixDelegation; }; #ifdef __DAVIX_HAS_STD_FUNCTION /// /// std::function for advanced authentification with client cert X509 /// /// @param info : Session info, contains information about server requesting the certificate /// @param cert : Client side credential to provide /// @return 0 if client cert is provider with success, can throw DavixException if error occurs typedef std::function authFunctionClientCertX509; #endif /// /// callback for advanced authentification with client cert X509 /// @param userdata : user defined data /// @param info : Session info, contains information about server requesting the certificate /// @param cert : Client side credential to provide /// @param err : error object to set if an error occures /// @return MUST return 0 if credential if provided with success or != 0 if error occures typedef int (*authCallbackClientCertX509)(void* userdata, const SessionInfo & info, X509Credential * cert, DavixError** err); /// /// callback for advanced authentification with client cert X509 /// @param userdata : user defined data /// @param info : Session info, contains information about server requesting the certificate /// @param login : login to use /// @param password : password to use /// @param count : number of try /// @return MUST return 0 if success, or !=0 if an error has occures typedef int (*authCallbackLoginPasswordBasic)(void* userdata, const SessionInfo & info, std::string & login, std::string & password, int count, DavixError** err); /// \cond PRIVATE_SYMBOLS std::string getAwsAuthorizationField(const std::string & stringToSign, const std::string & private_key, const std::string & access_key); /// \endcond PRIVATE_SYMBOLS } // namespace Davix #endif // DAVIX_AUTHOBJECT_HPP davix-R_0_5_0/include/davix/auth/davixx509cred.hpp000066400000000000000000000060011257152637300220710ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_X509CRED_HPP #define DAVIX_X509CRED_HPP #include #ifndef __DAVIX_INSIDE__ #error "Only davix.hpp for the C++ API or davix.h for the C API should be included." #endif /// @file davixx509cred.hpp /// @brief utilities for X509 credential namespace Davix { struct X509CredentialInternal; struct X509CredentialExtra; /// @class X509Credential /// @brief X509 certificate /// class DAVIX_EXPORT X509Credential { public: /// /// \brief default constructor /// X509Credential(); /// /// \brief copy constructor /// X509Credential(const X509Credential & orig); /// /// \brief assignment operator /// X509Credential & operator=(const X509Credential & orig); /// \brief destructor ~X509Credential(); /// load a credential from a PKCS12 file /// @param filepath_p12_cred : path to the p12 credential file /// @param password : pass to decrypt the credential, empty string if nothing /// @param err : davix error report int loadFromFileP12(const std::string & filepath_p12_cred, const std::string & password, DavixError** err); /// load a credential from a PEM file /// support RFC-3820 proxy certificate, "globus" proxy certificate and "VOMS" proxy certificate /// support for concatenated format /// /// to use a concatenated PEM cred, just set filepath_priv_key = filepath_cred = concat cred path /// /// @param filepath_priv_key : path to the private key file /// @param filepath_cred : path to the credential file /// @param password : pass to decrypt the credential, empty string if unencrypted /// @param err : davix error report int loadFromFilePEM(const std::string & filepath_priv_key, const std::string & filepath_cred, const std::string & password, DavixError** err); /// check if the object contain a credential /// @return true if contains a valid certificate, false if empty bool hasCert() const; private: X509CredentialInternal * d_ptr; friend struct X509CredentialExtra; }; } // namespace Davix #endif // DAVIX_X509CRED_HPP davix-R_0_5_0/include/davix/compat/000077500000000000000000000000001257152637300173065ustar00rootroot00000000000000davix-R_0_5_0/include/davix/compat/davix_ignored.hpp000066400000000000000000000006141257152637300226420ustar00rootroot00000000000000#ifndef DAVIX_IGNORED_HPP #define DAVIX_IGNORED_HPP // WARNING // This file contains functions / variables that will be removed from the official API // This file is maintained for compatbility only // Please, do not use any function of this header in a new program #include "../davix.hpp" std::ostream& operator<< (std::ostream& stream, const Davix::Uri & _u); #endif // DAVIX_IGNORED_HPP davix-R_0_5_0/include/davix/compat/deprecated.hpp000066400000000000000000000100211257152637300221110ustar00rootroot00000000000000#ifndef DAVIX_DEPRECATED #define DAVIX_DEPRECATED #include #include #include #include #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif /** @file deprecated.hpp @author Devresse Adrien @brief Deprecated class / functions of Davix for ABI/ API compatibility Each call to one of these function kill a kitten. Please love kittens and don't use them */ #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace Davix { struct HttpCacheTokenInternal; class DAVIX_EXPORT HttpCacheToken { public: HttpCacheToken(); HttpCacheToken(const HttpCacheToken & orig); virtual ~HttpCacheToken(); HttpCacheToken & operator=(const HttpCacheToken &); const Uri & getrequestUri() const; const Uri & getCachedRedirection() const; private: HttpCacheTokenInternal* d_ptr; friend struct HttpCacheTokenAccessor; }; class DAVIX_EXPORT FileInfoInterface{ public: virtual ~FileInfoInterface(){} virtual const std::type_info & getType() =0; virtual FileInfoInterface* getClone() = 0; }; template class DAVIX_EXPORT FileInfo : public FileInfoInterface{ public: virtual ~FileInfo(){} virtual const std::type_info & getType(){ return typeid(*static_cast(this)); } virtual FileInfoInterface* getClone(){ return new T(*static_cast(this)); } }; class DAVIX_EXPORT FileInfoSize : public FileInfo{ public: FileInfoSize() : size(0){} FileInfoSize(dav_size_t s) : size(s){} FileInfoSize(const FileInfoSize & orig) : size(orig.size) {} virtual ~FileInfoSize(){} dav_size_t size; }; class DAVIX_EXPORT FileInfoHash : public FileInfo{ public: FileInfoHash(const FileInfoHash & orig) : hash(orig.hash), hash_type(orig.hash_type) {} virtual ~FileInfoHash(){} std::string hash; std::string hash_type; }; class DAVIX_EXPORT FileInfoName : public FileInfo{ public: FileInfoName(const FileInfoName & orig) : name(orig.name){} virtual ~FileInfoName(){} std::string name; }; class DAVIX_EXPORT FileInfoProtocolType : public FileInfo{ public: FileInfoProtocolType() : protocol(){} FileInfoProtocolType(const FileInfoProtocolType & orig) : protocol(orig.protocol){} FileInfoProtocolType(const std::string & s) : protocol(s){} virtual ~FileInfoProtocolType(){} std::string protocol; }; typedef std::vector Properties; class DAVIX_EXPORT Replica { public: Replica() : uri(), props(){} Replica(const Replica & orig) : uri(orig.uri), props() { props.reserve(orig.props.size()); for(Properties::iterator it = props.begin(); it < props.end(); ++it){ props.push_back((*it)->getClone()); } } virtual ~Replica(){ for(Properties::iterator it = props.begin(); it < props.end(); ++it) delete *it; } Uri uri; Properties props; }; typedef std::deque ReplicaVec; struct HookIntern; /// /// \brief The HookTraits class /// /// Base class for Daivx Hook functions /// struct HookTraits{ HookTraits(); virtual ~HookTraits(); virtual const std::type_info & getType() =0; // internal HookIntern* d_ptr; }; template struct Hook: HookTraits{ virtual const std::type_info & getType(){ return typeid(*static_cast(this)); } }; class HttpRequest; typedef void (*CallbackHeader)(HttpRequest &, const std::string &, std::string &); struct HookSendHeader : public Hook{ CallbackHeader hook; }; struct HookReceiveHeader : public Hook{ CallbackHeader hook; }; typedef void (*CallbackRequestExec)(HttpRequest &); struct HookRequestPreExec : public Hook{ CallbackRequestExec hook; }; struct HookRequestPostExec : public Hook{ CallbackRequestExec hook; }; } // namespace Davix #endif #endif davix-R_0_5_0/include/davix/copy/000077500000000000000000000000001257152637300167755ustar00rootroot00000000000000davix-R_0_5_0/include/davix/copy/davixcopy.hpp000066400000000000000000000042661257152637300215240ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_COPY_HPP #define DAVIX_COPY_HPP #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif #ifndef DOXYGEN_SHOULD_SKIP_THIS #include namespace Davix { struct DAVIX_EXPORT PerformanceMarker { size_t index, count; time_t begin, latest; off_t transferred; off_t transferAvg; off_t transferInstant; PerformanceMarker(); }; struct DAVIX_EXPORT PerformanceData { time_t begin, latest; std::vector markers; PerformanceData(); ~PerformanceData(); void update(const PerformanceMarker& in); time_t absElapsed() const; off_t avgTransfer(void) const; off_t diffTransfer() const; off_t totalTransferred() const; }; class DAVIX_EXPORT DavixCopy { public: DavixCopy(Context & c, const RequestParams *params); virtual ~DavixCopy(); void copy(const Uri &source, const Uri &destination, unsigned nstreams, DavixError **error); // Callbacks typedef void (*PerformanceCallback)(const PerformanceData& perfData, void* data); void setPerformanceCallback(PerformanceCallback callback, void *udata); private: class DavixCopyInternal *d_ptr; DavixCopy(const DavixCopy&); DavixCopy& operator = (const DavixCopy&); }; } #endif #endif // DAVIX_COPY_HPP davix-R_0_5_0/include/davix/davix.hpp000066400000000000000000000043671257152637300176610ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_HPP #define DAVIX_HPP /// /// @file davix.hpp /// @author Devresse Adrien /// /// /// @brief C++ API of Davix /// Davix is a high level HTTP/Webdav library /// for file management and file access. /// /// You need to create a context before any operations /// #ifndef __DAVIX_INSIDE__ #define __DAVIX_INSIDE__ #endif #ifndef DAVIX_EXPORT #define DAVIX_EXPORT #endif #include /// main context #include /// authentication utilities #include /// low level HttpRequest builder #include /// request parameters #include /// davix uri parser #include /// file API, main API for remote I/O #include /// posix like API #include /// status and error management #include /// logger features #include /// REST utilities functions #include /// hooks for extensions #include // The usage of this header : // - promote Comic Sans // - create black holes // - kill kitten #include // third party copy // Note this is an extension supported // by a couple of http implementations only // i.e. lcgdm-dav #include #endif // DAVIX_HPP davix-R_0_5_0/include/davix/davix_file_types.hpp000066400000000000000000000074431257152637300221020ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_FILE_TYPES_HPP #define DAVIX_FILE_TYPES_HPP #include #include /** @file davix_file_types.hpp @author Devresse Adrien @brief davix file related type declarations */ // file descriptor declaration struct Davix_dir_handle; struct Davix_fd; typedef struct Davix_dir_handle DAVIX_DIR; typedef struct Davix_fd DAVIX_FD; namespace Davix{ /// @struct DavIOVecInput /// @brief input parameters for vector operations in Davix struct DAVIX_EXPORT DavIOVecInput{ void* diov_buffer; /**< buffer, in case of read : destination buffer, in case of write : source buffer */ dav_off_t diov_offset; /**< initial offset taken from the source */ dav_size_t diov_size; /**< size of the data requested */ }; /// @struct DavIOVecOuput /// @brief result of vector operations in Davix struct DAVIX_EXPORT DavIOVecOuput{ void* diov_buffer; /**< pointer to the buffer used for this fragment */ dav_ssize_t diov_size; /**< size of the data returned, -1 if error */ }; /// @enum advise_t /// Information about the next type of operation executed /// AdviseAuto : default operation, no optimization /// AdviseSequentialRead : optimize next operation for sequential read/write /// AdviseRandomRead: optimize next operation for random position read/write enum DAVIX_EXPORT advise_t{ AdviseAuto=0x00, AdviseSequential, AdviseRandom, }; /// /// @brief StatInfo struct /// @struct StatInfo /// container for base file meta-data, plateform agnostic stat struct /// struct StatInfo{ StatInfo(): size(0), nlink(0), mode(0), atime(0), mtime(0), ctime(0){ } /// size in bytes of the resource dav_size_t size; /// number of links to the resource /// optional dav_ssize_t nlink; /// POSIX rights of the resource /// optional, supported with some Webdav servers mode_t mode; /// access time time_t atime; /// modification time time_t mtime; /// creation time time_t ctime; /// struct converter from POSIX stat inline void fromPosixStat(const struct stat & st){ mode = static_cast(st.st_mode); atime = static_cast(st.st_atime); mtime = static_cast(st.st_mtime); ctime = static_cast(st.st_ctime); size = static_cast(st.st_size); nlink = static_cast(st.st_nlink); } /// struct converter to POSIX stat inline struct stat & toPosixStat(struct stat & st){ st.st_mode = static_cast(mode); st.st_atime = static_cast(atime); st.st_mtime = static_cast(mtime); st.st_ctime = static_cast(ctime); st.st_size = static_cast(size); st.st_nlink = static_cast(nlink); return st; } }; } // Davix #endif // DAVIX_FILE_TYPES_HPP davix-R_0_5_0/include/davix/davixcontext.hpp000066400000000000000000000067541257152637300212700ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIXCONTEXT_HPP #define DAVIXCONTEXT_HPP #include #include #include #include #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif /// /// @file davixcontext.hpp /// @author Devresse Adrien /// /// Handle of Davix namespace Davix{ struct ContextInternal; struct ContextExplorer; class HookList; class HttpRequest; class DavPosix; /// @brief Main handle for Davix /// /// Each new davix context contains its own session-reuse pool and set of parameters /// a Context can execute multiple queries in parallels and is thread safe class DAVIX_EXPORT Context { public: /// /// \brief Default constructor /// Context(); /// /// \brief copy constructor /// \param c /// Context(const Context & c); /// /// \brief assignment operator /// \param c /// \return /// Context & operator=(const Context & c); /// /// \brief destructor /// virtual ~Context(); /// clone this instance to a new context Context* clone(); #ifdef __DAVIX_HAS_STD_FUNCTION /// set a new hook (callback) to intercept event in davix /// see davix_hooks.hpp for more details about hooks /// WARNING: setting a new HOOK override exiting ones template inline void setHook(const HookType & id){ hookDefine(getHookList(), id); } /// get the value register for one type of hook template inline const HookType & getHook(){ return hookGet(getHookList()); } #endif /// @brief load a plugin or a profile identified by name /// @param name : name of the plugin or profile to load /// /// Example: loadModule("grid") configure davix /// for a grid environment usage void loadModule(const std::string & name); /// enable or disable the session caching void setSessionCaching(bool caching); /// get session caching status bool getSessionCaching() const; private: // internal context ContextInternal* _intern; friend class DavPosix; friend struct ContextExplorer; HookList & getHookList(); public: /// @deprecated HttpRequest* createRequest(const Uri & uri, DavixError** err); /// @deprecated HttpRequest* createRequest(const std::string & url, DavixError** err); /// @deprecated DavPosix* createDavPosix(); private: }; /// version string of the current davix library /// @return version of davix DAVIX_EXPORT const std::string & version(); } #endif // DAVIXCONTEXT_HPP davix-R_0_5_0/include/davix/file/000077500000000000000000000000001257152637300167425ustar00rootroot00000000000000davix-R_0_5_0/include/davix/file/davfile.hpp000066400000000000000000000317531257152637300210760ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVFILE_HPP #define DAVFILE_HPP #include #include #include #include #include #include #include #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif /// /// @file davfile.hpp /// @author Devresse Adrien /// /// File API of Davix namespace Davix{ struct StatInfo; /// /// @class DavFile /// @brief Davix File Interface /// /// Davix File interface class DAVIX_EXPORT DavFile { public: struct DavFileInternal; class Iterator{ friend struct DavFileInternal; public: Iterator() : d_ptr() {} Iterator(const Iterator & orig) : d_ptr(orig.d_ptr){} bool next(); const std::string & name(); const StatInfo & info(); private: struct Internal; std::shared_ptr d_ptr; }; /// /// \brief default constructor /// \param c context /// \param url remote file URL /// DavFile(Context & c, const Uri & url); DavFile(Context &c, const RequestParams & params, const Uri &url); DavFile(const DavFile & orig); /// /// \brief destructor /// virtual ~DavFile(); /// @brief return Uri of the current file /// const Uri & getUri() const; /// /// @brief return all replicas associated to this file /// /// Replicas are found using a corresponding The MetaLink standard ( rfc5854, rfc6249 ) /// /// @param params Davix Request parameters /// @param err Davix error report /// @return Replica vector, if error is found return empty vector and set err properly /// /// @snippet example_code_snippets.cpp getReplicas std::vector getReplicas(const RequestParams* params, DavixError** err) throw(); /// /// @brief Vector read operation /// Albe to do several read on several data chunk in one single operation. /// Uses Http multi-part when supported by the server, /// simulate a vector read operation otherwise. /// /// @param params Davix request Parameters /// @param input_vec input vectors, parameters /// @param ioutput_vec output vectors, results /// @param count_vec number of vector /// @param err Davix error report /// @return total number of bytes read, or -1 if error occures /// /// @snippet example_code_snippets.cpp readPartialBufferVec dav_ssize_t readPartialBufferVec(const RequestParams* params, const DavIOVecInput * input_vec, DavIOVecOuput * ioutput_vec, const dav_size_t count_vec, DavixError** err) throw(); /// /// @brief Partial position independant read. /// /// /// Use ranged request when supported by the server, /// simulate a ranged request when not supported /// /// @param params Davix request Parameters /// @param buff buffer /// @param count maximum read size /// @param offset starting offset for the read operation /// @param err Davix error report /// @return total number of bytes read, or -1 if error occures /// /// @snippet example_code_snippets.cpp readPartial dav_ssize_t readPartial(const RequestParams* params, void* buff, dav_size_t count, dav_off_t offset, DavixError** err) throw(); /// /// @brief Get the full file content and write it to file descriptor /// /// @param params Davix request Parameters /// @param fd file descriptor for write operation /// @param err Davix error report /// @return total number of bytes read, or -1 if error occures /// /// @snippet example_code_snippets.cpp getToFd dav_ssize_t getToFd(const RequestParams* params, int fd, DavixError** err) throw(); /// /// @brief Get the first 'size_read' bytes of the file and write it to file descriptor /// /// @param params Davix request Parameters /// @param fd file descriptor for write operation /// @param size_read number of bytes to read /// @param err Davix error report /// @return total number of bytes read, or -1 if error occures /// /// @snippet example_code_snippets.cpp getToFd sized dav_ssize_t getToFd(const RequestParams* params, int fd, dav_size_t size_read, DavixError** err) throw(); /// /// @brief Get the full file content in a dynamically allocated buffer /// /// @param params Davix request Parameters /// @param buffer reference to a vector for the result /// @param err Davix error report /// @return total number of bytes read, or -1 if error occures /// /// @snippet example_code_snippets.cpp getFull dav_ssize_t getFull(const RequestParams* params, std::vector & buffer, DavixError** err) throw(); /// /// @brief Get the full file content to buffer /// /// @param params Davix request Parameters /// @param buffer reference to a vector for storing the result /// @return total number of bytes read, or -1 if error occures /// /// Get the file content in a dynamically allocated buffer /// /// WARNING: this operation is without size limit for the content /// /// @snippet example_code_snippets.cpp get dav_ssize_t get(const RequestParams* params, std::vector & buffer); /// /// @brief Create/Replace file content /// /// @param params Davix request Parameters /// @param fd file descriptor /// @param size_write number of bytes to write /// @throw throw @ref DavixException if an error occurs /// /// Create / Replace the file. /// Read the new content from the file descriptor fd for a maximum of size_write bytes. /// /// @snippet example_code_snippets.cpp put fd void put(const RequestParams* params, int fd, dav_size_t size_write); /// /// @brief Create/Replace file content /// /// @param params Davix request Parameters /// @param buffer buffer with data to write /// @param size_write number of bytes to write /// @throw throw @ref DavixException if an error occurs /// /// Set a new content for the file. /// The new content comes from buffer. /// /// @snippet example_code_snippets.cpp put buffer void put(const RequestParams* params, const char* buffer, dav_size_t size_write); #ifdef __DAVIX_HAS_STD_FUNCTION /// /// @brief Create/Replace file content /// /// @param params Davix request Parameters /// @param callback data provider callback /// @param size Total size of the data to write /// @throw throw @ref DavixException if an error occurs /// /// Set a new content for the file. /// The new content comes from a data provider callback. /// /// @snippet example_code_snippets.cpp put callback void put(const RequestParams* params, const DataProviderFun & callback, dav_size_t size); #endif /// /// @brief move /// @param params Davix request Parameters /// @param destination destination resource /// /// Move the current resource to Destination. /// /// The result of the operation depend of the protocol used. /// /// Protocol supported currently: WebDav, S3 /// /// @snippet example_code_snippets.cpp move void move(const RequestParams* params, DavFile & destination); /// /// @brief Suppress the current entity or collection. /// /// @param params Davix request Parameters /// @throw throw @ref DavixException if error occurs /// /// @snippet example_code_snippets.cpp delete void deletion(const RequestParams* params = NULL); /// /// @brief Suppress the current entity or collection. /// /// Exception safe version of @ref deletion(const RequestParams* params = NULL) /// /// @snippet example_code_snippets.cpp delete no throw int deletion(const RequestParams* params, DavixError** err) throw(); /// /// @brief create a collection (directory or bucket) at the current url /// /// @param params Davix request Parameters /// @throw throw @ref DavixException if error occurs /// /// @snippet example_code_snippets.cpp makeCollection void makeCollection(const RequestParams *params = NULL); /// /// @brief create a collection (directory or bucket) at the current url /// /// Exception safe version of @ref makeCollection(const RequestParams *params = NULL) /// /// @snippet example_code_snippets.cpp makeCollection no throw int makeCollection(const RequestParams* params, DavixError** err) throw(); /// /// @brief execute a file meta-data query /// /// @param params Davix request Parameters /// @param st stat struct /// @param err Davix error report /// @return 0 if success, or -1 if error occures /// /// @snippet example_code_snippets.cpp statInfo StatInfo & statInfo(const RequestParams* params, StatInfo & info); /// /// @brief execute a POSIX-like stat() query /// /// @param params Davix request parameters /// @param st stat struct /// @param err Davix error report /// @return 0 if success, or -1 if error occures /// /// @snippet example_code_snippets.cpp stat int stat(const RequestParams* params, struct stat * st, DavixError** err) throw(); /// /// @brief Collection listing /// /// @param params Davix request parameters /// @return Iterator to the collection /// /// @snippet example_code_snippets.cpp listCollection Iterator listCollection(const RequestParams* params); /// /// @brief compute checksum of the file /// /// with the given algorithm (MD5, CRC32, ADLER32) /// /// server implementation dependend /// /// Davix::checksum support LCGDM-DAV, dCache Jetty and Aws S3 checksum support /// /// @param params request parameters /// @param checksm checksum buffer /// @param chk_algo string of the algorithm (eg: "MD5" ) /// @return reference to checksm /// @throw throw @ref DavixException if error occurs /// /// @snippet example_code_snippets.cpp checksum std::string & checksum(const RequestParams *params, std::string &checksm, const std::string &chk_algo); /// /// @brief compute checksum of the file with the given algorithm (MD5, CRC32, ADLER32) /// /// Exception safe version of @ref checksum /// /// @snippet example_code_snippets.cpp checksum no throw int checksum(const RequestParams *params, std::string & checksm, const std::string & chk_algo, DavixError **err) throw(); /// /// @brief provide information on the next file operation /// /// provide information on the next file operations for optimizations and prefetching /// /// @param offset /// @param size_read /// @param adv /// void prefetchInfo(off_t offset, dav_size_t size_read, advise_t adv); private: DavFileInternal* d_ptr; public: /// @deprecated deprecated, will be removed in 2.0 DEPRECATED(dav_ssize_t getAllReplicas(const RequestParams* params, ReplicaVec & vec, DavixError** err)); /// /// @deprecated please use put() as the replacement, will be removed in 2.0 /// DEPRECATED(int putFromFd(const RequestParams* params, int fd, dav_size_t size_write, DavixError** err) throw()); }; typedef DavFile File; } // Davix // provide stream operator for Davix::File std::ostream & operator<<(std::ostream & out, Davix::DavFile & file); std::istream & operator>>(std::istream & in, Davix::DavFile & file); #endif // DAVFILE_HPP davix-R_0_5_0/include/davix/file/davix_file_info.hpp000066400000000000000000000020451257152637300226010ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_FILE_INFO_HPP #define DAVIX_FILE_INFO_HPP #include #include #endif // DAVIX_FILE_INFO_HPP davix-R_0_5_0/include/davix/file/davposix.hpp000066400000000000000000000314561257152637300213210ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_DAVPOSIX_HPP #define DAVIX_DAVPOSIX_HPP #include #include #include #include /** @file davposix.hpp @author Devresse Adrien @brief POSIX-like API of davix */ #ifndef __DAVIX_INSIDE__ #error "Only davix.hpp for the C++ API or davix.h for the C API should be included." #endif namespace Davix { class DavPosixInternal; /// /// @brief POSIX-like API of Davix. /// /// DavPosix offers a POSIX-like API for HTTP/WebDav file operations. /// /// POSIX API can be used for convenience when porting application. /// to a POSIX like interface. /// /// DavPosix and all associated method are Thread safe. class DAVIX_EXPORT DavPosix : NonCopyable { public: /// /// \brief default constructor /// \param handle /// /// /// @snippet example_code_snippets.cpp DavPosix DavPosix(Context* handle); virtual ~DavPosix(); /** @brief POSIX-like stat() call Behavior similar to the POSIX stat function, see man 3 stat. Supported by Webdav, Http and S3. Depending of the protocol, some struct stat field can be ignored. @param params request options, can be NULL @param str string url @param st stat struct to fill @param err Davix error report system @return 0 if success, negative value if error @snippet example_code_snippets.cpp stat */ int stat(const RequestParams* params, const std::string & str, struct stat * st, DavixError** err); /** @brief 64bits version of /ref Davix::DavPosix::stat. @snippet example_code_snippets.cpp stat */ int stat64(const RequestParams *params, const std::string & url, StatInfo* st, DavixError** err); /** @brief open a directory for listing. behavior similar to the POSIX opendir function. Supported by Webdav. @param params request options, can be NULL @param url url of the directory to list @param err Davix error report system @return DAVIX_DIR davix readdir handle, NULL if error @snippet example_code_snippets.cpp opendir */ DAVIX_DIR* opendir(const RequestParams* params, const std::string & url, DavixError** err); /** @brief read an entry directory. Behavior similar to the POSIX readdir function. @param dir directory handle @param err Davix Error report @return dirent struct if success, or NULL if error @snippet example_code_snippets.cpp opendir */ struct dirent* readdir(DAVIX_DIR* dir, DavixError** err); /** @brief close a directory handle @param d directory handle to close @param err Davix error report system @return 0 if success else a negative value and err is set. @snippet example_code_snippets.cpp opendir */ int closedir(DAVIX_DIR* d, DavixError** err); /** @brief open a directory for listing with per entry meta-data informations. Similar to \ref Davix::DavPosix::opendir but provide stat() informations for each entry Supported by Webdav. @param params request options, can be NULL @param url url of the directory to list @param err Davix error report system @return DAVIX_DIR davix readdir handle or NULL if error, in this case err is set. @snippet example_code_snippets.cpp opendirpp */ DAVIX_DIR* opendirpp(const RequestParams* params, const std::string & url, DavixError** err); /** @brief execute an readdirpp function Similar to \ref Davix::DavPosix::readdir but provide stat() informations for each entry. Supported by Webdav. @param dir directory handle @param st struct to fill @param err Davix Error report @return dirent struct if success, or NULL if error @snippet example_code_snippets.cpp opendirpp */ struct dirent* readdirpp(DAVIX_DIR* dir, struct stat * st, DavixError** err ); /** @brief close a directory handle @param d directory handle to close @param err Davix error report system @return 0 if success else a negative value and err is set. @snippet example_code_snippets.cpp opendirpp */ int closedirpp(DAVIX_DIR* d, DavixError** err ); /** @brief execute a mkdir function with Webdav. Behavior similar to the POSIX mkdir function. @warning dependening of the server, implementation, mode_t parameter can be ignored @param params request options, can be NULL @param url url of the directory to create @param right default mode of the directory ( ignored for now ) @param err Davix error report system @return 0 if success else a negative value and err is set. @snippet example_code_snippets.cpp mkdir */ int mkdir(const RequestParams* params, const std::string& url, mode_t right, DavixError** err); /** @brief rename a target file or collection. Behavior similar to the POSIX rename function. @param params request options, can be NULL @param source_url old url of the resource @param target_url new url of the resource @param err Davix error report system @return 0 if success else a negative value and err is set. @snippet example_code_snippets.cpp rename */ int rename(const RequestParams* params, const std::string& source_url, const std::string& target_url, DavixError** err); /** @brief execute a remove file operation. Behavior similar to the POSIX unlink function. @param params request options, can be NULL @param url file to delete @param err Davix error report system @return 0 if success else a negative value and err is set. @snippet example_code_snippets.cpp unlink */ int unlink(const RequestParams* params, const std::string& url, DavixError** err); /** @brief execute a remove directory operation. Behavior similar to the POSIX rmdir function @param params request options, can be NULL @param url directory to delete @param err Davix error report system @return 0 if success else a negative value and err is set. @snippet example_code_snippets.cpp rmdir */ int rmdir(const RequestParams* params, const std::string& url, DavixError** err); /** @brief open a file for read/write operation in a POSIX-like approach. Behavior similar to the POSIX open function This operation is supported on plain HTTP servers. @param params request options, can be NULL @param url url of the HTTP file to open @param flags open flags, similar to the POSIX function open @param err Davix Error report @return Davix file descriptor in case of success, or NULL if an error occures. @snippet example_code_snippets.cpp open */ DAVIX_FD* open(const RequestParams* params, const std::string & url, int flags, DavixError** err); /** @brief read a file in a POSIX-like approach with HTTP(S). Behavior similar to the POSIX read function @param fd davix file descriptor @param buffer buffer to fill @param count maximum number of bytes to read @param err Davix Error report @return the size of data or a negative value if an error occured @snippet example_code_snippets.cpp read */ ssize_t read(DAVIX_FD* fd, void* buffer, size_t count, DavixError** err); /** @brief do a partial read of a file in a POSIX-like approach with HTTP(S). Behavior similar to the POSIX pread function. @param fd davix file descriptor @param buffer buffer to fill @param count maximum number of bytes to read @param offset offset to use @param err Davix Error report @return the size of data or a negative value if an error occured @snippet example_code_snippets.cpp pread */ ssize_t pread(DAVIX_FD* fd, void* buffer, size_t count, off_t offset, DavixError** err); /** @brief 64bits version of /ref Davix::DavPosix::pread */ dav_ssize_t pread64(DAVIX_FD* fd, void* buffer, dav_size_t count, dav_off_t offset, DavixError ** err); /** @brief do a partial write of a file in a POSIX-like approach with HTTP(S). Behavior similar to the POSIX pwrite function @param fd davix file descriptor @param buffer buffer to fill @param count maximum number of bytes to write @param offset offset to use @param err Davix Error report @return the size of data written or a negative value if an error occured @snippet example_code_snippets.cpp pwrite */ ssize_t pwrite(DAVIX_FD* fd, const void* buffer, size_t count, off_t offset, DavixError** err); /** @brief 64bits version of /ref Davix::DavPosix::pwrite */ dav_ssize_t pwrite64(DAVIX_FD* fd, const void* buffer, dav_size_t count, dav_off_t offset, DavixError** err); /** @brief pread_vec a file in a POSIX-like approach with HTTP(S). Vector read operation. Able to do several read operations in one single request. @param fd davix file descriptor @param input_vec input vectors, parameters @param output_vec output vectors, results @param count_vec number of vector struct @param err Davix Error report @return total number of bytes read, or -1 if error occures @snippet example_code_snippets.cpp preadVec */ dav_ssize_t preadVec(DAVIX_FD* fd, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, dav_size_t count_vec, DavixError** err); /** @brief write a file in a POSIX-like approach with HTTP(S). Behavior similar to the POSIX write function. @param fd davix file descriptor @param buf buffer with the write content @param count number of bytes to write @param err Davix Error report @return the size of the written data or a negative value if an error occured @snippet example_code_snippets.cpp write */ ssize_t write(DAVIX_FD* fd, const void* buf, size_t count, DavixError** err); /** @brief move the cursor a davix file with HTTP(S). Behavior similar to the POSIX lseek function. @param fd davix file descriptor @param offset offset in byte inside the file @param flags lseek flags, similar to the lseek function @param err Davix Error report @return the offset position or (off_t)-1 if error occurs @snippet example_code_snippets.cpp lseek */ off_t lseek(DAVIX_FD* fd, off_t offset, int flags, DavixError** err); /** @brief 64bits versions of /ref Davix::DavixPosix::lseek */ dav_off_t lseek64(DAVIX_FD* fd, dav_off_t, int flags, DavixError** err); /** @brief close a existing file descriptor. Note : all file descriptors MUST be closed before the destruction of the parent davix context @param fd davix file descriptor @param err Davix Error report @return 0 if success, negative value if error @snippet example_code_snippets.cpp close */ int close(DAVIX_FD* fd, DavixError** err); /** @brief give advise about next file operation similar to posix_fadvise, allow I/O optimizations non-blocking asynchronous function @param fd Davix file descriptor @param offset offset of the next chunk to read @param len size of the next chunk to read @param advise type of pattern for I/O : sequential, random */ void fadvise(DAVIX_FD* fd, dav_off_t offset, dav_size_t len, advise_t advice); private: DAVIX_DIR* internal_opendirpp(const RequestParams* params, const char * scope, const std::string & body, const std::string & url, DavixError** err); Context* context; long _timeout; long _s_buff; DavPosixInternal* d_ptr; }; } // namespace Davix #endif // DAVIX_DAVPOSIX_HPP davix-R_0_5_0/include/davix/hooks/000077500000000000000000000000001257152637300171465ustar00rootroot00000000000000davix-R_0_5_0/include/davix/hooks/davix_hooks.hpp000066400000000000000000000022761257152637300222040ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_HOOKS_HPP #define DAVIX_HOOKS_HPP // See davix_hooks_fwd.hpp for Hooks declarations /** @file davix_hooks.hpp @author Devresse Adrien @brief Hook (callback) functions of davix */ #include #include #endif // DAVIX_HOOKS_HPP davix-R_0_5_0/include/davix/hooks/davix_hooks_fwd.hpp000066400000000000000000000034241257152637300230400ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_HOOKS_FWD_HPP #define DAVIX_HOOKS_FWD_HPP #include #include /** @file davix_hooks_fwd.hpp @author Devresse Adrien @brief Hook definitions of davix */ namespace Davix{ class HttpRequest; class RequestParams; class Uri; #ifdef __DAVIX_HAS_STD_FUNCTION /// Hook called before processing any request typedef std::function< void (RequestParams& p, HttpRequest & req, Uri & u) > RequestPreRunHook; /// Hook called when sending any request, just after sending headers typedef std::function RequestPreSendHook; /// Hook called when receiving any request, just after receiving headers typedef std::function RequestPreReceHook; #endif } #endif // DAVIX_HOOKS_FWD_HPP davix-R_0_5_0/include/davix/hooks/davix_hooks_impl.hpp000066400000000000000000000046451257152637300232270ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_HOOKS_IMPL_HPP #define DAVIX_HOOKS_IMPL_HPP #include // intern file, Never use directly #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace Davix{ struct ContextInternal; #ifdef __DAVIX_HAS_STD_FUNCTION class HookList{ public: RequestPreRunHook _pre_run_req; RequestPreSendHook _pre_send_req; RequestPreReceHook _pre_rece_req; private: HookList(); friend struct ContextInternal; }; // define template inline void hookDefine(HookList & c, const HookType & hook){ (void) c; (void) hook; throw DavixException(std::string("davix::hook"), StatusCode::InvalidHook, "Invalid Hook type"); } template<> inline void hookDefine(HookList &c, const RequestPreRunHook & hook){ c._pre_run_req = hook; } template<> inline void hookDefine(HookList &c, const RequestPreSendHook & hook){ c._pre_send_req = hook; } template<> inline void hookDefine(HookList &c, const RequestPreReceHook & hook){ c._pre_rece_req = hook; } // get template inline const HookType & hookGet(HookList & c){ (void) c; throw DavixException(std::string("davix::hook"), StatusCode::InvalidHook, "Invalid Hook type"); } template<> inline const RequestPreRunHook & hookGet(HookList & c){ return c._pre_run_req; } template<> inline const RequestPreSendHook & hookGet(HookList & c){ return c._pre_send_req; } template<> inline const RequestPreReceHook & hookGet(HookList & c){ return c._pre_rece_req; } #endif } #endif #endif // DAVIX_HOOKS_IMPL_HPP davix-R_0_5_0/include/davix/params/000077500000000000000000000000001257152637300173065ustar00rootroot00000000000000davix-R_0_5_0/include/davix/params/davix_request_params_types.hpp000066400000000000000000000074711257152637300255020ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef REQUEST_PARAMS_TYPES_HPP #define REQUEST_PARAMS_TYPES_HPP /** @file request_params_types.hpp @author Devresse Adrien @brief types for request parameters */ #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif #include #include "../utils/davix_uri.hpp" namespace Davix{ namespace RequestProtocol{ /// /// \brief Http based protocol to use for advanced queries /// enum Protocol{ // default Auto=0, // Strict Http without extensions Http, // Use Http + Webdav extension Webdav, // Use Amazon S3 API AwsS3 }; } namespace MetalinkMode{ enum MetalinkMode{ // default mode = failover Auto=0, // Disable Metalink Support Disable, // Use only for failover purpose FailOver, // Enable parallel DL XStream }; } namespace S3ListingMode{ enum S3ListingMode{ // Full hierarchical listing (depth is 1) Hierarchical, // Semi-hierarchical listing (depth is infinity) SemiHierarchical, // Flat listing Flat }; } namespace CopyMode{ enum CopyMode{ // source push to destination Push, // destination pull from source Pull }; } /// /// \brief string for Amazon private key /// typedef std::string AwsSecretKey; /// /// \brief string for Amazon public key /// typedef std::string AwsAccessKey; #ifdef __DAVIX_HAS_STD_FUNCTION /// /// \brief DataProviderFun /// /// Before each time the body is provided, the callback will be called /// once with max_size == 0. The body may have to be provided >1 time /// per request (for authentication retries etc.). /// /// For a call with max_size == 0, the callback must return zero on success /// or non-zero on error /// /// For a call with max_size > 0, the callback must return: /// <0 : error, abort request /// 0 : ignore 'buffer' contents, end of data. /// 0 < x <= buflen : buffer contains x bytes of data. */ /// typedef std::function DataProviderFun; namespace Transfer{ enum Type{ Read =0x00, Write =0x01, }; } /// /// \brief TransferMonitorCB /// /// /// Monitor the number of bytes transfered for an associated query /// /// url : url of the resource /// baudrate: baudrate for the transfer in bytes/second /// bytes_transfered: bytes transfered at the time of the callback called /// total_size: total size of the resource if available, can be 0 if not determined /// typedef std::function TransferMonitorCB; #endif } // Davix #endif // REQUEST_PARAMS_TYPES_HPP davix-R_0_5_0/include/davix/params/davixrequestparams.hpp000066400000000000000000000237301257152637300237540ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_REQUESTPARAMS_HPP #define DAVIX_REQUESTPARAMS_HPP #include #include #include "davix_request_params_types.hpp" #include "../auth/davixauth.hpp" /** @file davixrequestparams.hpp @author Devresse Adrien @brief C++ Davix configuration API */ #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif namespace Davix { struct RequestParamsInternal; /// /// @class RequestParams /// @brief Main container for Davix request options /// /// RequestParams hold the davix request options : /// authentification parameters, timeouts, user-agents,... /// A Requestparams object can be shared between several Request class DAVIX_EXPORT RequestParams { public: /// /// \brief default constructor /// RequestParams(); /// /// \brief copy constructor /// \param params /// RequestParams(const RequestParams & params); /// /// \brief conveniencecopy constructor with NULL check /// \param params RequestParams(const RequestParams* params); /// \brief assignment operator RequestParams & operator=(const RequestParams & _p); virtual ~RequestParams(); /// disable the certificate authority validity check for the https request void setSSLCAcheck(bool chk); /// return the SSL Certificate authority validity check bool getSSLCACheck() const; /// set a X509 credential for a simple client authentication /// this function overwrite \ref setClientCertCallbackX509 void setClientCertX509(const X509Credential & cli_cert); /// get the current client side credential const X509Credential & getClientCertX509() const; /// set login/password for HTTP Authentication void setClientLoginPassword(const std::string & login, const std::string & password); /// get login/password for HTTP Authentication const std::pair & getClientLoginPassword() const; #ifdef __DAVIX_HAS_STD_FUNCTION /// set a function for or X509 client side dynamic authentication /// this function overwrite \ref setClientCertCallbackX509 void setClientCertFunctionX509(const authFunctionClientCertX509 & callback); /// return the function const authFunctionClientCertX509 & getClientCertFunctionX509() const; #endif /// set a callback for X509 client side dynamic authentication /// this function overwrite \ref setClientCertX509 void setClientCertCallbackX509(authCallbackClientCertX509 callback, void* userdata); /// return the current client side callback for authentication with the associated user data std::pair getClientCertCallbackX509() const; /// set a callback for basic login/password http authentication /// this function overwrite \ref setClientLoginPassword void setClientLoginPasswordCallback(authCallbackLoginPasswordBasic callback, void* userdata); /// return the current login/password callback and the associated user data std::pair getClientLoginPasswordCallback() const; /// /// \brief define a Amazon S3 private key and public key /// \param secret_key secret key /// \param access_key public key /// void setAwsAuthorizationKeys(const AwsSecretKey & secret_key, const AwsAccessKey & access_key); /// /// \brief get Amazon S3 authentication tokens /// \return pair of secret key and public key /// const std::pair & getAwsAutorizationKeys() const; /// set listing mode flag for S3 bucket void setS3ListingMode(const S3ListingMode::S3ListingMode s3_listing_mode); /// get listing mode flag for S3 bucket S3ListingMode::S3ListingMode getS3ListingMode() const; /// set maximum number of key entries return by S3 list object request void setS3MaxKey(const unsigned long s3_max_key_entries); /// get maximun number of key entries return by S3 list object request unsigned long getS3MaxKey() const; /// add the CA certificate in the directory 'path' as trusted certificate void addCertificateAuthorityPath(const std::string & path); /// get the list of the current user defined CA path const std::vector & listCertificateAuthorityPath() const; /// define the connexion timeout /// conn_timeout is a relative time /// DEFAULT : 30s void setConnectionTimeout(struct timespec* conn_timeout); /// get the current connexion timeout const struct timespec * getConnectionTimeout() const; /// define the maximum execution time for a davix request /// ops_timeout is a relative time /// DEFAULT : infinite void setOperationTimeout(struct timespec* ops_timeout); /// get the maximum execution time for a davix request /// DEFAULT : infinite const struct timespec * getOperationTimeout()const; /// enable or disable transparent redirection support /// In the transparent redirection mode, /// davix follows the HTTP redirection automatically /// DEFAULT : enabled void setTransparentRedirectionSupport(bool redirection); /// return true if the transparent redirection mode is enabled bool getTransparentRedirectionSupport() const; /// /// \brief number of re-try in case of operation failure /// \param number_retry /// /// define the number of retry attempt in case of an operation failure void setOperationRetry(int number_retry); /// /// \brief getOperationRetry /// \return /// get current number of retry attempt, see \ref setOperationRetry for more details int getOperationRetry() const; /// /// \brief Delay in second between retry attempts ///// \param delay_retry /// /// define the number of seconds between retry attempts in case of slow servers void setOperationRetryDelay(int delay_retry); /// /// \brief getOperationRetryDelay /// \return /// get current number of seconds between retry attempts, see \ref setOperationRetryDelay for more details int getOperationRetryDelay() const; /// set copy mode for 3rd party copy void setCopyMode(const CopyMode::CopyMode copy_mode); /// get copy mode for 3rd party copy CopyMode::CopyMode getCopyMode() const; /// set recursive mode for directory operations void setRecursiveMode(const bool recursive_mode); /// get recursive mode for directory operations bool getRecursiveMode() const; #ifdef __DAVIX_HAS_STD_FUNCTION /// /// @brief setTransfertMonitorCb /// @param cb /// /// define a transfer callback /// The transfer callback is called on a regular based /// when a data transfer operation is progressing ( put, get, copy ) /// /// The callback is called at least once per transfer for the following operations : /// - DavFile::put /// - DavixFile::get / getV /// - Posix::read / pread / write / prwrite / preadVec /// /// void setTransfertMonitorCb(const TransferMonitorCB & cb); /// /// \brief getTransferMonitorCb /// \return current transfer monitor callback /// /// see \ref setTransfertMonitorCb for more details /// const TransferMonitorCB & getTransferMonitorCb() const; #endif //__DAVIX_HAS_STD_FUNCTION /// set the user agent for the associated request void setUserAgent(const std::string & user_agent); /// get the current user agent string const std::string & getUserAgent() const; /// set the request protocol ( ex : Webdav, Http-only, S3 ) void setProtocol(const RequestProtocol::Protocol proto); /// get the current value of the request protocol RequestProtocol::Protocol getProtocol() const; /// Enable or disable the usage of the Metalink /// (RFC-5854 and RFC-6249) with libdavix /// Metalink can be used for fail-over purpose, or multi-source download void setMetalinkMode( const MetalinkMode::MetalinkMode mode); /// get the Current Metalink mode MetalinkMode::MetalinkMode getMetalinkMode() const; /// set the keep alive value of the associated session void setKeepAlive(const bool keep_alive_flag); /// get the keep alive value of this request params bool getKeepAlive() const; /// Add a custom header line that has to be included in the requests /// @param key key of the header /// @param val value of the header void addHeader(const std::string &key, const std::string &val); /// return the list of custom headers configured const HeaderVec & getHeaders() const; /// set a SOCKS5 proxy server for intermediate usage /// example: setProxyServer("socks5://login:password@socks5.exmaple.org:8080") /// @param proxy_url url of the proxy server void setProxyServer(const Uri & proxy_url); /// get current SOCKS5 proxy server /// @return URL of the server or NULL if not defined const Uri* getProxyServer() const; /// internal usage void* getParmState() const; /// swap two RequestParams content /// fast operation void swap(RequestParams & params); private: // dptr RequestParamsInternal* d_ptr; }; } // namespace Davix #endif // DAVIX_REQUESTPARAMS_HPP davix-R_0_5_0/include/davix/request/000077500000000000000000000000001257152637300175135ustar00rootroot00000000000000davix-R_0_5_0/include/davix/request/httprequest.hpp000066400000000000000000000340341257152637300226200ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_HTTPREQUEST_H #define DAVIX_HTTPREQUEST_H #include #include #include #include #include #include #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif /** @file httprequest.hpp @author Devresse Adrien @brief Http low level request interface */ namespace Davix { /// Callback for body providers /// Before each time the body is provided, the callback will be called /// once with buflen == 0. The body may have to be provided >1 time /// per request (for authentication retries etc.). /// For a call with buflen > 0, the callback must return: /// <0 : error, abort request; session error string must be set. /// 0 : ignore 'buffer' contents, end of body. /// 0 < x <= buflen : buffer contains x bytes of body data. */ typedef dav_ssize_t (*HttpBodyProvider)(void *userdata, char *buffer, dav_size_t buflen); /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// class NEONRequest; class NEONSessionFactory; class HttpCacheToken; namespace RequestFlag{ /// /// \brief Request flag /// /// enum RequestFlag{ SupportContinue100 = 0x01, /**< Enable support for 100 Continue code (default: OFF) */ IdempotentRequest = 0x02 /**< Specifie the request as Idempotent ( default : ON) */ }; } /// @class HttpRequest /// @brief Http low level request interface. /// /// HTTPRequest is the main davix class for low level HTTP queries. /// /// HTTPRequest objects are provided by Davix::Context /// class DAVIX_EXPORT HttpRequest : private NonCopyable { public: /// /// \brief HttpRequest constructor with a defined URL /// \param context davix context /// \param url URL of the resource /// \param err Davix error report system /// /// @snippet example_code_snippets.cpp HttpRequest uri HttpRequest(Context & context, const Uri & url, DavixError** err); /// /// \brief HttpRequest constructor with a defined URL from a string /// \param context davix context /// \param url URL of the resource /// \param err Davix error report system /// /// @snippet example_code_snippets.cpp HttpRequest HttpRequest(Context & context, const std::string & url, DavixError** err); /// /// \brief HttpRequest internal usage /// \param req /// HttpRequest(NEONRequest* req); virtual ~HttpRequest(); /// add a optional HTTP header request /// replace an existing one if already exist /// if the content of value of the header field is empty : remove an existing one /// @param field header field name /// @param value header field value /// /// @snippet example_code_snippets.cpp HttpRequest::addHeaderField void addHeaderField(const std::string & field, const std::string & value); /// /// \brief set the request method ( "GET", "PUT", ... ) /// \param method request method /// /// @snippet example_code_snippets.cpp HttpRequest::setRequestMethod void setRequestMethod(const std::string & method); /// /// \brief set the request parameter /// \param parameters Davix Request parameters /// /// define the request parameters, can be used to define parameters /// such as authentication scheme, timeout or user agent. /// /// @snippet example_code_snippets.cpp HttpRequest::setParameters void setParameters(const RequestParams ¶meters); /// @brief execute this request completely /// /// the answer is accessible with \ref Davix::HttpRequest::getAnswerContent /// @param err davix error report /// @return 0 on success /// /// @snippet example_code_snippets.cpp HttpRequest::executeRequest int executeRequest(DavixError** err); /// /// set the content of the request from a string /// an empty string set no request content /// @warning this string is not duplicated internally for performance reasons /// /// @snippet example_code_snippets.cpp HttpRequest::setRequestBody void setRequestBody(const std::string & body); /// /// set the content of the request from a buffer /// NULL pointer means a empty content /// /// @snippet example_code_snippets.cpp HttpRequest::setRequestBody void setRequestBody(const void * buffer, dav_size_t len_buff); /// /// set the content of the request from a file descriptor /// start at offset and read a maximum of len bytes /// /// @snippet example_code_snippets.cpp HttpRequest::setRequestBody void setRequestBody(int fd, dav_off_t offset, dav_size_t len); /// /// set a callback to provide the body of the requests /// void setRequestBody(HttpBodyProvider provider, dav_size_t len, void* udata); /// /// @brief start a multi-part HTTP Request /// /// the multi-part HTTP Request of davix /// should be used for request with a large answer /// /// /// @param err : DavixError error report system /// @return return 0 if success, or a negative value if an error occures /// /// @snippet example_code_snippets.cpp HttpRequest::beginRequest int beginRequest(DavixError** err); /// /// read a block of a maximum size bytes in the answer /// can return < max_size bytes depending of the data available /// /// @param buffer : buffer to fill /// @param max_size : maximum number of byte to read /// @param err : DavixError error report system /// @return number of bytes readed /// /// @snippet example_code_snippets.cpp HttpRequest::readBlock dav_ssize_t readBlock(char* buffer, dav_size_t max_size, DavixError** err); /// /// read a block of a maximum size bytes in the answer into buffer /// can return < max_size bytes depending of the data available /// /// @param buffer : vector to fill /// @param max_size : maximum number of byte to read /// @param err : DavixError error report system /// @return number of bytes readed /// /// @snippet example_code_snippets.cpp HttpRequest::readBlock dav_ssize_t readBlock(std::vector & buffer, dav_size_t max_size, DavixError** err); /// /// read a segment of size bytes, return always max_size excepted if the end of the content is reached /// /// @param buffer : vector to fill /// @param max_size : maximum number of byte to read /// @param err : DavixError error report system /// @return number of bytes readed /// /// @snippet example_code_snippets.cpp HttpRequest::readSegment dav_ssize_t readSegment(char* buffer, dav_size_t max_size, DavixError** err); /// /// write the full answer content to the given file descriptor /// @param fd : buffer to fill /// @param err : DavixError error report system /// @return number of bytes read /// /// @snippet example_code_snippets.cpp HttpRequest::readToFd dav_ssize_t readToFd(int fd, DavixError** err); /// /// write the first 'read_size' first bytes to the given file descriptor /// @param fd : buffer to fill /// @param read_size : number of bytes to read /// @param err : DavixError error report system /// @return number of bytes read /// /// @snippet example_code_snippets.cpp HttpRequest::readToFd dav_ssize_t readToFd(int fd, dav_size_t read_size, DavixError** err); /// /// read a line of text of a maximum size bytes in the answer /// @param buffer : buffer to fill /// @param max_size : maximum number of bytes to read /// @param err : DavixError error report system /// @return number of bytes readed, if return == max_size -> the line too big /// /// @snippet example_code_snippets.cpp HttpRequest::readLine dav_ssize_t readLine(char* buffer, dav_size_t max_size, DavixError** err); /// /// discard the response body /// @param err: DavixError error report system /// /// @snippet example_code_snippets.cpp HttpRequest::discardBody void discardBody(DavixError** err); /// /// finish a request stated with beginRequest /// /// @snippet example_code_snippets.cpp HttpRequest::endRequest int endRequest(DavixError** err); /// return the body of the answer /// /// @snippet example_code_snippets.cpp HttpRequest::getAnswerContent const char* getAnswerContent(); /// return the body of the answer in a vector /// /// @snippet example_code_snippets.cpp HttpRequest::getAnswerContentVec std::vector & getAnswerContentVec(); /// get content length /// @return content size, return -1 if chunked /// /// @snippet example_code_snippets.cpp HttpRequest::getAnswerSize dav_ssize_t getAnswerSize() const; /// get last modified time /// /// @snippet example_code_snippets.cpp HttpRequest::getLastModified time_t getLastModified() const; /// /// clear the current result /// /// @snippet example_code_snippets.cpp HttpRequest::clearAnswerContent void clearAnswerContent(); /// /// @return current request code error /// undefined if executeRequest or beginRequest has not be called before /// /// @snippet example_code_snippets.cpp HttpRequest::getRequestCode int getRequestCode(); /// /// get the value associated to a header key in the request answer /// @param header_name : key of the header field /// @param value : reference of the string to set /// @return true if this header exist or false if it does not /// /// @snippet example_code_snippets.cpp HttpRequest::getAnswerHeader bool getAnswerHeader(const std::string & header_name, std::string & value) const; /// /// get all the headers associated with this answer /// @param value : vector of headers /// @return true if this header exist or false if it does not /// /// @snippet example_code_snippets.cpp HttpRequest::getAnswerHeaders size_t getAnswerHeaders( HeaderVec & vec_headers) const; /// @deprecated not in use anymore DEPRECATED(HttpCacheToken* extractCacheToken() const); /// @deprecated not in use anymore DEPRECATED(void useCacheToken(const HttpCacheToken* token)); /// set a HttpRequest flag void setFlag(const RequestFlag::RequestFlag flag, bool value); /// get a HttpRequest flag value bool getFlag(const RequestFlag::RequestFlag flag); private: NEONRequest* d_ptr; void runPreRunHook(); void runRegisterHooks(); friend class NEONRequest; friend class NEONSessionFactory; }; /// @class GetRequest /// @brief Http low level request configured for GET operation class GetRequest : public HttpRequest{ public: /// /// \brief Construct a HttpRequest for GET a operation /// \param context /// \param uri /// \param err /// /// @snippet example_code_snippets.cpp HttpRequest::GetRequest GetRequest(Context & context, const Uri & uri, DavixError** err); }; /// @class PutRequest /// @brief Http low level request configured for PUT operation class PutRequest : public HttpRequest{ public: /// /// \brief Construct a HttpRequest for PUT a operation /// \param context /// \param uri /// \param err /// /// @snippet example_code_snippets.cpp HttpRequest::PutRequest PutRequest(Context & context, const Uri & uri, DavixError** err); }; /// @class PostRequest /// @brief Http low level request configured for POST operation class PostRequest : public HttpRequest{ public: /// /// \brief Construct a HttpRequest for POST a operation /// \param context /// \param uri /// \param err /// /// @snippet example_code_snippets.cpp HttpRequest::PutRequest PostRequest(Context & context, const Uri & uri, DavixError** err); }; /// @class HeadRequest /// @brief Http low level request configured for HEAD operation class HeadRequest : public HttpRequest{ public: /// /// \brief Construct a HttpRequest for a HEAD operation /// \param context /// \param uri /// \param err /// /// @snippet example_code_snippets.cpp HttpRequest::HeadRequest HeadRequest(Context & context, const Uri & uri, DavixError** err); }; /// @class DeleteRequest /// @brief Http low level request configured for DELETE operation class DeleteRequest : public HttpRequest{ public: /// /// \brief Construct a HttpRequest forfor a DELETE operation /// \param context /// \param uri /// \param err /// /// @snippet example_code_snippets.cpp HttpRequest::DeleteRequest DeleteRequest(Context & context, const Uri & uri, DavixError** err); }; /// @class PropfindRequest /// @brief Webdav low level request configured for PROPFIND operation class PropfindRequest : public HttpRequest{ public: /// /// \brief Construct a HttpRequest for a PROPFIND operation /// \param context /// \param uri /// \param err /// /// @snippet example_code_snippets.cpp HttpRequest::PropfindRequest PropfindRequest(Context & context, const Uri & uri, DavixError** err); }; } #endif // DAVIX_HTTPREQUEST_H davix-R_0_5_0/include/davix/status/000077500000000000000000000000001257152637300173465ustar00rootroot00000000000000davix-R_0_5_0/include/davix/status/davixstatusrequest.hpp000066400000000000000000000232411257152637300240510ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_DAVIXSTATUSREQUEST_HPP #define DAVIX_DAVIXSTATUSREQUEST_HPP #include #include #include /** @file davixstatusrequest.hpp @author Devresse Adrien, CERN @brief Error report system of davix */ #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif namespace Davix { class Context; class NGQRequest; struct DavixErrorInternal; namespace StatusCode{ /// Common Error code of Davix /// See \ref DavixError for more details /// enum Code { /// No Error report OK = 0x000, /// Request executed partially PartialDone = 0x001, /// Error in the Webdav properties parsing WebDavPropertiesParsingError = 0x002, /// Error in the Webdav properties parsing UriParsingError = 0x003, /// impossible to create a session SessionCreationError = 0x004, /// DNS resolution failure NameResolutionFailure= 0x005, /// Impossible to connect, host down or network problem ConnectionProblem = 0x006, /// redirection is needed manually RedirectionNeeded = 0x007, /// Impossible to connect, host down or network problem ConnectionTimeout = 0x008, /// operation timeout OperationTimeout = 0x009, /// this operation is not supported OperationNonSupported= 0x00a, /// Action impossible, is a directory or a collection IsNotADirectory = 0x00b, /// Invalid file descriptor InvalidFileHandle = 0x00c, /// Request already running AlreadyRunning = 0x00d, /// Authentication Error AuthenticationError= 0x00e, /// Wrong Login and/or Password LoginPasswordError = 0x00f, /// Impossible to find specified credential CredentialNotFound = 0x010, /// Permission deny, Authorisation problem ( EACCESS, EPERM ) PermissionRefused = 0x011, /// File not found (ENOENT ) FileNotFound = 0x012, /// This file is not a regular file but a directory ( EISDIR ) IsADirectory = 0x013, /// System call related error SystemError = 0x014, /// File already exist ( EEXIST ) FileExist = 0x015, /// Invalid argument from user ( EINVAL ) InvalidArgument = 0x016, /// Server answer problem ( > 500 ) InvalidServerResponse = 0x017, /// SSL/TLS layer Error SSLError = 0x018, /// Impossible to decrypt client credential for usage CredDecryptionError = 0x019, /// Operation canceled Canceled = 0x020, /// Delegation error DelegationError = 0x021, /// Remote error. Used for third party copies: it means the /// destination failed. RemoteError = 0x022, /// Generic Parsing Error ParsingError = 0x23, /// Invalid Hook type InvalidHook = 0x24, /// Connection timeout during a redirection TimeoutRedirectionError = 0x25, /// Undefined error UnknowError = 0x100 }; } /// @class DavixError /// @brief Davix Error Handler /// /// Error report system of Davix, similar behavior to the Glib Error report /// Davix does not use C++ exception /// /// /// Each function which takes a DavixError** as argument can take the value NULL /// /// Example : /// /// class DAVIX_EXPORT DavixError{ public: /// /// Construct a DavixError object /// /// @param scope : string parameter representing the scope of the error /// @param errCode : Davix Error code, see Davix::StatusCode::Code /// @param errMsg : String representation of the error DavixError(const std::string & scope, StatusCode::Code errCode, const std::string & errMsg); /// /// \brief copy constructor /// \param e /// DavixError(const DavixError & e); /// /// \brief assignment operator /// \param e /// \return /// DavixError & operator=(const DavixError & e); /// /// \brief ~DavixError /// virtual ~DavixError(); /// /// \brief clone Error /// \return new dynamically allocated copy of the Error /// DavixError* clone(); /// /// @return Davix status code of the error StatusCode::Code getStatus() const; /// /// set the status code for this error void setStatus(const StatusCode::Code); /// /// get the string representation of this error const std::string & getErrMsg() const; /// /// set the string representation of this error void setErrMsg(const std::string & msg); /// /// set the scope of this error void setErrScope(const std::string & scope); /// /// get the scope of this error const std::string & getErrScope() const; /// /// \brief create a new DavixError /// \param err pointer to a DavixError pointer /// \param scope scope of the Error /// \param errCode Error code /// \param errMsg Error message /// /// /// create a new dynamically allocated DavixError Object /// if err is NULL, silent suppress the error report static void setupError(DavixError** err, const std::string & scope, StatusCode::Code errCode, const std::string & errMsg); /// /// clear the content of the current error and set err to NULL static void clearError(DavixError** err); /// /// \brief propagate an Error structure to an upper level /// \param newErr /// \param oldErr /// /// propagate the Davix Error Object from oldErr to newErr /// OldErr can be consider as free after this operation /// erase the current error if newErr is not NULL /// static void propagateError(DavixError** newErr, DavixError* oldErr); //// /// \brief swap the two error content /// \param err /// void swap(DavixError & err); /// /// \brief propagatePrefixedError /// \param newErr /// \param oldErr /// \param prefix /// /// same than propagateError but add a string prefix in front of the error description /// ////// static void propagatePrefixedError(DavixError** newErr, DavixError* oldErr, const std::string & prefix); private: DavixErrorInternal * d_ptr; }; /// @class DavixException /// @brief Davix Exception class /// /// Contain a Davix Error /// /// class DAVIX_EXPORT DavixException : public std::exception{ struct DavixExceptionIntern; public: /// Construct a DavixException DavixException(const std::string & scope, StatusCode::Code c, const std::string & msg) throw(); /// Create a DavixEception from a DavixError, err is considered as free and invalid after creation DavixException(DavixError** err); /// Copy Constructor DavixException(const DavixException & orig) throw(); virtual ~DavixException() throw(); /// return a string representation of the scope for this davix exception virtual const char* scope() const throw(); /// return the error code association to this DavixException, same than @ref DavixError::getStatus() virtual StatusCode::Code code() const throw(); /// return a string representation or the error virtual const char* what() const throw(); /// Extract a DavixError from this exception void toDavixError(DavixError** err); protected: DavixError e; DavixExceptionIntern* d_ptr; }; void checkDavixError(DavixError** err); #define TRY_DAVIX try #define CATCH_DAVIX(err) catch(DavixException & e){ \ e.toDavixError(err); \ }catch(std::exception & e){ \ DavixError::setupError(err, " ", StatusCode::SystemError, std::string("System Error ").append(e.what())); \ }catch(...){ \ DavixError::setupError(err, " ", StatusCode::UnknowError, std::string("Unknow Error .... report this")); \ } /// \cond PRIVATE_SYMBOLS /// DAVIX_EXPORT std::string davix_scope_stat_str(); DAVIX_EXPORT std::string davix_scope_davOps_str(); DAVIX_EXPORT std::string davix_scope_mkdir_str(); DAVIX_EXPORT std::string davix_scope_rm_str(); DAVIX_EXPORT std::string davix_scope_mv_str(); DAVIX_EXPORT std::string davix_scope_directory_listing_str(); DAVIX_EXPORT std::string davix_scope_http_request(); DAVIX_EXPORT std::string davix_scope_meta(); DAVIX_EXPORT std::string davix_scope_xml_parser(); DAVIX_EXPORT std::string davix_scope_uri_parser(); DAVIX_EXPORT std::string davix_scope_io_buff(); DAVIX_EXPORT std::string davix_scope_x509cred(); // DAVIX_EXPORT void davix_errno_to_davix_error(int errcode, const std::string & scope, const std::string & msg, DavixError** newErr); DAVIX_EXPORT void errno_to_davix_exception(int errno_code, const std::string & scope, const std::string & msg); // !!!!!!!!!!!!!!!!!!! // Warning: Deprecated symbols, do not use anymore // ///////////////////////////////////////////////// // Deprecated, do not use, API compability only namespace StatusCode{ const Code AuthentificationError = AuthenticationError; } typedef enum StatusCode::Code davix_status_t; /// \endcond PRIVATE_SYMBOLS } // namespace Davix #endif // DAVIX_DAVIXSTATUSREQUEST_H davix-R_0_5_0/include/davix/utils/000077500000000000000000000000001257152637300171635ustar00rootroot00000000000000davix-R_0_5_0/include/davix/utils/davix_config.hpp000066400000000000000000000056011257152637300223360ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_CONFIG #define DAVIX_CONFIG #include #ifndef __DAVIX_INSIDE__ #error "Only davix.hpp should be included." #endif // // export // #ifndef DAVIX_EXPORT #define DAVIX_EXPORT __attribute__((visibility("default"))) #endif // // detect GCC // #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) # ifndef __DAVIX_COMPILER_GCC # define __DAVIX_COMPILER_GCC # endif #endif // // detect CXX11 support // #if ( (__cplusplus > 199711L) \ || (defined (DAVIX_FORCE_CXX11)) \ || (defined __GXX_EXPERIMENTAL_CXX0X__) ) # ifndef __DAVIX_CX11_SUPPORT # define __DAVIX_CX11_SUPPORT # endif #endif // // detect TR1 support // #if ( (defined DAVIX_FORCE_TR1) \ || (defined __DAVIX_COMPILER_GCC) \ || (defined HAVE_TR1_SUPPORT)) # ifndef __DAVIX_TR1_SUPPORT # define __DAVIX_TR1_SUPPORT #endif #endif // // include tr1 namespace // #if (!(defined __DAVIX_CX11_SUPPORT) \ && (defined __DAVIX_TR1_SUPPORT)) # include # include namespace std{ using namespace std::tr1; } #endif // // enable STD_FUNCTION_DECL // #if ((defined __DAVIX_CX11_SUPPORT) \ || (defined __DAVIX_TR1_SUPPORT) \ || (defined HAVE_STD_FUNCTION)) # ifndef __DAVIX_HAS_STD_FUNCTION # define __DAVIX_HAS_STD_FUNCTION # endif #endif // // davix preproc facilities // #undef DAVIX_C_DECL_BEGIN #undef DAVIX_C_DECL_END #ifdef __cplusplus #define DAVIX_C_DECL_BEGIN \ extern "C" { #define DAVIX_C_DECL_END } #else #define DAVIX_C_DECL_BEGIN // void #define DAVIX_C_DECL_END // void #endif // // compat 32 bits #if (( __WORDSIZE == 32 ) \ || ( SIZE_MAX == (4294967295U) )) \ && !(defined __DAVIX_COMPAT_32) \ && !(defined __NO_DAVIX_COMPAT_32) #define __DAVIX_COMPAT_32 #endif // // deprecated #undef DEPRECATED #ifdef __GNUC__ #define DEPRECATED(func) func __attribute__ ((deprecated)) #else #define DEPRECATED(func) func #endif #endif // DAVIX_TYPES_HPP davix-R_0_5_0/include/davix/utils/davix_logger.hpp000066400000000000000000000104641257152637300223530ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_LOGGER_HPP #define DAVIX_LOGGER_HPP #include #include namespace Davix{ // log level #define DAVIX_LOG_CRITICAL 1 #define DAVIX_LOG_WARNING 2 #define DAVIX_LOG_VERBOSE 3 #define DAVIX_LOG_DEBUG 4 #define DAVIX_LOG_TRACE 5 #define DAVIX_LOG_ALL 6 // log scope #define DAVIX_LOG_FILE (1<<0) #define DAVIX_LOG_POSIX (1<<1) #define DAVIX_LOG_XML (1<<2) #define DAVIX_LOG_SSL (1<<3) #define DAVIX_LOG_HEADER (1<<4) #define DAVIX_LOG_BODY (1<<5) #define DAVIX_LOG_CHAIN (1<<6) #define DAVIX_LOG_CORE (1<<7) #define DAVIX_LOG_GRID (1<<8) #define DAVIX_LOG_SOCKET (1<<9) #define DAVIX_LOG_LOCKS (1<<10) #define DAVIX_LOG_HTTP (1<<11) #define DAVIX_LOG_SCOPE_NEON (1<<29) #define DAVIX_LOG_SCOPE_ALL (~(0) ^ DAVIX_LOG_BODY) // define string for log scopes extern const char* SCOPE_FILE; // Davix file interface extern const char* SCOPE_HTTP; // Http Request Scope extern const char* SCOPE_POSIX; // Davix posix interface extern const char* SCOPE_XML; // XML info and parser output extern const char* SCOPE_SSL; // SSL and cert details extern const char* SCOPE_HEADER; // Request and respond headers extern const char* SCOPE_BODY; // HTTP bodies extern const char* SCOPE_CHAIN; // IO chains info extern const char* SCOPE_CORE; // Config and misc info extern const char* SCOPE_GRID; // Misc info from 3rd parties extern const char* SCOPE_SOCKET; // Socket info extern const char* SCOPE_LOCKS; // WebDAV locking info extern const char* SCOPE_ALL; // All of the above // log a string to the Davix logger system void logStr(int scope, int log_level, const std::string & str); /// /// \brief getLogLevel /// \return current davix Logger level /// int getLogLevel(); /// /// \brief setLogLevel /// \param logLevel /// /// define davix logger level void setLogLevel(int logLevel); /// /// \brief getLogScope /// \return current davix scope mask /// int getLogScope(); /// /// \brief setLogScope /// /// define davix scope mask. /// Only the componnents covered by the mask will be available via the logging void setLogScope(int mask); /// /// \brief setLogScope /// \param scope /// define davix scope mask from a list of string separated by comma void setLogScope(const std::string & scope); /// /// \brief getScopeName /// \param scope_mask /// \return scope name of the first scope that match the mask /// if none match, return ALL /// std::string getScopeName(int scope_mask); } // Davix DAVIX_C_DECL_BEGIN /// set the davix log mask /// everything that is not coverred by the mask is dropped extern DAVIX_EXPORT void davix_set_log_level(int log_mask); /// get current log mask extern DAVIX_EXPORT int davix_get_log_level(); /// internal logger function extern DAVIX_EXPORT void davix_logger(int log_mask, const char * msg, ...); /// variadic version of internal logger function extern DAVIX_EXPORT void davix_vlogger(int log_mask, const char* msg, va_list args); /// @brief setup a log handler /// /// redirect the davix log output to the function f_handler /// setting up a log handler disable the std output log /// /// @param fhandler : log handler callback /// @param userdata : callback userdata extern DAVIX_EXPORT void davix_set_log_handler( void (*fhandler)(void* userdata, int mgs_level, const char* msg), void* userdata); DAVIX_C_DECL_END #endif // DAVIX_LOGGER_H davix-R_0_5_0/include/davix/utils/davix_nocopy.hpp000066400000000000000000000024101257152637300223730ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #pragma once #ifndef DAVIX_NOCOPY_HPP #define DAVIX_NOCOPY_HPP /// @class NonCopyable /// @brief Simple NonCopyableProtector class NonCopyable{ protected: NonCopyable() {} ~NonCopyable() {} private: // emphasize the following members are private NonCopyable( const NonCopyable& ); const NonCopyable& operator=( const NonCopyable& ); }; #endif // DAVIX_NOCOPY_HPP davix-R_0_5_0/include/davix/utils/davix_s3_utils.hpp000066400000000000000000000032551257152637300226410ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_S3_UTILS_HPP #define DAVIX_S3_UTILS_HPP #include namespace Davix{ namespace S3{ void signRequest(const RequestParams & params, const std::string & method, const Uri & url, HeaderVec & headers); Uri tokenizeRequest(const RequestParams & params, const std::string & method, const Uri & url, HeaderVec & headers, time_t expirationTime); Uri s3UriTransformer(const Uri & original_url, const RequestParams & params, const bool addDelimiter); time_t s3TimeConverter(std::string &s3time); std::string hexPrinter(const unsigned char* data, dav_size_t nbytes); // MD5 from string int calculateMD5(std::string &input, std::string &output); // MD5 from fd int calculateMD5(int fd, std::string &output); } // S3 } // Davix #endif // DAVIX_S3_UTILS_HPP davix-R_0_5_0/include/davix/utils/davix_types.hpp000066400000000000000000000043511257152637300222360ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_TYPES_HPP #define DAVIX_TYPES_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "davix_config.hpp" #include "davix_nocopy.hpp" #ifndef __DAVIX_INSIDE__ #error "Only davix.hpp should be included." #endif // type decl #ifndef DAVIX_EXPORT #define DAVIX_EXPORT __attribute__((visibility("default"))) #endif struct Davix_context; struct Davix_error; // alias typedef struct Davix_context* davix_sess_t; typedef struct Davix_error* davix_error_t; typedef struct davix_file_desc_s* davix_file_desc_t; typedef struct davix_auth_st* davix_auth_t; typedef struct davix_request_params* davix_params_t; // Davix types typedef uint64_t dav_size_t; typedef int64_t dav_ssize_t; #ifdef __DAVIX_COMPAT_32 // defined only for 32 bits arc and abi compat typedef uint64_t dav_off_t; #else typedef int64_t dav_off_t; #endif // block size #define DAVIX_BLOCK_SIZE 4096 #define DAVIX_MAX_BLOCK_SIZE 16777216 namespace Davix{ // Davix namespace declaration typedef std::pair HeaderLine; typedef std::vector< HeaderLine > HeaderVec; } // Davix #endif // DAVIX_TYPES_HPP davix-R_0_5_0/include/davix/utils/davix_uri.hpp000066400000000000000000000113031257152637300216640ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #pragma once #ifndef DAVIX_DAVIXURI_HPP #define DAVIX_DAVIXURI_HPP #include #include #include /** @file davix_uri.hpp @author Devresse Adrien @brief URI utilities functions for davix */ #ifndef __DAVIX_INSIDE__ #error "Only davix.h or davix.hpp should be included." #endif namespace Davix { struct UriPrivate; /// @class Uri /// @brief Uri parser /// /// convenience class for uri parsing /// /// @snippet example_code_snippets.cpp Uri example class DAVIX_EXPORT Uri { public: /// Construct an empty invalid Uri Uri(); /// construct a new Davix Uri from a string URL Uri(const std::string & uri_string); /// Copy constructor Uri(const Uri & uri); /// /// \brief assignment operator /// \param orig /// \return /// Uri & operator=(const Uri & orig); virtual ~Uri(); /// get a string representation of the full uri /// @return return the path or an empty string if error const std::string & getString() const; /// get the port number /// @return return the prot number of 0 if unspecified int getPort() const; /// get the protocol scheme /// @return return the protocol scheme or an empty string if error const std::string & getProtocol() const; /// get the host name /// @return return the hostname or an empty string if error const std::string & getHost() const; /// get the path part of the Uri /// @return return the path of the Uri or an empty string if error const std::string & getPath()const; /// gextract user information from the URI /// @return return the path of the Uri or an empty string if error const std::string & getUserInfo() const; /// get a concatenation of the path and the query argument of the URI /// @return return a path + query arguments concatenation or an empty string if error const std::string & getPathAndQuery() const; /// get the query argument part of the uri /// @return return the query path string or an empty string if not exist or if error const std::string & getQuery() const; /// Status of the Uri /// see StatusCode::Code /// @return StatusCode::OK if success or StatusCode::UriParsingError if error StatusCode::Code getStatus() const; /// /// \brief test if two URI are equals /// \param u1 /// \return true if equal, else false /// bool equal(const Uri & u1) const; /// /// \brief compare oepration /// \param u2 /// \return true if u2 == current uri /// bool operator==(const Uri & u2) const; /// /// \brief Escape string /// \param str URL to escape /// \return encoded string /// static std::string escapeString(const std::string & str); /// /// \brief Unescape urI /// \param str URL to escape /// \return unencoded string /// static std::string unescapeString(const std::string & str); /// /// \brief create a new Uri from URI and a relative associated path /// \param uri original URI /// \param relPath relative path /// \return new URI from this path /// static Uri fromRelativePath(const Uri & uri, const std::string & relPath); private: UriPrivate* d_ptr; void _init(); }; /// /// check the validity of a Davix::Uri /// @param uri : davix uri /// @param err : Davix Error report object /// @return true if the uri is valid, or false and setup err with a string expression bool DAVIX_EXPORT uriCheckError(const Uri & uri, DavixError ** err); /// return associated std port for this request /// return default http port or default SSL port if not precised unsigned int DAVIX_EXPORT httpUriGetPort(const Uri & uri); std::ostream& operator<< (std::ostream& stream, const Davix::Uri & _u); } // namespace Davix #endif // DAVIX_DAVIXURI_HPP davix-R_0_5_0/packaging/000077500000000000000000000000001257152637300152115ustar00rootroot00000000000000davix-R_0_5_0/packaging/CMakeLists.txt000066400000000000000000000003211257152637300177450ustar00rootroot00000000000000# configure packaging files configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/rpm/specs/davix.spec.in" "${CMAKE_CURRENT_SOURCE_DIR}/rpm/specs/davix.spec" @ONLY ) davix-R_0_5_0/packaging/Makefile000066400000000000000000000044021257152637300166510ustar00rootroot00000000000000NAME=davix SPEC=rpm/specs/$(NAME).spec VERSION=${shell grep '^Version:' $(SPEC) | awk '{print $$2}' } # Leave blank. To be overriden by CI tools. RELEASE= CWD=${shell pwd} RPMBUILD=/tmp/rpmbuild SRPMS=$(CWD) RPMS=$(CWD)/out MOCK_CHROOT=epel-6-cernonly-x86_64 MOCK_FLAGS=--verbose RPMDEFINES_SRC=--define='_topdir $(RPMBUILD)' \ --define='_sourcedir $(CWD)' \ --define='_builddir %{_topdir}/BUILD' \ --define='_srcrpmdir $(SRPMS)' \ --define='_rpmdir $(RPMS)' \ --define "_source_filedigest_algorithm md5" \ $(RPMBUILD_SRC_EXTRA_FLAGS) RPMDEFINES_BIN=--define='_topdir $(RPMBUILD)' \ --define='_sourcedir %{_topdir}/SOURCES' \ --define='_builddir %{_topdir}/BUILD' \ --define='_srcrpmdir $(SRPMS).' \ --define='_rpmdir $(RPMS)' \ --define "_binary_filedigest_algorithm md5" \ $(RPMBUILD_BIN_EXTRA_FLAGS) PBUILDER_FLAGS= PBUILDER_TMP="/tmp/" all: srpm clean: rm -fv *.tar rm -fv *.tar.gz rm -fv *.rpm rm -fv *.log rm -rfv out rm -fv *.deb rm -fv *.xz rm -fv *.dsc rm -fv *.changes rm -rfv "$(RPMBUILD)" dist: clean tar vczf "$(NAME)-$(VERSION).tar.gz" --exclude="*.rpm" --exclude="*.gz" --exclude=".git" --exclude="*.pyc" --transform="s,^,$(NAME)-$(VERSION)/," .. $(RPMBUILD): mkdir -p "$(RPMBUILD)" override_release: $(SPEC) $(if $(RELEASE), sed -i "s/Release:.*/Release: $(RELEASE)/g" "$(SPEC)") srpm: dist $(SPEC) $(RPMBUILD) override_release /usr/bin/rpmbuild --nodeps -bs $(RPMDEFINES_SRC) $(SPEC) rpm: srpm /usr/bin/rpmbuild --rebuild $(RPMDEFINES_BIN) $(NAME)-$(VERSION)-*.src.rpm mock: srpm /usr/bin/mock $(MOCK_FLAGS) -r $(MOCK_CHROOT) $(NAME)-$(VERSION)-*.src.rpm deb-src: dist rm -rf "$(PBUILDER_TMP)/$(NAME)-$(VERSION)" tar xzf "$(NAME)-$(VERSION).tar.gz" -C "$(PBUILDER_TMP)" cp -rv debian "$(PBUILDER_TMP)/$(NAME)-$(VERSION)" $(if $(RELEASE), sed -ri "s/($(NAME) )\((([0-9]+\.)+[0-9]+)-[0-9]+\)/\\1(\\2-$(RELEASE))/g" "$(PBUILDER_TMP)/$(NAME)-$(VERSION)/debian/changelog") cp -f "$(NAME)-$(VERSION).tar.gz" "$(PBUILDER_TMP)/$(NAME)_$(VERSION).orig.tar.gz" cd "$(PBUILDER_TMP)/$(NAME)-$(VERSION)"; \ debuild -us -uc -S mv $(PBUILDER_TMP)/$(NAME)_$(VERSION)*.gz . mv $(PBUILDER_TMP)/$(NAME)_$(VERSION)*.xz . mv $(PBUILDER_TMP)/$(NAME)_$(VERSION)*.dsc . deb: deb-src pbuilder build $(PBUILDER_FLAGS) $(NAME)_$(VERSION)*.dsc davix-R_0_5_0/packaging/bin/000077500000000000000000000000001257152637300157615ustar00rootroot00000000000000davix-R_0_5_0/packaging/bin/packager_rpm.sh000077500000000000000000000053211257152637300207540ustar00rootroot00000000000000#!/bin/bash ## help tool for generic packaging # @author: Devresse Adrien ## vars BASE_TMP=/tmp FINAL_DIR="RPMS/" TARBALL_FILTER="--exclude='.git' --exclude='.svn' --exclude='RPMS' --exclude='*.rpm'" FOO="HELLO" set -e create_tmp_dir() { export TMP_DIR="$BASE_TMP/$RANDOM$RANDOM$RANDOM_$$" mkdir -p $TMP_DIR } get_attrs_spec(){ export SPEC_CONTENT="$(rpm -E "`cat $1`")" export PKG_VERSION="$( echo "$SPEC_CONTENT" | grep "Version:" | sed 's@Version:\(.*\)@\1@g' | sed -e 's/^[ \t]*//')" export PKG_RELEASE="$( echo "$SPEC_CONTENT" | grep "Version:" | sed 's@Release:\(.*\)@\1@g' | sed -e 's/^[ \t]*//')" export PKG_NAME="$(echo "$SPEC_CONTENT" | grep "Name:" | sed 's@Name:\(.*\)@\1@g' | sed -e 's/^[ \t]*//')" export SPEC_CONTENT="$(echo "$SPEC_CONTENT" | sed "s/%{name}/$PKG_NAME/g" | sed "s/%{version}/$PKG_VERSION/g" | sed "s/%{Release}/$PKG_RELEASE/g")" export PKG_SOURCE="$( echo "$SPEC_CONTENT" | grep "Source0:" | sed 's@Source0:\(.*\)@\1@g' )" export PKG_SOURCE="$( echo $PKG_SOURCE | awk -F/ '{print $NF'})" export SRC_NAME="$PKG_SOURCE" echo "res : $SRC_NAME $PKG_VERSION $PKG_NAME $PKG_SOURCE" } # src_dir, tarbal_filepath create_tarball(){ create_tmp_dir SRC_FOLDER="/$TMP_DIR/$PKG_NAME-$PKG_VERSION" mkdir -p "$SRC_FOLDER" echo "copy files..." cp -r $1/* $SRC_FOLDER/ CURRENT_DIR=$PWD cd $TMP_DIR echo "copy files..." eval "tar -cvzf $2 $TARBALL_FILTER $PKG_NAME-$PKG_VERSION" echo "tarball result : $2 $TARBALL_FILTER " cd $CURRENT_DIR rm -rf $TMP_DIR } # specfiles_dir create_rpmbuild_env(){ create_tmp_dir export RPM_BUILD_DIR="$TMP_DIR" mkdir -p $RPM_BUILD_DIR/RPMS $RPM_BUILD_DIR/SOURCES $RPM_BUILD_DIR/BUILD $RPM_BUILD_DIR/SRPMS $RPM_BUILD_DIR/SPECS $RPM_BUILD_DIR/tmp cp $1/* $RPM_BUILD_DIR/SPECS/ } # specfiles_dir delete_rpmbuild_env(){ rm -rf $RPM_BUILD_DIR/ } # specfile rpm_build_src_package(){ echo "Begin the rpmbuild source call for spec file $1 ...." local OLD_DIR=$PWD local MACRO_TOPDIR="s \"_topdir $RPM_BUILD_DIR\"" cd $RPM_BUILD_DIR ls $PWD/SOURCES/ rpmbuild -bs --nodeps --define "_topdir $RPM_BUILD_DIR" SPECS/$1 cd $OLD_DIR echo "End the rpmbuild source call...." } ## main if [[ "$1" == "" || "$2" == "" ]]; then echo "Usage $0 [spec_dir] [src_dir] " exit -1 fi create_rpmbuild_env $1 mkdir -p SRPMS # list spec file for i in $1/*.spec do echo " create RPMS for spec file : $i" get_attrs_spec $i echo "Source : $SRC_NAME" echo "Version : $PKG_VERSION" echo "Name: $PKG_NAME" echo "create source tarball..." create_tarball $2 "$RPM_BUILD_DIR/SOURCES/$SRC_NAME" echo "TARBALL: $RPM_BUILD_DIR/SOURCES/$SRC_NAME" rpm_build_src_package `basename $i` done mkdir -p $FINAL_DIR cp $RPM_BUILD_DIR/SRPMS/* $FINAL_DIR ## clean everything delete_rpmbuild_env davix-R_0_5_0/packaging/debian/000077500000000000000000000000001257152637300164335ustar00rootroot00000000000000davix-R_0_5_0/packaging/debian/changelog000066400000000000000000000027141257152637300203110ustar00rootroot00000000000000 davix (0.5.0-1) unstable; urgency=low * Update to version 0.5.0 -- DMC Devel Tue, 02 Sept 2015 10:00:00 +0200 davix (0.4.2-1) unstable; urgency=low * Update to version 0.4.2 -- DMC Devel Tue, 21 Jul 2015 10:00:00 +0200 davix (0.4.1-1) unstable; urgency=low * Update to version 0.4.1 -- DMC Devel Wed, 15 Jul 2015 10:00:00 +0200 davix (0.4.0-1) unstable; urgency=medium * Update to version 0.4.0 -- Mattias Ellert Mon, 08 Dec 2014 16:31:16 +0100 davix (0.3.6-1) unstable; urgency=medium * Update to version 0.3.6 -- Mattias Ellert Thu, 23 Oct 2014 16:02:47 +0200 davix (0.3.1-1) unstable; urgency=medium * Update to version 0.3.1 -- Mattias Ellert Tue, 08 Jul 2014 09:59:36 +0200 davix (0.2.8-1) unstable; urgency=medium * Update to version 0.2.8 -- Mattias Ellert Mon, 23 Dec 2013 04:14:45 +0100 davix (0.2.7-1) unstable; urgency=low * Update to version 0.2.7 -- Mattias Ellert Wed, 27 Nov 2013 21:54:48 +0100 davix (0.2.2-2) unstable; urgency=low * Fix copyright file -- Mattias Ellert Tue, 03 Sep 2013 09:32:50 +0200 davix (0.2.2-1) unstable; urgency=low * Initial release (Closes: #719947) -- Mattias Ellert Sat, 10 Aug 2013 03:55:47 +0200 davix-R_0_5_0/packaging/debian/compat000066400000000000000000000000021257152637300176310ustar00rootroot000000000000008 davix-R_0_5_0/packaging/debian/control000066400000000000000000000026531257152637300200440ustar00rootroot00000000000000Source: davix Priority: optional Maintainer: Mattias Ellert Build-Depends: debhelper (>= 8.0.0), cmake, libxml2-dev, libssl-dev, gsoap, libboost-system-dev, libboost-thread-dev, rapidjson-dev, libgtest-dev, abi-compliance-checker, pkg-config, doxygen Standards-Version: 3.9.6 Section: net Homepage: http://dmc.web.cern.ch/projects/davix/home Package: davix Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libdavix0 (= ${binary:Version}) Description: Toolkit for http based file management Davix is a toolkit designed for file operations with http based protocols (WebDav, Amazon S3, ...). Package: libdavix0 Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Runtime library for davix Library for davix. Davix is a toolkit designed for file operations with http based protocols (WebDav, Amazon S3, ...). Package: davix-dev Section: libdevel Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libdavix0 (= ${binary:Version}) Description: Development files for davix Development files for davix. Davix is a toolkit designed for file operations with http based protocols (WebDav, Amazon S3, ...). Package: davix-doc Section: doc Architecture: all Depends: ${misc:Depends} Description: Documentation for davix Documentation and examples for davix. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). davix-R_0_5_0/packaging/debian/copyright000066400000000000000000000123321257152637300203670ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: davix Source: http://grid-deployment.web.cern.ch/grid-deployment/dms/lcgutil/tar/davix/davix-0.4.0.tar.gz Files: * Copyright: 2012-2014 Adrien Devresse, CERN License: LGPL-2.1+ Files: deps/boost_intern Copyright: Various Authors License: Boost Comment: Not used - removed in configure - uses libboost-dev instead Files: deps/libneon Copyright: 1999-2008 Joe Orton Aleix Conchillo Flaque Arfrever Frehtes Taifersar Arahesis Arun Garg Daniel Stenberg Free Software Foundation, Inc. Henrik Holst Jiang Lei Kai Sommerfeld Karl Ove Hufthammer. Michael Sobolev Nobuyuki Tsuchimura Sylvain Glaize Thomas Schultz Vladimir Berezniker @ http://public.xdi.org/=vmpn Yves Martin 2012-2014 Adrien Devresse, CERN License: LGPL-2+ Comment: This is a fork of the neon library: http://www.webdav.org/neon/ The modifications are substantial - it can no longer be considered a bundled copy of the original source. Unbundling in favour of using the libneon27 package is not possible. Files: deps/libneon/doc deps/libneon/test Copyright: 1999-2008 Joe Orton License: GPL-2+ Files: deps/rapidjson Copyright: 2011 Milo Yip (miloyip@gmail.com) License: MIT Comment: Not used - removed in configure - uses rapidjson-dev instead Files: deps/strptime Copyright: 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. License: LGPL-2+ Comment: Not used - removed in configure - part of glibc Files: test/pywebdav Copyright: 2009 Simon Pamies 1999-2006 Christian Scholz 2009 Vince Spicer License: GPL-2+ Comment: Not used - removed in configure - could use python-webdav instead However, the functional tests thar use this require valid credentials and network access and can therefore not be run as part of the package build. Files: debian/* Copyright: 2013-2014 Mattias Ellert License: LGPL-2.1+ License: LGPL-2.1+ On Debian systems, the complete text of the GNU Library General Public License version 2.1 can be found in "/usr/share/common-licenses/LGPL-2.1". License: LGPL-2+ On Debian systems, the complete text of the GNU Library General Public License version 2 can be found in "/usr/share/common-licenses/LGPL-2". License: GPL-2+ On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". License: MIT 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License: Boost Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: . The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. . 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. davix-R_0_5_0/packaging/debian/davix-dev.install000066400000000000000000000002301257152637300217050ustar00rootroot00000000000000usr/include/davix usr/lib/libdavix.so usr/lib/libdavix_copy.so usr/lib/pkgconfig/davix.pc usr/lib/pkgconfig/davix_copy.pc usr/share/man/man3/libdavix.3 davix-R_0_5_0/packaging/debian/davix-doc.docs000066400000000000000000000000071257152637300211600ustar00rootroot00000000000000#DOCS# davix-R_0_5_0/packaging/debian/davix-doc.install000066400000000000000000000000311257152637300216730ustar00rootroot00000000000000usr/share/doc/davix/html davix-R_0_5_0/packaging/debian/davix.install000066400000000000000000000005501257152637300211360ustar00rootroot00000000000000usr/bin/davix-cp usr/bin/davix-get usr/bin/davix-http usr/bin/davix-ls usr/bin/davix-mkdir usr/bin/davix-put usr/bin/davix-rm usr/bin/davix-mv usr/share/man/man1/davix-get.1 usr/share/man/man1/davix-http.1 usr/share/man/man1/davix-ls.1 usr/share/man/man1/davix-mkdir.1 usr/share/man/man1/davix-put.1 usr/share/man/man1/davix-rm.1 usr/share/man/man1/davix-mv.1 davix-R_0_5_0/packaging/debian/libdavix0.docs000066400000000000000000000000071257152637300211640ustar00rootroot00000000000000README davix-R_0_5_0/packaging/debian/libdavix0.install000066400000000000000000000001231257152637300217010ustar00rootroot00000000000000usr/lib/libdavix.so.* usr/lib/libdavix_copy.so.* usr/share/doc/davix/RELEASE-NOTES davix-R_0_5_0/packaging/debian/patches/000077500000000000000000000000001257152637300200625ustar00rootroot00000000000000davix-R_0_5_0/packaging/debian/patches/davix-gtest.patch000066400000000000000000000007321257152637300233440ustar00rootroot00000000000000diff -ur davix-0.4.0.orig/test/unit/CMakeLists.txt davix-0.4.0/test/unit/CMakeLists.txt --- davix-0.4.0.orig/test/unit/CMakeLists.txt 2014-12-08 12:10:50.000000000 +0100 +++ davix-0.4.0/test/unit/CMakeLists.txt 2014-12-08 16:34:36.920000000 +0100 @@ -5,6 +5,8 @@ include_directories(${PROJECT_SOURCE_DIR}/src "." ${GTEST_INCLUDE_DIRS}) include_directories(${HEADER_RAPIDJSON}) +add_subdirectory(gtest) +link_directories(${CMAKE_CURRENT_BINARY_DIR}/gtest) ## alibxx davix-R_0_5_0/packaging/debian/patches/series000066400000000000000000000000231257152637300212720ustar00rootroot00000000000000davix-gtest.patch davix-R_0_5_0/packaging/debian/rules000077500000000000000000000014301257152637300175110ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- -include /usr/share/dpkg/buildflags.mk CFLAGS += $(CPPFLAGS) CXXFLAGS += $(CPPFLAGS) export CFLAGS CXXFLAGS LDFLAGS %: dh $@ override_dh_auto_configure: # Remove bundled stuff rm -rf deps/boost_intern rm -rf deps/rapidjson rm -rf deps/strptime rm -rf test/pywebdav # Debian's gtest is not precompiled - link source ln -fs /usr/src/gtest test/unit/gtest dh_auto_configure -- -DLIB_SUFFIX="" -DUNIT_TESTS=TRUE \ -DENABLE_THIRD_PARTY_COPY=TRUE override_dh_auto_build: dh_auto_build -- all doc override_dh_install: rm debian/tmp/usr/share/doc/davix/LICENSE dh_install --fail-missing override_dh_auto_clean: rm -f test/unit/gtest dh_auto_clean override_dh_auto_test: ( cd obj-* ; make abi-check ) dh_auto_test -- ARGS+="-V -T Test" davix-R_0_5_0/packaging/debian/source/000077500000000000000000000000001257152637300177335ustar00rootroot00000000000000davix-R_0_5_0/packaging/debian/source/format000066400000000000000000000000141257152637300211410ustar00rootroot000000000000003.0 (quilt) davix-R_0_5_0/packaging/debian/source/lintian-overrides000066400000000000000000000001721257152637300233140ustar00rootroot00000000000000# The autotools files are not used - build uses cmake davix source: outdated-autotools-helper-file deps/libneon/config.* davix-R_0_5_0/packaging/rpm/000077500000000000000000000000001257152637300160075ustar00rootroot00000000000000davix-R_0_5_0/packaging/rpm/specs/000077500000000000000000000000001257152637300171245ustar00rootroot00000000000000davix-R_0_5_0/packaging/rpm/specs/davix.spec000066400000000000000000000106721257152637300211210ustar00rootroot00000000000000# unversionned doc dir F20 change https://fedoraproject.org/wiki/Changes/UnversionedDocdirs %{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}} # EL5 compat for boost, cmake %if 0%{?el5} %global boost_cmake_flags -DBOOST_INCLUDEDIR=/usr/include/boost141 -DBOOST_LIBRARYDIR=%{_libdir}/boost141 %else %global boost_cmake_flags -DBOOST_INCLUDEDIR=/usr/include %endif Name: davix Version: 0.5.0 Release: 1%{?dist} Summary: Toolkit for Http-based file management Group: Applications/Internet License: LGPLv2+ URL: http://dmc.web.cern.ch/projects/davix/home # git clone http://git.cern.ch/pub/davix Source0: http://grid-deployment.web.cern.ch/grid-deployment/dms/lcgutil/tar/%{name}/%{name}-%{version}.tar.gz BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) #main lib dependencies %if 0%{?el5} BuildRequires: boost141-devel %else BuildRequires: boost-devel %endif BuildRequires: cmake BuildRequires: doxygen BuildRequires: libxml2-devel BuildRequires: openssl-devel # davix-copy dependencies BuildRequires: gsoap-devel # unit tests and abi check %if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 6 BuildRequires: abi-compliance-checker %endif BuildRequires: gtest-devel Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). Davix provides an API and a set of command line tools. %package libs Summary: Development files for %{name} Group: Applications/Internet %description libs Libraries for %{name}. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). %package devel Summary: Development files for %{name} Group: Applications/Internet Requires: %{name}-libs%{?_isa} = %{version}-%{release} Requires: pkgconfig %description devel Development files for %{name}. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). %package doc Summary: Documentation for %{name} Group: Documentation %if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 6 BuildArch: noarch %endif %description doc Documentation and examples for %{name}. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). %clean rm -rf %{buildroot} make clean %prep %setup -q # remove useless embedded components rm -rf test/pywebdav/ %build %cmake \ -DDOC_INSTALL_DIR=%{_pkgdocdir} \ -DGTEST_EXTERNAL=TRUE \ -DENABLE_THIRD_PARTY_COPY=TRUE \ -DUNIT_TESTS=TRUE \ %{boost_cmake_flags} \ . make %{?_smp_mflags} make doc %check %if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 6 make abi-check %endif ctest -V -T Test %install rm -rf %{buildroot} make DESTDIR=%{buildroot} install %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig %files %defattr (-,root,root) %{_bindir}/* %{_mandir}/man1/* %files libs %defattr (-,root,root) %{_libdir}/libdavix.so.* %{_libdir}/libdavix_copy.so.* %{_mandir}/man3/* %files devel %defattr (-,root,root) %{_libdir}/libdavix.so %{_libdir}/libdavix_copy.so %dir %{_includedir}/davix %{_includedir}/davix/* %{_libdir}/pkgconfig/* %files doc %defattr (-,root,root) %{_pkgdocdir}/LICENSE %{_pkgdocdir}/RELEASE-NOTES %{_pkgdocdir}/html/ %changelog * Fri Dec 05 2014 Adrien Devresse - 0.4.0-1 - davix 0.4.0 release, see RELEASE-NOTES for changes * Tue Aug 12 2014 Adrien Devresse - 0.3.6-1 - davix 0.3.6 release, see RELEASE-NOTES for changes * Tue Jul 22 2014 Adrien Devresse - 0.3.4-1 - Update to release 0.3.4 * Wed Jun 04 2014 Adrien Devresse - 0.3.1-1 - davix 0.3.1 release, see RELEASE-NOTES for changes * Tue Jun 03 2014 Adrien Devresse - 0.3.0-1 - davix 0.3.0 release, see RELEASE-NOTES for changes * Tue Jan 28 2014 Adrien Devresse - 0.2.10-1 - davix 0.2.10 release, see RELEASE-NOTES for details * Mon Oct 28 2013 Adrien Devresse - 0.2.7-3 - New update of davix, see RELEASE-NOTES for details * Tue Sep 03 2013 Adrien Devresse - 0.2.6-1 - Release 0.2.6 of davix, see RELEASE-NOTES for details * Wed Jun 05 2013 Adrien Devresse - 0.2.2-2 - Initial EPEL release davix-R_0_5_0/packaging/rpm/specs/davix.spec.in000066400000000000000000000107051257152637300215230ustar00rootroot00000000000000# unversionned doc dir F20 change https://fedoraproject.org/wiki/Changes/UnversionedDocdirs %{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}} # EL5 compat for boost, cmake %if 0%{?el5} %global boost_cmake_flags -DBOOST_INCLUDEDIR=/usr/include/boost141 -DBOOST_LIBRARYDIR=%{_libdir}/boost141 %else %global boost_cmake_flags -DBOOST_INCLUDEDIR=/usr/include %endif Name: davix Version: @VERSION_STRING@ Release: 1%{?dist} Summary: Toolkit for Http-based file management Group: Applications/Internet License: LGPLv2+ URL: http://dmc.web.cern.ch/projects/davix/home # git clone http://git.cern.ch/pub/davix Source0: http://grid-deployment.web.cern.ch/grid-deployment/dms/lcgutil/tar/%{name}/%{name}-%{version}.tar.gz BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) #main lib dependencies %if 0%{?el5} BuildRequires: boost141-devel %else BuildRequires: boost-devel %endif BuildRequires: cmake BuildRequires: doxygen BuildRequires: libxml2-devel BuildRequires: openssl-devel # davix-copy dependencies BuildRequires: gsoap-devel # unit tests and abi check %if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 6 BuildRequires: abi-compliance-checker %endif BuildRequires: gtest-devel Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). Davix provides an API and a set of command line tools. %package libs Summary: Development files for %{name} Group: Applications/Internet %description libs Libraries for %{name}. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). %package devel Summary: Development files for %{name} Group: Applications/Internet Requires: %{name}-libs%{?_isa} = %{version}-%{release} Requires: pkgconfig %description devel Development files for %{name}. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). %package doc Summary: Documentation for %{name} Group: Documentation %if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 6 BuildArch: noarch %endif %description doc Documentation and examples for %{name}. Davix is a toolkit designed for file operations with Http based protocols (WebDav, Amazon S3, ...). %clean rm -rf %{buildroot} make clean %prep %setup -q # remove useless embedded components rm -rf test/pywebdav/ %build %cmake \ -DDOC_INSTALL_DIR=%{_pkgdocdir} \ -DGTEST_EXTERNAL=TRUE \ -DENABLE_THIRD_PARTY_COPY=TRUE \ -DUNIT_TESTS=TRUE \ %{boost_cmake_flags} \ . make %{?_smp_mflags} make doc %check %if %{?fedora}%{!?fedora:0} >= 10 || %{?rhel}%{!?rhel:0} >= 6 make abi-check %endif ctest -V -T Test %install rm -rf %{buildroot} make DESTDIR=%{buildroot} install %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig %files %defattr (-,root,root) %{_bindir}/* %{_mandir}/man1/* %files libs %defattr (-,root,root) %{_libdir}/libdavix.so.* %{_libdir}/libdavix_copy.so.* %{_mandir}/man3/* %files devel %defattr (-,root,root) %{_libdir}/libdavix.so %{_libdir}/libdavix_copy.so %dir %{_includedir}/davix %{_includedir}/davix/* %{_libdir}/pkgconfig/* %files doc %defattr (-,root,root) %{_pkgdocdir}/LICENSE %{_pkgdocdir}/RELEASE-NOTES %{_pkgdocdir}/html/ %changelog * Fri Dec 05 2014 Adrien Devresse - 0.4.0-1 - davix 0.4.0 release, see RELEASE-NOTES for changes * Tue Aug 12 2014 Adrien Devresse - 0.3.6-1 - davix 0.3.6 release, see RELEASE-NOTES for changes * Tue Jul 22 2014 Adrien Devresse - 0.3.4-1 - Update to release 0.3.4 * Wed Jun 04 2014 Adrien Devresse - 0.3.1-1 - davix 0.3.1 release, see RELEASE-NOTES for changes * Tue Jun 03 2014 Adrien Devresse - 0.3.0-1 - davix 0.3.0 release, see RELEASE-NOTES for changes * Tue Jan 28 2014 Adrien Devresse - 0.2.10-1 - davix 0.2.10 release, see RELEASE-NOTES for details * Mon Oct 28 2013 Adrien Devresse - 0.2.7-3 - New update of davix, see RELEASE-NOTES for details * Tue Sep 03 2013 Adrien Devresse - 0.2.6-1 - Release 0.2.6 of davix, see RELEASE-NOTES for details * Wed Jun 05 2013 Adrien Devresse - 0.2.2-2 - Initial EPEL release davix-R_0_5_0/src/000077500000000000000000000000001257152637300140545ustar00rootroot00000000000000davix-R_0_5_0/src/CMakeLists.txt000066400000000000000000000063131257152637300166170ustar00rootroot00000000000000# main file for src FILE(GLOB src_davix "*.cpp") FILE(GLOB src_neon "neon/*.cpp") FILE(GLOB src_davix_status "status/*.cpp") FILE(GLOB src_davix_fileops "fileops/*.cpp") FILE(GLOB src_davix_params "params/*.cpp") FILE(GLOB src_davix_auth "auth/*.cpp") FILE(GLOB src_davix_file "file/*.cpp") FILE(GLOB src_davix_deprecated "deprecated/*.cpp") FILE(GLOB src_davix_request "request/*.cpp") FILE(GLOB src_davix_hooks "hooks/*.cpp") FILE(GLOB src_davix_modules "modules/*.cpp") FILE(GLOB src_davix_utils "utils/*.cpp") include_directories("libs" ".") if(HAVE_TR1_SUPPORT) endif(HAVE_TR1_SUPPORT) configure_file(davix_internal_config.in ${CMAKE_CURRENT_BINARY_DIR}/davix_internal_config.hpp @ONLY) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) link_directories(${HTTPLIB_PKG_LIBRARY_DIR} ${CRYPTO_PKG_LIBRARY_DIR} ${LIBXML2_PKG_LIBRARY_DIR} ) add_subdirectory(modules/copy) add_subdirectory(libs) add_subdirectory(xml) if(ENABLE_TOOLS) add_subdirectory(tools) endif() add_subdirectory(neon) SET(SRC_HTTP ${src_neon}) LIST(APPEND SRC_DAVIX_FULL ${src_davix} ${src_davix_request} ${SRC_HTTP} ${src_xmlparser} ${src_datetime} ${src_davix_status} ${src_davix_fileops} ${src_davix_utils} ${src_davix_params} ${src_davix_auth} ${src_davix_file} ${src_davix_deprecated} ${src_davix_hooks} ${src_davix_modules} ${SRC_STRPTIME} ${SRC_MEMPCPY} ${SRC_STRLCPY} ${SRC_STRING_UTILS_CPP} ${SRC_BASE64} ${SRC_HMACSHA1} ) add_definitions(${HTTPLIB_PKG_CFLAGS} ) if(SHARED_LIBRARY) add_library(libdavix SHARED ${SRC_DAVIX_FULL} ) add_dependencies(libdavix neon) target_link_libraries(libdavix alibxx_core ${HTTPLIB_PKG_LIBRARIES} ${CRYPTO_PKG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SOCKET_PKG_LIBRARIES} ${Boost_LIBRARIES}) if(HAVE_CLOCK_GETTIME) target_link_libraries(libdavix rt) endif(HAVE_CLOCK_GETTIME) set_target_properties(libdavix PROPERTIES VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} SOVERSION ${VERSION_MAJOR} CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME ${OUTPUT_NAME_DAVIX}) install(TARGETS libdavix DESTINATION ${LIB_INSTALL_DIR} ) add_PkgConfigFile_for_Library("davix.pc" libdavix HEADER_DIRS "davix" CFLAGS " -D_FILE_OFFSET_BITS=64 " DESCRIPTION "Libdavix, IO library for HTTP based protocols" ) #install pkgconfig install(FILES ${CMAKE_CURRENT_BINARY_DIR}/davix.pc DESTINATION ${PKGCONFIG_FILES_DIR} ) endif(SHARED_LIBRARY) if(STATIC_LIBRARY) add_definitions(-DA_LIB_NAMESPACE=Davix) FILE(GLOB src_alibxx_static "libs/alibxx/*/*.cpp") add_library(libdavix_static STATIC ${SRC_DAVIX_FULL} ${src_alibxx_static}) set_target_properties(libdavix_static PROPERTIES OUTPUT_NAME ${OUTPUT_NAME_DAVIX}) install(TARGETS libdavix_static DESTINATION ${LIB_INSTALL_DIR} ) endif(STATIC_LIBRARY) SET(davix_tool_common_src "${davix_tool_common_src_up}" PARENT_SCOPE) davix-R_0_5_0/src/auth/000077500000000000000000000000001257152637300150155ustar00rootroot00000000000000davix-R_0_5_0/src/auth/davix_openssl.cpp000066400000000000000000000123641257152637300204050ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 // openSSL security layer implem namespace Davix { const std::string openssl_scope = "Davix::OpenSSL"; void opensslErrorMapper(const std::string & msg, DavixError** err){ unsigned long e = 0; char buff_err[255] ={0}; e= ERR_get_error(); if(e == 0){ DavixError::setupError(err, openssl_scope, StatusCode::UnknowError, "No Error reported by OpenSSL"); return; } StatusCode::Code c; switch(ERR_GET_REASON(e)){ case PEM_R_BAD_DECRYPT: case PEM_R_BAD_PASSWORD_READ: case PEM_R_PROBLEMS_GETTING_PASSWORD: c = StatusCode::CredDecryptionError; break; default: c = StatusCode::SSLError; } std::ostringstream ss; ERR_error_string_n(e, buff_err, 255); ss << msg << " : " << buff_err; DavixError::setupError(err, openssl_scope, c, ss.str()); } static int SSL_pem_passwd_cb(char *buffer, int size, int rwflag, void *userdata){ (void) rwflag; if(userdata != NULL) { const char* passwd = static_cast(userdata); int passwd_len = strlen(passwd); if (passwd_len == 0 || passwd_len > size) return 0; strncpy(buffer, passwd, size); return passwd_len; } return 0; } ne_ssl_client_cert *SSL_X509_Pem_Read(const std::string & pkeyfile_str, const std::string & credfile_str, const std::string & password_str, DavixError** err){ FILE *fp; BIO* in=NULL; X509 *cert,*ca; STACK_OF(X509)* chain = NULL; EVP_PKEY *pkey; ne_ssl_client_cert *cc=NULL; int len, errcode; const char * pkeyfile = pkeyfile_str.c_str(), *credfile = credfile_str.c_str(), *password = password_str.c_str(); unsigned char* name; if( pkeyfile ==NULL || credfile ==NULL || ((in = BIO_new(BIO_s_file())) == NULL)){ DavixError::setupError(err, openssl_scope, StatusCode::UnknowError, "init error"); return NULL; } // load cred if (BIO_read_filename(in, credfile) <= 0){ std::ostringstream msg; msg << "impossible to open " << credfile << ": "; opensslErrorMapper(msg.str(), err); ERR_clear_error(); BIO_free(in); return NULL; } if ( (cert = PEM_read_bio_X509(in, NULL, SSL_pem_passwd_cb, (void*) password)) == NULL){ std::ostringstream msg; msg << "parse PEM credential failed " << credfile << ": "; opensslErrorMapper(msg.str(), err); ERR_clear_error(); BIO_free(in); return NULL; } // load chain chain = sk_X509_new_null(); while ((ca = PEM_read_bio_X509(in,NULL, SSL_pem_passwd_cb, (void*) password)) != NULL){ sk_X509_push(chain, ca); } /* When the while loop ends, it's usually just EOF. */ BIO_free(in); errcode = ERR_peek_last_error(); if (ERR_GET_LIB(errcode) == ERR_LIB_PEM && ERR_GET_REASON(errcode) == PEM_R_NO_START_LINE){ ERR_clear_error(); }else{ opensslErrorMapper(" parse PEM credential chain failed ", err); ERR_clear_error(); X509_free(cert); return NULL; } // load pkey fp = fopen(pkeyfile, "rb"); if (fp == NULL){ std::ostringstream ss; ss << "Impossible to open " << pkeyfile << " : " << strerror(errno); DavixError::setupError(err, openssl_scope, StatusCode::CredentialNotFound, ss.str()); errno = 0; X509_free(cert); return NULL; } if ( (pkey = PEM_read_PrivateKey(fp, NULL, SSL_pem_passwd_cb, (void*) password)) == NULL){ opensslErrorMapper(std::string("parse PEM private key failed ").append(pkeyfile), err); ERR_clear_error(); X509_free(cert); return NULL; } fclose(fp); // load ca chain name = X509_alias_get0(cert, &len); cc = (ne_ssl_client_cert*) calloc(sizeof(ne_ssl_client_cert),1); cc->pkey = pkey; cc->decrypted = 1; if (name && len > 0) cc->friendly_name = strndup((char *)name, len); populate_cert(&cc->cert, cert); cc->cert.chain = chain; return cc; } } davix-R_0_5_0/src/auth/davixauth.cpp000066400000000000000000000022361257152637300175210ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include namespace Davix{ std::vector v; SessionInfo::SessionInfo() : data(NULL){ } std::vector & SessionInfo::getReadableDN() const{ // TODO: implement proper DN mapping return v; } } davix-R_0_5_0/src/auth/davixx509cred.cpp000066400000000000000000000110321257152637300201150ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "davixx509cred_internal.hpp" namespace Davix { struct X509CredentialInternal{ X509CredentialInternal() : _cred(NULL), x509_ucert(), x509_ukey(), x509_passwd(), pemLoaded(false) {} X509CredentialInternal(const X509CredentialInternal & orig) : _cred((orig._cred)?ne_ssl_dup_client_cert(orig._cred):NULL), x509_ucert(orig.x509_ucert), x509_ukey(orig.x509_ukey), x509_passwd(orig.x509_passwd), pemLoaded(orig.pemLoaded) {} X509CredentialInternal & operator=(const X509CredentialInternal & orig){ _cred= (orig._cred)?ne_ssl_dup_client_cert(orig._cred):NULL; x509_ucert.assign(orig.x509_ucert); x509_ukey.assign(orig.x509_ukey); x509_passwd.assign(orig.x509_passwd); pemLoaded = orig.pemLoaded; return *this; } ~X509CredentialInternal(){ clear_cert(); } void clear_cert(){ if(_cred){ ne_ssl_clicert_free(_cred); _cred = NULL; } pemLoaded = false; x509_ucert.clear(); x509_ukey.clear(); x509_passwd.clear(); } ne_ssl_client_cert * _cred; // Remember pem location std::string x509_ucert; std::string x509_ukey; std::string x509_passwd; bool pemLoaded; }; X509Credential::X509Credential() : d_ptr(new X509CredentialInternal()) { } X509Credential::X509Credential(const X509Credential &orig) : d_ptr(new X509CredentialInternal(*(orig.d_ptr))) { } X509Credential & X509Credential::operator =( const X509Credential & orig){ if(this == & orig) return *this; delete d_ptr; d_ptr = new X509CredentialInternal(*(orig.d_ptr)); return *this; } X509Credential::~X509Credential(){ delete d_ptr; } int X509Credential::loadFromFileP12(const std::string &p12_cred, const std::string & passwd, DavixError **err){ d_ptr->clear_cert(); if( (d_ptr->_cred = ne_ssl_clicert_read(p12_cred.c_str())) == NULL){ Davix::DavixError::setupError(err, davix_scope_x509cred(),StatusCode::CredentialNotFound, std::string("Impossible to load credential ").append(p12_cred)); return -1; } if( ne_ssl_clicert_encrypted(d_ptr->_cred) !=0 && ne_ssl_clicert_decrypt(d_ptr->_cred, passwd.c_str()) !=0){ Davix::DavixError::setupError(err, davix_scope_x509cred(), StatusCode::LoginPasswordError, std::string("Impossible to decrypt the credential ").append(p12_cred).append(" with the provided password")); d_ptr->clear_cert(); return -1; } return 0; } int X509Credential::loadFromFilePEM(const std::string & filepath_priv_key, const std::string & filepath_cred, const std::string & password, DavixError** err){ d_ptr->clear_cert(); if( (d_ptr->_cred = SSL_X509_Pem_Read(filepath_priv_key, filepath_cred, password, err)) != NULL){ d_ptr->x509_ucert = filepath_cred; d_ptr->x509_ukey = filepath_priv_key; d_ptr->x509_passwd = password; d_ptr->pemLoaded = true; return 0; } return -1; } bool X509Credential::hasCert() const{ return (d_ptr->_cred != NULL); } ne_ssl_client_cert* X509CredentialExtra::extract_ne_ssl_clicert(const X509Credential &cred) { return (cred.d_ptr->_cred); } bool X509CredentialExtra::get_x509_info(const X509Credential &cred, std::string* ucert, std::string* ukey, std::string* passwd) { ucert->assign(cred.d_ptr->x509_ucert); ukey->assign(cred.d_ptr->x509_ukey); passwd->assign(cred.d_ptr->x509_passwd); return cred.d_ptr->pemLoaded; } } // namespace DAvix davix-R_0_5_0/src/auth/davixx509cred_internal.hpp000066400000000000000000000030131257152637300220160ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_X509CRED_INTERNAL_HPP #define DAVIX_X509CRED_INTERNAL_HPP #include #include namespace Davix{ // SSL Ops ne_ssl_client_cert *SSL_X509_Pem_Read(const std::string & pkeyfile, const std::string & credfile, const std::string & password, DavixError** err); struct X509CredentialExtra{ static ne_ssl_client_cert* extract_ne_ssl_clicert(const X509Credential & cred); static bool get_x509_info(const X509Credential &cred, std::string* ucert, std::string* ukey, std::string* passwd); }; } #endif // DAVIX_X509CRED_INTERNAL_HPP davix-R_0_5_0/src/davix_context_internal.hpp000066400000000000000000000026331257152637300213440ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_CONTEXTINTERNAL_H #define DAVIX_CONTEXTINTERNAL_H #include #include #include #include namespace Davix { /// @cond HIDDEN_SYMBOLS struct ContextExplorer{ static NEONSessionFactory & SessionFactoryFromContext(Context & c); }; // libpath handler struct LibPath{ LibPath(); std::string path; }; const std::string & getLibPath(); ///@endcond } // namespace Davix #endif // DAVIX_CONTEXTINTERNAL_H davix-R_0_5_0/src/davix_internal.hpp000066400000000000000000000036641257152637300176050ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_INTERNAL_HPP #define DAVIX_INTERNAL_HPP // configuration #include #include // C++ includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NO_BOOST_INCLUDE // boost #include #include #endif // C includes #include #include #include #include #include #include // Posix includes #include #include "libs/alibxx/alibxx.hpp" namespace Davix{ // http request internals void httpcodeToDavixException(int code, const std::string & scope, const std::string & end_message = std::string()); bool httpcodeIsValid(int code); void httpcodeToDavixError(int code, const std::string & scope, const std::string & end_message, DavixError** err); } #endif // DAVIX_INTERNAL_HPP davix-R_0_5_0/src/davix_internal_config.in000066400000000000000000000040031257152637300207350ustar00rootroot00000000000000#ifndef CONFIG_H #define CONFIG_H // POSIX inclusion #include #include #include #include // C++ C mapping #include #include #include // define alib namespace #undef A_LIB_NAMESPACE #define A_LIB_NAMESPACE Davix // buffer parameters #define DAVIX_BUFFER_SIZE 2048 #define DAVIX_READ_BLOCK_SIZE 4096 // default task queue size #define DAVIX_DEFAULT_TASKQUEUE_SIZE 100 // default connexion timeout for HTTP/Dav connexion #define DAVIX_DEFAULT_CONN_TIMEOUT 30 // default timeout on operations for HTTP/Webdav #define DAVIX_DEFAULT_OPS_TIMEOUT 0 // default retry number const int default_retry_number= 10; // c++11 #cmakedefine HAVE_CXX011_FULL_SUPPORT 1 #cmakedefine HAVE_CXX011_PARTIAL_SUPPORT 1 // tr1 #cmakedefine HAVE_TR1_SUPPORT 1 // default export #undef DAVIX_EXPORT #define DAVIX_EXPORT // POSIX // has unistd #cmakedefine HAVE_UNISTD_H 1 // has clock_gettime #cmakedefine HAVE_CLOCK_GETTIME 1 #cmakedefine HAVE_GETTIMEOFDAY 1 // openssl backend #cmakedefine HAVE_OPENSSL 1 // has locale #cmakedefine HAVE_LOCALE_H 1 // has strptime #cmakedefine HAVE_STRPTIME_H 1 #ifndef HAVE_STRPTIME_H # define strptime __strptime #endif #cmakedefine HAVE_STRLCPY_H 1 // have gmtime_r #cmakedefine HAVE_GMTIME_R 1 // readdir max name size #ifndef NAME_MAX #define NAME_MAX 256 #endif // termios #cmakedefine HAVE_TERMIOS_H 1 // getconsolemode #cmakedefine HAVE_SETCONSOLEMODE 1 // // Win 32 mapper #if( defined _WIN32 )|| ( defined __MINGW32__ ) // macros #define __PLATFORM_WINDOWS__ // stat struct def typedef short nlink_t; typedef short gid_t; typedef short uid_t; #undef DAVIX_EXPORT #if defined(libdavix_EXPORTS) #define DAVIX_EXPORT __declspec(dllexport) #else #define DAVIX_EXPORT __declspec(dllimport) #endif /* libdavix_EXPORTS */ // windows headers #include #include #endif /* end of win32*/ // Davix versionnin #define DAVIX_VERSION "@VERSION_STRING@" #define DAVIX_VERSION_TAG "@VERSION_TAG@" #endif // CONFIG_H davix-R_0_5_0/src/davixcontext.cpp000066400000000000000000000103271257152637300173030ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 namespace Davix{ struct LibPath; static const std::string _version = DAVIX_VERSION "-" DAVIX_VERSION_TAG; static LibPath lib_path; /// Implementation f the core logic in davix struct ContextInternal { ContextInternal(NEONSessionFactory * fsess): _fsess(fsess), _s_buff(65536), _timeout(300), _context_flags(0), _hook_list() { DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "libdavix path {}", getLibPath()); } ContextInternal(const ContextInternal & orig): _fsess(new NEONSessionFactory()), _s_buff(orig._s_buff), _timeout(orig._timeout), _context_flags(orig._context_flags), _hook_list(orig._hook_list) { } virtual ~ContextInternal(){} // implementation of getSessionFactory inline NEONSessionFactory* getSessionFactory(){ return _fsess.get(); } void setBufferSize(const dav_size_t value){ _s_buff = value; } Ptr::Scoped _fsess; dav_size_t _s_buff; unsigned long _timeout; bool _context_flags; HookList _hook_list; }; /////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// Context::Context() : _intern(new ContextInternal(new NEONSessionFactory())) { } Context::Context(const Context &c) : _intern(new ContextInternal(*(c._intern))){ } Context & Context::operator=(const Context & c){ if( this != &c ){ if( _intern != NULL) delete _intern; _intern = new ContextInternal(*(c._intern)); } return *this; } Context::~Context(){ delete _intern; } Context* Context::clone(){ return new Context(*this); } void Context::setSessionCaching(bool caching){ _intern->_fsess->setSessionCaching(caching); } bool Context::getSessionCaching() const{ return _intern->_fsess->getSessionCaching(); } HttpRequest* Context::createRequest(const std::string & url, DavixError** err){ return new HttpRequest(*this, Uri(url), err); } HttpRequest* Context::createRequest(const Uri &uri, DavixError **err){ return new HttpRequest(*this, uri, err); } void Context::loadModule(const std::string &name){ if( StrUtil::compare_ncase("grid",name) == 0){ loadGridProfile(*this); return; } DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_CORE, "No module named {} found", name); } HookList & Context::getHookList(){ return _intern->_hook_list; } NEONSessionFactory & ContextExplorer::SessionFactoryFromContext(Context & c){ return *static_cast(c._intern->getSessionFactory()); } LibPath::LibPath(){ Dl_info shared_lib_infos; // do an address resolution on a local function // get this resolution to determine davix shared library path at runtime if( dladdr((void*) &version, &shared_lib_infos) != 0){ path = shared_lib_infos.dli_fname; } } const std::string & version(){ return _version; } const std::string & getLibPath(){ return lib_path.path; } } // End Davix davix-R_0_5_0/src/deprecated/000077500000000000000000000000001257152637300161545ustar00rootroot00000000000000davix-R_0_5_0/src/deprecated/httpcachetoken.cpp000066400000000000000000000047541257152637300216760ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include namespace Davix { struct HttpCacheTokenInternal{ HttpCacheTokenInternal() : _req_uri(), _redirection_uri() {} HttpCacheTokenInternal(const HttpCacheTokenInternal & orig) : _req_uri(orig._req_uri), _redirection_uri(orig._redirection_uri) { } virtual ~HttpCacheTokenInternal(){} Uri _req_uri, _redirection_uri; private: HttpCacheTokenInternal & operator=(const HttpCacheTokenInternal &); }; HttpCacheToken::HttpCacheToken() : d_ptr(new HttpCacheTokenInternal()) { } HttpCacheToken::HttpCacheToken(const HttpCacheToken &orig) : d_ptr(new HttpCacheTokenInternal(*(orig.d_ptr))) { } HttpCacheToken & HttpCacheToken::operator=(const HttpCacheToken & orig){ if(&orig == this) return *this; delete d_ptr; d_ptr = new HttpCacheTokenInternal(*(orig.d_ptr)); return *this; } HttpCacheToken::~HttpCacheToken(){ delete d_ptr; } const Uri & HttpCacheToken::getCachedRedirection() const{ return d_ptr->_redirection_uri; } const Uri & HttpCacheToken::getrequestUri() const { return d_ptr->_req_uri; } // Deprecated replicas // created for Abi compatibility void deprecated_abi_calls(){ Replica* r = new Replica(); ReplicaVec* v = new ReplicaVec(); v->resize(1); FileInfo* t = new FileInfo(); delete (t->getClone()); delete t; FileInfoSize* s = new FileInfoSize(); delete s; delete r; delete v; } HookTraits::HookTraits() : d_ptr(NULL){ } HookTraits::~HookTraits(){ } } davix-R_0_5_0/src/file/000077500000000000000000000000001257152637300147735ustar00rootroot00000000000000davix-R_0_5_0/src/file/davfile.cpp000066400000000000000000000241151257152637300171140ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include namespace Davix{ DavFile::Iterator createIterator(DavFile::DavFileInternal& f, const RequestParams * params); struct DavFile::DavFileInternal{ DavFileInternal(Context & c, const Uri & u, const RequestParams & params = RequestParams()) : _c(c), _u(u), _params(params) {} DavFileInternal(const DavFileInternal & orig) : _c(orig._c), _u(orig._u), _params(orig._params) {} Context & _c; Uri _u; RequestParams _params; HttpIOChain & getIOChain(HttpIOChain & c){ return ChainFactory::instanceChain(CreationFlags(), c); } IOChainContext getIOContext(const RequestParams * params){ return IOChainContext(_c, _u, (params)?(params):(&_params)); } DavFile::Iterator createIterator(const RequestParams * params); static void check_iterator(DavFile::Iterator::Internal* ptr){ if(ptr == NULL) throw DavixException(davix_scope_directory_listing_str(), StatusCode::InvalidArgument, "Usage of an invalid Iterator"); } }; struct DavFile::Iterator::Internal{ Internal(DavFile::DavFileInternal & f, const RequestParams* p) : io_chain(), io_context(f.getIOContext(p)) { f.getIOChain(io_chain); io_chain.nextSubItem(io_context, name, info); } HttpIOChain io_chain; IOChainContext io_context; std::string name; StatInfo info; }; DavFile::Iterator DavFile::DavFileInternal::createIterator(const RequestParams * params){ DavFile::Iterator it; it.d_ptr.reset(new DavFile::Iterator::Internal(*this, params)); return it; } bool DavFile::Iterator::next(){ return d_ptr->io_chain.nextSubItem(d_ptr->io_context, d_ptr->name, d_ptr->info); } const std::string & DavFile::Iterator::name(){ DavFileInternal::check_iterator(d_ptr.get()); return d_ptr->name; } const StatInfo & DavFile::Iterator::info(){ DavFileInternal::check_iterator(d_ptr.get()); return d_ptr->info; } DavFile::DavFile(Context &c, const Uri &u) : d_ptr(new DavFileInternal(c,u)) { } DavFile::DavFile(Context &c, const RequestParams & params, const Uri &u) : d_ptr(new DavFileInternal(c,u,params)) { } DavFile::DavFile(const DavFile & orig): d_ptr(new DavFileInternal(*orig.d_ptr)){ } DavFile::~DavFile(){ delete d_ptr; } const Uri & DavFile::getUri() const{ return d_ptr->_u; } std::vector DavFile::getReplicas(const RequestParams *_params, DavixError **err) throw(){ std::vector res; TRY_DAVIX{ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(_params); return d_ptr->getIOChain(chain).getReplicas(io_context, res); }CATCH_DAVIX(err) return res; } dav_ssize_t DavFile::getAllReplicas(const RequestParams* params, ReplicaVec & v, DavixError **err){ (void) params; (void) v; Davix::DavixError::setupError(err, davix_scope_http_request(), StatusCode::OperationNonSupported, " GetAllReplicas Function not supported, please use GetReplicas()"); return -1; } dav_ssize_t DavFile::readPartialBufferVec(const RequestParams *params, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** err) throw(){ TRY_DAVIX{ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); return d_ptr->getIOChain(chain).preadVec(io_context, input_vec, output_vec, count_vec); }CATCH_DAVIX(err) return -1; } dav_ssize_t DavFile::readPartial(const RequestParams *params, void* buff, dav_size_t count, dav_off_t offset, DavixError** err) throw(){ TRY_DAVIX{ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); return d_ptr->getIOChain(chain).pread(io_context, buff, count, offset); }CATCH_DAVIX(err) return -1; } int DavFile::deletion(const RequestParams *params, DavixError **err) throw(){ TRY_DAVIX{ deletion(params); return 0; }CATCH_DAVIX(err) return -1; } void DavFile::deletion(const RequestParams *params){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).deleteResource(io_context); } dav_ssize_t DavFile::getToFd(const RequestParams* params, int fd, DavixError** err) throw(){ TRY_DAVIX{ return DavFile::getToFd(params, fd, 0, err); }CATCH_DAVIX(err) return -1; } dav_ssize_t DavFile::getToFd(const RequestParams* params, int fd, dav_size_t size_read, DavixError** err) throw(){ TRY_DAVIX{ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); return d_ptr->getIOChain(chain).readToFd(io_context, fd, size_read); }CATCH_DAVIX(err) return -1; } dav_ssize_t DavFile::getFull(const RequestParams* params, std::vector & buffer, DavixError** err) throw(){ TRY_DAVIX{ return get(params, buffer); }CATCH_DAVIX(err) return -1; } dav_ssize_t DavFile::get(const RequestParams* params, std::vector & buffer){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); return d_ptr->getIOChain(chain).readFull(io_context, buffer); } int DavFile::putFromFd(const RequestParams* params, int fd, dav_size_t size, DavixError** err) throw(){ TRY_DAVIX{ put(params, fd, size); return 0; }CATCH_DAVIX(err) return -1; } void DavFile::put(const RequestParams *params, int fd, dav_size_t size_write){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).writeFromFd(io_context, fd, size_write); } void DavFile::put(const RequestParams *params, const DataProviderFun &callback, dav_size_t size_write){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).writeFromCb(io_context, callback, size_write); } static dav_ssize_t buffer_mapper(void* buffer, dav_size_t max_size, const char* origin_buffer, dav_size_t buffer_size, dav_size_t* written_bytes){ dav_ssize_t res; if(max_size ==0 || buffer_size == *written_bytes){ *written_bytes =0; return 0; } res = std::min(max_size, buffer_size - *written_bytes); memcpy(buffer, origin_buffer+ *written_bytes, res); *written_bytes += res; return res; } void DavFile::put(const RequestParams *params, const char *buffer, dav_size_t size_write){ using namespace boost; dav_size_t written_bytes=0; put(params, bind(buffer_mapper, _1, _2, buffer, size_write, &written_bytes), size_write); } void DavFile::move(const RequestParams *params, DavFile & destination){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).move(io_context, destination.getUri().getString()); } int DavFile::makeCollection(const RequestParams *params, DavixError **err) throw(){ TRY_DAVIX{ makeCollection(params); return 0; }CATCH_DAVIX(err) return -1; } void DavFile::makeCollection(const RequestParams *params){ RequestParams _params(params); HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).makeCollection(io_context); } int DavFile::stat(const RequestParams* params, struct stat * st, DavixError** err) throw(){ TRY_DAVIX{ if(st == NULL) throw DavixException(davix_scope_meta(), StatusCode::InvalidArgument, "Argument stat NULL"); StatInfo info; statInfo(params, info).toPosixStat(*st); return 0; }CATCH_DAVIX(err) return -1; } StatInfo& DavFile::statInfo(const RequestParams *params, StatInfo &info){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).statInfo(io_context, info); return info; } DavFile::Iterator DavFile::listCollection(const RequestParams *params){ return d_ptr->createIterator(params); } int DavFile::checksum(const RequestParams *params, std::string & checksm, const std::string & chk_algo, DavixError **err) throw(){ TRY_DAVIX{ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(params); d_ptr->getIOChain(chain).checksum(io_context, checksm, chk_algo); return 0; }CATCH_DAVIX(err) return -1; } void DavFile::prefetchInfo(off_t offset, dav_size_t size_read, advise_t adv){ HttpIOChain chain; IOChainContext io_context = d_ptr->getIOContext(NULL); d_ptr->getIOChain(chain).prefetchInfo(io_context, offset, size_read, adv); } } //Davix std::ostream & operator<<(std::ostream & out, Davix::DavFile & file){ std::vector buffer; file.get(NULL, buffer); out.write(&buffer[0], buffer.size()); return out; } std::istream & operator>>(std::istream & in, Davix::DavFile & file){ std::vector buffer((std::istream_iterator(in)), std::istream_iterator()); file.put(NULL, &(buffer.at(0)), buffer.size()); return in; } davix-R_0_5_0/src/file/davposix.cpp000066400000000000000000000411731257152637300173420ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 using namespace StrUtil; namespace Davix{ const std::string scope = "DavFile"; static HttpIOChain & getIOChain(HttpIOChain & chain){ CreationFlags flags; flags[CHAIN_POSIX] = true; return ChainFactory::instanceChain(flags, chain); } static IOChainContext getIOContext( Context & context, const Uri & uri, const RequestParams* params){ return IOChainContext(context, uri, params); } } static const std::string simple_listing(""); static const std::string stat_listing("" "" "" "" ""); struct Davix_dir_handle{ Davix_dir_handle(Davix::Context & context, const Davix::Uri & u, const Davix::RequestParams * p): params(p), uri(u), io_chain(), io_context(context, uri, ¶ms), start_entry_name(), start_entry_st(), dir_info((struct dirent*) calloc(1,sizeof(struct dirent) + NAME_MAX +1)), dir_offset(0), end(false){ Davix::getIOChain(io_chain); } ~Davix_dir_handle(){ free(dir_info); } // params Davix::RequestParams params; Davix::Uri uri; Davix::HttpIOChain io_chain; Davix::IOChainContext io_context; //first entry std::string start_entry_name; Davix::StatInfo start_entry_st; // dir struct struct dirent* dir_info; off_t dir_offset; // end listing bool end; private: Davix_dir_handle(const Davix_dir_handle & ); Davix_dir_handle & operator=(const Davix_dir_handle & ); }; struct Davix_fd{ Davix_fd(Davix::Context & context, const Davix::Uri & uri, const Davix::RequestParams * params) : _uri(uri), _params(params), io_handler(), io_context(Davix::getIOContext(context, _uri, &_params)){ Davix::getIOChain(io_handler); } virtual ~Davix_fd(){ try{ io_handler.resetIO(io_context); }catch(Davix::DavixException & e){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_POSIX, "Error when closed file descriptor, possibly file corrupted {}", e.what()); } } Davix::Uri _uri; Davix::RequestParams _params; Davix::HttpIOChain io_handler; Davix::IOChainContext io_context; }; namespace Davix { static void toDirent(struct dirent * d, const std::string & filename, const StatInfo & info){ StrUtil::copy_std_string_to_buff(d->d_name, NAME_MAX, filename); if (S_ISDIR(info.mode)) d->d_type = DT_DIR; else if (S_ISLNK(info.mode)) d->d_type = DT_LNK; else d->d_type = DT_REG; } DavPosix::DavPosix(Context* _context) : context(_context), _timeout(180), _s_buff(2048), d_ptr(NULL) { (void ) d_ptr; // silence warning } DavPosix::~DavPosix(){ } DAVIX_DIR* internal_opendir(Context & context, const RequestParams* params, const std::string & url){ Ptr::Scoped dir(new DAVIX_DIR(context, url, params)); dir->end = ! dir->io_chain.nextSubItem(dir->io_context,dir->start_entry_name, dir->start_entry_st); return dir.release(); } DAVIX_DIR* DavPosix::opendir(const RequestParams* params, const std::string &url, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, odir); DAVIX_DIR* r = NULL; TRY_DAVIX{ r = internal_opendir(*context, params, url); }CATCH_DAVIX(err) return (DAVIX_DIR*) r; } DAVIX_DIR* DavPosix::opendirpp(const RequestParams* params, const std::string &url, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, odirpp); DAVIX_DIR* r = NULL; TRY_DAVIX{ r = internal_opendir(*context, params, url); }CATCH_DAVIX(err) return (DAVIX_DIR*) r; } struct dirent* internal_readdir(DAVIX_DIR * dir, struct stat* st){ if( dir==NULL){ throw DavixException(davix_scope_directory_listing_str(), StatusCode::InvalidFileHandle, "Invalid file descriptor for DAVIX_DIR*"); } if(dir->end) return NULL; if(dir->start_entry_name.size() >0) { // first entry if(st){ dir->start_entry_st.toPosixStat(*st); } toDirent(dir->dir_info, dir->start_entry_name, dir->start_entry_st); dir->start_entry_name.clear(); return dir->dir_info; } StatInfo info; std::string name; if( dir->io_chain.nextSubItem(dir->io_context, name, info) ==false){ return NULL; } if(st){ info.toPosixStat(*st); } toDirent(dir->dir_info, name, info); return dir->dir_info; } struct dirent* DavPosix::readdir(DAVIX_DIR * d, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, rdir); DavixError* tmp_err=NULL; DAVIX_DIR* dir = static_cast(d); TRY_DAVIX{ return internal_readdir(dir, NULL); }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return NULL; } struct dirent* DavPosix::readdirpp(DAVIX_DIR * d, struct stat *st, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, rdirpp); DavixError* tmp_err=NULL; DAVIX_DIR* dir = static_cast(d); TRY_DAVIX{ return internal_readdir(dir, st); }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return NULL; } int DavPosix::closedirpp(DAVIX_DIR * d, DavixError** err){ int ret =-1; TRY_DAVIX{ if( d==NULL){ throw DavixException(davix_scope_directory_listing_str(), Davix::StatusCode::InvalidFileHandle, "Invalid file descriptor for DAVIX_DIR*"); }else{ delete (static_cast(d)); ret =0; } }CATCH_DAVIX(err) return ret; } int DavPosix::closedir(DAVIX_DIR * d, DavixError** err){ return closedirpp(d,err); } void DavPosix::fadvise(DAVIX_FD *fd, dav_off_t offset, dav_size_t len, advise_t advise){ try{ if( fd==NULL) return; fd->io_handler.prefetchInfo(fd->io_context, offset, len, advise); }catch(DavixException & e){ DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_POSIX, "fdadvise error {}", e.what()); }catch(...){ DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_POSIX, "Unknown error, aborted"); } } //////////////////////////////////////////////////// //////////////////// Davix POSIX meta ops ///////////////////////////////////////////////////// int DavPosix::rename(const RequestParams * _params, const std::string &source_url, const std::string &target_url, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, renm); int ret=-1; TRY_DAVIX{ Uri uri(source_url); HttpIOChain chain; IOChainContext io_context = getIOContext(*context, uri, _params); getIOChain(chain).move(io_context, target_url); ret = 0; }CATCH_DAVIX(err) return ret; } int DavPosix::mkdir(const RequestParams * _params, const std::string &url, mode_t right, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_mkdir); (void) right; int ret=-1; TRY_DAVIX{ Uri uri(url); HttpIOChain chain; IOChainContext io_context = getIOContext(*context, uri, _params); getIOChain(chain).makeCollection(io_context); ret = 0; }CATCH_DAVIX(err) return ret; } int DavPosix::stat(const RequestParams * params, const std::string & url, struct stat* st, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_stat); File f(*context, url); int ret = f.stat(params, st, err); return ret; } int DavPosix::stat64(const RequestParams *params, const std::string & url, StatInfo *st, DavixError **err){ TRY_DAVIX{ if(st == NULL) throw DavixException(davix_scope_meta(), StatusCode::InvalidArgument, "Argument stat NULL"); File f(*context, url); f.statInfo(params, *st); return 0; }CATCH_DAVIX(err) return -1; } int davix_remove_posix(Context* context, const RequestParams * params, const std::string & url, bool directory, DavixError** err){ DavixError* tmp_err = NULL; int ret = -1; Uri uri(url); TRY_DAVIX{ if(params && params->getProtocol() == RequestProtocol::Http){ // pure protocol http : ignore posix semantic, execute a simple delete HttpIOChain chain; IOChainContext io_context = getIOContext(*context, uri, params); getIOChain(chain).deleteResource(io_context); ret = 0; }else{ // full posix semantic support HttpIOChain chain; IOChainContext io_context = getIOContext(*context, uri, params); struct StatInfo infos; getIOChain(chain).statInfo(io_context, infos); if( S_ISDIR(infos.mode)){ // directory : impossible to delete if not empty if(directory == true){ chain.deleteResource(io_context); ret =0; }else{ ret = -1; throw DavixException(davix_scope_davOps_str(), StatusCode::IsADirectory, fmt::format(" {} is a directory, impossible to unlink\n", uri)); } }else{ // file, rock & roll if(directory == false){ chain.deleteResource(io_context); ret =0; }else{ ret = -1; throw DavixError(davix_scope_davOps_str(), StatusCode::IsNotADirectory, fmt::format(" {} is not a directory, impossible to rmdir", uri)); } } } }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return ret; } int DavPosix::unlink(const RequestParams * params, const std::string &uri, DavixError** err){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_POSIX, " -> davix_unlink"); int ret=-1; DavixError* tmp_err=NULL; TRY_DAVIX{ ret = davix_remove_posix(context, params, uri, false, &tmp_err); }CATCH_DAVIX(&tmp_err) DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_POSIX, " davix_unlink <-"); DavixError::propagatePrefixedError(err, tmp_err, "DavPosix::unlink "); return ret; } int DavPosix::rmdir(const RequestParams * params, const std::string &uri, DavixError** err){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_POSIX, " -> davix_rmdir"); int ret=-1; DavixError* tmp_err=NULL; TRY_DAVIX{ ret = davix_remove_posix(context, params, uri, true, &tmp_err); }CATCH_DAVIX(&tmp_err) DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_POSIX, " davix_rmdir <-"); DavixError::propagatePrefixedError(err, tmp_err, "DavPosix::rmdir "); return ret; } //////////////////////////////////////////////////// //////////////////// Davix POSIX I/O ///////////////////////////////////////////////////// inline int davix_check_rw_fd(DAVIX_FD* fd, DavixError** err){ if(fd == NULL){ DavixError::setupError(err, davix_scope_http_request(),StatusCode::InvalidFileHandle, "Invalid Davix file descriptor"); return -1; } return 0; } DAVIX_FD* DavPosix::open(const RequestParams * _params, const std::string & url, int flags, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_open); DavixError* tmp_err=NULL; Davix_fd* fd = NULL; TRY_DAVIX{ Uri uri(url); if(uri.getStatus() != StatusCode::OK){ throw DavixException(davix_scope_http_request(), uri.getStatus(), " Uri invalid in Davix::Open"); } fd = new Davix_fd(*context, uri, _params); fd->io_handler.open(fd->io_context, flags); }CATCH_DAVIX(&tmp_err) if(tmp_err){ DavixError::propagateError(err, tmp_err); delete fd; fd= NULL; } return fd; } ssize_t DavPosix::read(DAVIX_FD* fd, void* buf, size_t count, Davix::DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_read); ssize_t ret =-1; DavixError* tmp_err=NULL; TRY_DAVIX{ if( davix_check_rw_fd(fd, &tmp_err) ==0){ ret = (ssize_t) fd->io_handler.read(fd->io_context, buf, (dav_size_t) count); } }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return ret; } ssize_t DavPosix::pread(DAVIX_FD* fd, void* buf, size_t count, off_t offset, DavixError** err){ return static_cast(pread64(fd, buf, static_cast(count), static_cast(offset), err)); } dav_ssize_t DavPosix::pread64(DAVIX_FD *fd, void *buf, dav_size_t count, dav_off_t offset, DavixError **err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_pread); dav_ssize_t ret =-1; DavixError* tmp_err=NULL; TRY_DAVIX{ if( davix_check_rw_fd(fd, &tmp_err) ==0){ ret = fd->io_handler.pread(fd->io_context, buf, count, offset); } }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err);; return ret; } ssize_t DavPosix::pwrite(DAVIX_FD* fd, const void* buf, size_t count, off_t offset, DavixError** err){ (void) fd; (void) buf; (void) count; (void) offset; DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_pwrite); DavixError::setupError(err, davix_scope_io_buff(), StatusCode::OperationNonSupported, "Operation pwrite Not supported"); return -1; } dav_ssize_t DavPosix::pwrite64(DAVIX_FD *fd, const void *buf, dav_size_t count, dav_off_t offset, DavixError **err){ (void) fd; (void) buf; (void) count; (void) offset; DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_pwrite); DavixError::setupError(err, davix_scope_io_buff(), StatusCode::OperationNonSupported, "Operation pwrite Not supported"); return -1; } dav_ssize_t DavPosix::preadVec(DAVIX_FD* fd, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, dav_size_t count_vec, DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_preadvec); ssize_t ret =-1; DavixError* tmp_err=NULL; TRY_DAVIX{ if( davix_check_rw_fd(fd, &tmp_err) ==0){ ret = fd->io_handler.preadVec(fd->io_context, input_vec, output_vec, count_vec); } }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return ret; } ssize_t DavPosix::write(DAVIX_FD* fd, const void* buf, size_t count, Davix::DavixError** err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_write); ssize_t ret =-1; DavixError* tmp_err=NULL; TRY_DAVIX{ if( davix_check_rw_fd(fd, &tmp_err) ==0){ ret = (ssize_t) fd->io_handler.write(fd->io_context, buf, (dav_size_t) count); } }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return ret; } off_t DavPosix::lseek(DAVIX_FD* fd, off_t offset, int flags, Davix::DavixError** err){ dav_off_t res = lseek64(fd, static_cast(offset), flags, err); if(res > std::numeric_limits::max()) return std::numeric_limits::max(); return res; } dav_off_t DavPosix::lseek64(DAVIX_FD *fd, dav_off_t offset, int flags, DavixError **err){ DAVIX_SCOPE_TRACE(DAVIX_LOG_POSIX, fun_lseek); ssize_t ret =-1; DavixError* tmp_err=NULL; TRY_DAVIX{ if( davix_check_rw_fd(fd, &tmp_err) ==0){ ret = fd->io_handler.lseek(fd->io_context, offset, flags); } }CATCH_DAVIX(&tmp_err) DavixError::propagateError(err, tmp_err); return ret; } int DavPosix::close(DAVIX_FD* fd, Davix::DavixError** err){ TRY_DAVIX{ if(fd){ fd->io_handler.resetIO(fd->io_context); delete fd; } }CATCH_DAVIX(err) return 0; } } // namespace Davix davix-R_0_5_0/src/fileops/000077500000000000000000000000001257152637300155155ustar00rootroot00000000000000davix-R_0_5_0/src/fileops/chain_factory.cpp000066400000000000000000000027611257152637300210400ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "chain_factory.hpp" #include "davmeta.hpp" #include "httpiovec.hpp" #include "davix_reliability_ops.hpp" #include "iobuffmap.hpp" namespace Davix{ ChainFactory::ChainFactory(){} HttpIOChain& ChainFactory::instanceChain(const CreationFlags & flags, HttpIOChain & c){ HttpIOChain* elem; elem= c.add(new MetalinkOps())->add(new AutoRetryOps())->add(new S3MetaOps())->add(new HttpMetaOps()); // add posix to the chain if needed if(flags[CHAIN_POSIX] == true){ elem = elem->add(new HttpIOBuffer()); } elem->add(new HttpIO())->add(new HttpIOVecOps()); return c; } } davix-R_0_5_0/src/fileops/chain_factory.hpp000066400000000000000000000024411257152637300210400ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef CHAIN_FACTORY_HPP #define CHAIN_FACTORY_HPP #include #include #include namespace Davix{ const int CHAIN_POSIX = 1; typedef std::bitset<32> CreationFlags; class ChainFactory { public: static HttpIOChain& instanceChain(const CreationFlags & flags, HttpIOChain & c); private: ChainFactory(); }; } #endif // CHAIN_FACTORY_HPP davix-R_0_5_0/src/fileops/davix_reliability_ops.cpp000066400000000000000000000324231257152637300226120ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "davix_reliability_ops.hpp" #include #include #include #include namespace Davix{ using namespace StrUtil; using namespace boost; typedef function< dav_ssize_t (IOChainContext &)> FuncIO; typedef function< StatInfo & (IOChainContext &) > FuncStatInfo; static bool metalink_support_disabled=false; static once_flag metalink_once = BOOST_ONCE_INIT; void propagateNonRecoverableExceptions(DavixException & e){ /// Forward redirections and other error we don't want to recover if(e.code() == StatusCode::RedirectionNeeded || e.code() == StatusCode::OperationTimeout){ throw e; } } void metalink_check(){ metalink_support_disabled = (getenv("DAVIX_DISABLE_METALINK") != NULL); } static bool isMetalinkDisabled(const RequestParams* params){ call_once(metalink_check, metalink_once); return (params != NULL && params->getMetalinkMode() == MetalinkMode::Disable) || metalink_support_disabled; } template ReturnType metalinkTryReplicas(HttpIOChain & chain, IOChainContext & io_context, Executor fun){ std::vector replicas; // check if we expired io_context.checkTimeout(); // get all replicas from Metalink chain.getReplicas(io_context, replicas); for(std::vector::iterator it = replicas.begin();it != replicas.end(); ++it){ try{ IOChainContext internal_context(io_context._context, it->getUri(), io_context._reqparams); return fun(internal_context); }catch(DavixException & replica_error){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Fail access to replica {}: {}", it->getUri(), replica_error.what()); }catch(...){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Fail access to replica: Unknown Error"); } // check timeout again between two iterations io_context.checkTimeout(); } throw DavixException(davix_scope_io_buff(), StatusCode::InvalidServerResponse, "Impossible to access any of the replicas with success"); } template ReturnType metalinkExecutor(HttpIOChain & chain, IOChainContext & io_context, Executor fun){ // if disabled, do nothing if(isMetalinkDisabled(io_context._reqparams)){ return fun(io_context); } try{ // Execute operation return fun(io_context); }catch(DavixException & e){ propagateNonRecoverableExceptions(e); DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Failure: Impossible to execute operation on {}, error {}", io_context._uri.getString(), e.what()); DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Try to Recover with Metalink..."); try{ return metalinkTryReplicas(chain, io_context, fun); }catch(DavixException & metalink_error){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Impossible to Recover with Metalink: {}", metalink_error.what()); }catch(...){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Impossible to Recover with Metalink: Unknown Error"); } throw e; } } int davix_metalink_header_parser(const std::string & header_key, const std::string & header_value, const Uri & u_original, Uri & metalink){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Parse headers for metalink {} {}", header_key, header_value); if(compare_ncase(header_key, "Link") ==0 && header_value.find("application/metalink") != std::string::npos){ std::string::const_iterator it1, it2; if( ( it1 = std::find(header_value.begin(), header_value.end(), '<')) != header_value.end() && ( it2 = std::find(it1, header_value.end(), '>')) != header_value.end()){ std::string metalink_url(it1+1, it2); metalink = Uri::fromRelativePath(u_original, trim(metalink_url)); if(metalink.getStatus() == StatusCode::OK){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Valid metalink URI found {}", metalink.getString()); return 1; } } } return 0; } bool davix_metalink_header_content_type(const std::string & header_key, const std::string & header_value){ return (compare_ncase(header_key, "Content-type") ==0 && header_value.find("application/metalink") !=std::string::npos); } int davix_get_metalink_url( Context & c, const Uri & uri, const RequestParams & _params, Uri & metalink){ DavixError* tmp_err = NULL; RequestParams params(_params); // don't follow redirect, we need headers params.setTransparentRedirectionSupport(false); HeadRequest req(c, uri, &tmp_err); req.setParameters(params); req.addHeaderField("Accept", "application/metalink4+xml"); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Executing head query to {} for Metalink file", uri.getString()); if(tmp_err != NULL || (req.executeRequest(&tmp_err) <0)) { if (tmp_err) throw DavixException(davix_scope_meta(), tmp_err->getStatus(), tmp_err->getErrMsg()); else throw DavixException(davix_scope_meta(), Davix::StatusCode::UnknowError, "Unknown error"); } HeaderVec headers; req.getAnswerHeaders(headers); for(HeaderVec::iterator it = headers.begin(); it != headers.end(); it++){ if( davix_metalink_header_parser(it->first, it->second, uri, metalink) > 0) return 1; if(davix_metalink_header_content_type(it->first, it->second)){ // is a metalink content type, get it metalink = uri; return 1; } } return 0; } int davix_file_get_metalink_to_vfile(Context & c, const Uri & metalink_uri, const RequestParams & _params, std::vector & vec){ DavixError * tmp_err=NULL; GetRequest req(c, metalink_uri, &tmp_err); MetalinkParser parser(c, vec); req.setParameters(_params); req.addHeaderField("Accept", "application/metalink4+xml"); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Executing query for {} Metalink content", metalink_uri.getString()); if(tmp_err != NULL || (req.beginRequest(&tmp_err) <0) ) throw DavixException(davix_scope_meta(), tmp_err->getStatus(), tmp_err->getErrMsg()); if(httpcodeIsValid(req.getRequestCode()) == false){ throw DavixException(davix_scope_meta(), StatusCode::InvalidServerResponse, fmt::format("Unable to get Metalink file, error HTTP {}", req.getRequestCode())); } dav_ssize_t read_size; do{ char buffer[2049]; buffer[2048] = '\0'; if( (read_size = req.readSegment(buffer, 2048, &tmp_err)) < 0) throw DavixException(davix_scope_meta(), tmp_err->getStatus(), tmp_err->getErrMsg()); parser.parseChunk(buffer, read_size); }while(read_size > 0); req.endRequest(NULL); return vec.size(); } void davix_file_get_all_replicas_metalink( Context & c, const Uri & uri, const RequestParams & _params, std::vector & vec){ Uri metalink; if(davix_get_metalink_url(c, uri, _params, metalink) > 0 && davix_file_get_metalink_to_vfile(c, metalink,_params, vec) > 0){ return; } throw DavixException(davix_scope_meta(), StatusCode::OperationNonSupported, "Server does not support Metalink standard"); } MetalinkOps::MetalinkOps() { } MetalinkOps::~MetalinkOps(){ } std::vector & MetalinkOps::getReplicas(IOChainContext & iocontext, std::vector &vec){ davix_file_get_all_replicas_metalink(iocontext._context, iocontext._uri, iocontext._reqparams, vec); return vec; } StatInfo & MetalinkOps::statInfo(IOChainContext &iocontext, StatInfo &st_info){ FuncStatInfo func(bind(&HttpIOChain::statInfo, _next.get(), _1, ref(st_info))); return metalinkExecutor(*this, iocontext, func); } dav_ssize_t MetalinkOps::read(IOChainContext &iocontext, void *buf, dav_size_t count){ FuncIO func(bind(&HttpIOChain::read, _next.get(),_1, buf, count)); return metalinkExecutor(*this, iocontext, func); } dav_ssize_t MetalinkOps::pread(IOChainContext &iocontext, void *buf, dav_size_t count, dav_off_t offset){ FuncIO func(bind(&HttpIOChain::pread, _next.get(),_1, buf, count, offset)); return metalinkExecutor(*this, iocontext, func); } dav_ssize_t MetalinkOps::preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec){ FuncIO func(bind(&HttpIOChain::preadVec, _next.get(),_1, input_vec, output_vec, count_vec)); return metalinkExecutor(*this, iocontext, func); } // read to fd Metalink manager dav_ssize_t MetalinkOps::readToFd(IOChainContext & iocontext, int fd, dav_size_t size){ FuncIO func(bind(&HttpIOChain::readToFd, _next.get(), _1, fd, size)); return metalinkExecutor(*this, iocontext, func); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// template ReturnType autoRetryExecutor(HttpIOChain & chain, IOChainContext & io_context, Executor fun){ (void) chain; const int max_retry = io_context._reqparams->getOperationRetry(); const int retry_delay = io_context._reqparams->getOperationRetryDelay(); int retry =1; const Uri & u = io_context._uri; while(1){ io_context.checkTimeout(); try{ return fun(io_context); }catch(DavixException & error){ // propagate fatal exceptions and connection error exceptions propagateNonRecoverableExceptions(error); // we can not recover from connexion timeout // throw exception, cancel IO chain request if(error.code() == StatusCode::ConnectionTimeout){ throw error; } // we should also just give up if the server responds with 403 or 405 else if(error.code() == StatusCode::PermissionRefused){ throw error; } DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Operation failure: {}. After {} retry", error.what(), retry); if( retry >= max_retry){ throw DavixException(error.scope(), error.code(), fmt::format("Failure {} after {} attempts", error.what(), retry)); } }catch(...){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_CHAIN, "Operation failure: Unknown Error"); throw DavixException(davix_scope_io_buff(), StatusCode::UnknowError, fmt::format("Unrecoverable error from IOChain on {}", u)); } ++retry; sleep(retry_delay); } } AutoRetryOps::AutoRetryOps(){ } AutoRetryOps::~AutoRetryOps(){ } StatInfo & AutoRetryOps::statInfo(IOChainContext &iocontext, StatInfo &st_info){ FuncStatInfo func(bind(&HttpIOChain::statInfo, _next.get(), _1, ref(st_info))); return autoRetryExecutor(*this, iocontext, func); } dav_ssize_t AutoRetryOps::read(IOChainContext &iocontext, void *buf, dav_size_t count){ FuncIO func(bind(&HttpIOChain::read, _next.get(),_1, buf, count)); return autoRetryExecutor(*this, iocontext, func); } dav_ssize_t AutoRetryOps::pread(IOChainContext &iocontext, void *buf, dav_size_t count, dav_off_t offset){ FuncIO func(bind(&HttpIOChain::pread, _next.get(),_1, buf, count, offset)); return autoRetryExecutor(*this, iocontext, func); } dav_ssize_t AutoRetryOps::preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec){ FuncIO func(bind(&HttpIOChain::preadVec, _next.get(),_1, input_vec, output_vec, count_vec)); return autoRetryExecutor(*this, iocontext, func); } // read to fd Metalink manager dav_ssize_t AutoRetryOps::readToFd(IOChainContext & iocontext, int fd, dav_size_t size){ FuncIO func(bind(&HttpIOChain::readToFd, _next.get(), _1, fd, size)); return autoRetryExecutor(*this, iocontext, func); } } // namespace Davix davix-R_0_5_0/src/fileops/davix_reliability_ops.hpp000066400000000000000000000062501257152637300226160ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef METALINKOPS_HPP #define METALINKOPS_HPP #include #include #include #include namespace Davix{ /// /// \brief The MetalinkOps class /// /// Metalink chain element /// /// the metalink chain element handle the recovery using metalink for any "reading" operation of the I/O chain /// class MetalinkOps: public HttpIOChain{ public: MetalinkOps(); virtual ~MetalinkOps(); virtual StatInfo & statInfo(IOChainContext &iocontext, StatInfo &st_info); virtual dav_ssize_t read(IOChainContext & iocontext, void *buf, dav_size_t count); virtual dav_ssize_t pread(IOChainContext & iocontext, void* buf, dav_size_t count, dav_off_t offset); virtual dav_ssize_t preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec); // read to fd virtual dav_ssize_t readToFd(IOChainContext & iocontext, int fd, dav_size_t size); // calc replica virtual std::vector & getReplicas(IOChainContext & iocontext, std::vector & vec); }; /// \brief The AutoRetry class /// /// AutoRetry chain element /// /// the Retry chain element handle the recovery using auto-retry for any "reading" operation of the I/O chain /// class AutoRetryOps: public HttpIOChain{ public: AutoRetryOps(); virtual ~AutoRetryOps(); virtual StatInfo & statInfo(IOChainContext &iocontext, StatInfo &st_info); virtual dav_ssize_t read(IOChainContext & iocontext, void *buf, dav_size_t count); virtual dav_ssize_t pread(IOChainContext & iocontext, void* buf, dav_size_t count, dav_off_t offset); virtual dav_ssize_t preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec); // read to fd virtual dav_ssize_t readToFd(IOChainContext & iocontext, int fd, dav_size_t size); }; // utilities int davix_metalink_header_parser(const std::string & header_key, const std::string & header_value, const Uri & u_original, Uri & metalink); } #endif // METALINKOPS_HPP davix-R_0_5_0/src/fileops/davmeta.cpp000066400000000000000000000627151257152637300176550ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "davmeta.hpp" #include #include #include #include #include #include #include #include #include #include #include #include using namespace StrUtil; namespace Davix{ static const std::string simple_listing(""); static const std::string stat_listing("" "" "" "" ""); struct DirHandle{ DirHandle(HttpRequest* req, XMLPropParser * p): request(req), parser(p){} Ptr::Scoped request; Ptr::Scoped parser; }; /** execute a propfind/stat request on a given HTTP request handle return a vector with the content of the request if success */ std::vector req_webdav_propfind(HttpRequest* req, DavixError** err){ DavixError* tmp_err=NULL; int ret =-1; std::vector res; req->addHeaderField("Depth","0"); req->setRequestMethod("PROPFIND"); if( (ret = req->executeRequest(&tmp_err)) ==0){ ret = davixRequestToFileStatus(req, davix_scope_stat_str(), &tmp_err); res.swap(req->getAnswerContentVec()); } if(ret != 0) DavixError::propagateError(err, tmp_err); return res; } int dav_stat_mapper_webdav(Context &context, const RequestParams* params, const Uri & url, struct StatInfo& st_info){ int ret =-1; DavPropXMLParser parser; DavixError * tmp_err=NULL; HttpRequest req(context, url, &tmp_err); if( tmp_err == NULL){ req.setParameters(params); TRY_DAVIX{ std::vector body = req_webdav_propfind(&req, &tmp_err); if(!tmp_err){ parser.parseChunk(&(body[0]), body.size()); std::deque & props = parser.getProperties(); if( props.size() < 1){ throw DavixException(davix_scope_stat_str(), Davix::StatusCode::WebDavPropertiesParsingError, "Parsing Error : properties number < 1"); }else{ st_info = props.front().info; ret =0; } } }CATCH_DAVIX(&tmp_err) if(tmp_err != NULL) ret = -1; } checkDavixError(&tmp_err); return ret; } int dav_stat_mapper_http(Context& context, const RequestParams* params, const Uri & uri, struct StatInfo& st_info){ int ret = -1; DavixError * tmp_err=NULL; HeadRequest req(context, uri, &tmp_err); if( tmp_err == NULL){ req.setParameters(params); req.executeRequest(&tmp_err); if(!tmp_err){ if(httpcodeIsValid(req.getRequestCode()) ){ memset(&st_info, 0, sizeof(struct StatInfo)); const dav_ssize_t s = req.getAnswerSize(); st_info.size = std::max(0,s); st_info.mode = 0755 | S_IFREG; ret = 0; }else{ httpcodeToDavixError(req.getRequestCode(), davix_scope_http_request(), uri.getString() , &tmp_err); ret = -1; } } } checkDavixError(&tmp_err); return ret; } dav_ssize_t incremental_listdir_parsing(HttpRequest* req, XMLPropParser * parser, dav_size_t s_buff, const std::string & scope){ // std::cout << "time 1 pre-fecth" << time(NULL) << std::endl; DavixError* tmp_err=NULL; char buffer[s_buff+1]; const dav_ssize_t ret = req->readSegment(buffer, s_buff, &tmp_err); checkDavixError(&tmp_err); if(ret >= 0){ buffer[ret]= '\0'; parser->parseChunk(buffer, ret); }else{ throw DavixException(scope, StatusCode::UnknowError, "Unknow readSegment error"); } return ret; } dav_ssize_t getStatInfo(Context & c, const Uri & url, const RequestParams * p, struct StatInfo& st_info){ RequestParams params(p); configureRequestParamsProto(url, params); int ret =-1; switch(params.getProtocol()){ case RequestProtocol::Webdav: ret = dav_stat_mapper_webdav(c, ¶ms, url, st_info); break; default: ret = dav_stat_mapper_http(c, ¶ms, url, st_info); break; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " davix_stat <-"); return ret; } void parse_creation_deletion_result(int code, const Uri & u, const std::string & scope, const std::vector & body){ switch(code){ case 200: case 201: case 202: case 204:{ return; } case 207:{ // parse webdav DavDeleteXMLParser parser; parser.parseChunk(&(body[0]), body.size()); if( parser.getProperties().size() > 0){ for(unsigned int i=0; i < parser.getProperties().size(); ++i){ const int sub_code = parser.getProperties().at(i).req_status; std::ostringstream ss; ss << "occurred during deletion request for " << parser.getProperties().at(i).filename; if(httpcodeIsValid(sub_code) == false){ httpcodeToDavixException(sub_code, scope, ss.str()); } } return; } // if no properties, properties were filtered because invalid httpcodeToDavixException(404, scope); break; } } std::ostringstream ss; ss << " with url " << u.getString(); httpcodeToDavixException(code, scope, ss.str()); } int internal_delete_resource(Context & c, const Uri & url, const RequestParams & params){ DavixError* tmp_err=NULL; int ret=-1; RequestParams _params(params); DeleteRequest req(c, url, &tmp_err); req.setParameters(_params); if(!tmp_err){ if( ( ret=req.executeRequest(&tmp_err)) == 0){ parse_creation_deletion_result(req.getRequestCode(), url, davix_scope_rm_str(), req.getAnswerContentVec()); } } checkDavixError(&tmp_err); return ret; } int internal_make_collection(Context & c, const Uri & url, const RequestParams & params){ DAVIX_SCOPE_TRACE(DAVIX_LOG_CHAIN, mkcoll); int ret=-1; DavixError* tmp_err=NULL; RequestParams _params(params); HttpRequest req(c, url, &tmp_err); if(tmp_err == NULL){ req.setParameters(params); req.setRequestMethod("MKCOL"); if( (ret = req.executeRequest(&tmp_err)) == 0){ parse_creation_deletion_result(req.getRequestCode(), url, davix_scope_mkdir_str(), req.getAnswerContentVec()); } } checkDavixError(&tmp_err); return ret; } int internal_move(Context & c, const Uri & url, const RequestParams & params, const std::string & target_url){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> move"); int ret=-1; DavixError* tmp_err=NULL; RequestParams _params(params); HttpRequest req(c, url, &tmp_err); if(tmp_err == NULL){ req.setParameters(params); req.setRequestMethod("MOVE"); req.addHeaderField("Destination", target_url); if( (ret = req.executeRequest(&tmp_err)) == 0){ parse_creation_deletion_result(req.getRequestCode(), url, davix_scope_mv_str(), req.getAnswerContentVec()); } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " move <-"); checkDavixError(&tmp_err); return ret; } int internal_checksum(Context & c, const Uri & url, const RequestParams *p, std::string & checksm, const std::string & chk_algo){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> checksum"); int ret=-1; DavixError* tmp_err=NULL; RequestParams params(p); HeadRequest req(c, url, &tmp_err); if(tmp_err == NULL){ // add Digest file, support for other digest, extended format req.addHeaderField("Want-Digest", chk_algo); req.setParameters(params); if( (ret = req.executeRequest(&tmp_err)) == 0 && (ret = davixRequestToFileStatus(&req, davix_scope_mkdir_str(), &tmp_err)) >=0){ // try simple MD5 ( standard ) if(compare_ncase(chk_algo, "MD5") == 0){ std::string chk; if(req.getAnswerHeader("Content-MD5", chk) == true){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Extract MD5 checksum in base64 {}", chk); chk= Base64::base64_decode(chk); std::swap(checksm, chk); return 0; } } // fallback on extension for checksum std::string digest; req.getAnswerHeader("Digest", digest); if (digest.empty() == false){ size_t valueOffset = digest.find('='); if (valueOffset == std::string::npos || compare_ncase(digest,0, valueOffset, chk_algo.c_str()) !=0) throw DavixException(davix_scope_meta(), StatusCode::InvalidServerResponse, "Invalid server checksum answer"); digest.erase(digest.begin(), digest.begin()+valueOffset+1); std::swap(checksm, digest); return 0; } // last chance try to extract MD5 checksum from ETAG ( S3 work around ) std::string etag_str; if(compare_ncase(chk_algo, "MD5") ==0 && req.getAnswerHeader("etag", etag_str)){ stringVec tokens = tokenSplit(etag_str, "&;\\/\"'"); for(stringVec::iterator it = tokens.begin(); it < tokens.end(); it++){ if(it->size() == 32 && std::find_if(it->begin(), it->end(), std::not1(StrUtil::isHexa())) == it->end()){ std::swap(checksm, *it); return 0; } } } std::ostringstream ss; ss << "checksum calculation for " << chk_algo << "not supported for " << url; throw DavixException(davix_scope_meta(), StatusCode::OperationNonSupported, ss.str()); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " checksum <-"); return 0; } } throw DavixException(&tmp_err); } bool wedav_get_next_property(Ptr::Scoped & handle, std::string & name_entry, StatInfo & info){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> wedav_get_next_property"); const size_t read_size = 2048; HttpRequest& req = *(handle->request); // setup env again XMLPropParser& parser = *(handle->parser); size_t prop_size = parser.getProperties().size(); ssize_t s_resu = read_size; while( prop_size == 0 && s_resu > 0){ // request not complete and current data too smalls // continue the parsing until one more result s_resu = incremental_listdir_parsing(&req, &parser, read_size, "WebDav::listing"); prop_size = parser.getProperties().size(); } if(prop_size == 0){ return false; // end of the request, end of the story } FileProperties & front = parser.getProperties().front(); name_entry.swap(front.filename); info = front.info; parser.getProperties().pop_front(); // clean the current element return true; } void webdav_start_listing_query(Ptr::Scoped & handle, Context & context, const RequestParams* params, const Uri & url, const std::string & body){ dav_ssize_t s_resu; DavixError* tmp_err=NULL; handle.reset(new DirHandle(new PropfindRequest(context, url, &tmp_err), new DavPropXMLParser())); checkDavixError(&tmp_err); HttpRequest & http_req = *(handle->request); XMLPropParser & parser = *(handle->parser); http_req.addHeaderField("Depth","1"); http_req.setParameters(params); // setup the handle for simple listing only http_req.setRequestBody(body); http_req.beginRequest(&tmp_err); checkDavixError(&tmp_err); check_file_status(http_req, davix_scope_directory_listing_str()); size_t prop_size = 0; do{ // parse the begining of the request until the first property -> directory property s_resu = incremental_listdir_parsing(&http_req, &parser, 2048, davix_scope_directory_listing_str()); prop_size = parser.getProperties().size(); if(s_resu < 2048 && prop_size <1){ // verify request status : if req done + no data -> error throw DavixException(davix_scope_directory_listing_str(), StatusCode::WebDavPropertiesParsingError, "bad server answer, not a valid WebDav PROPFIND answer"); } }while( prop_size < 1); // leave is end of req & no data const StatInfo & info = parser.getProperties().at(0).info; if( S_ISDIR(info.mode) == false){ std::ostringstream ss; ss << url << " is not a collection, listing impossible"; throw DavixException(davix_scope_directory_listing_str(), StatusCode::IsNotADirectory, ss.str()); }else{ parser.getProperties().pop_front(); // suppress the parent directory infos... } } bool webdav_directory_listing(Ptr::Scoped & handle, Context & context, const RequestParams* params, const Uri & uri, const std::string & body, std::string & name_entry, StatInfo & info){ if(handle.get() == NULL){ webdav_start_listing_query(handle, context, params, uri, body); } return wedav_get_next_property(handle, name_entry, info); } HttpMetaOps::HttpMetaOps(): HttpIOChain(){} HttpMetaOps::~HttpMetaOps(){} void HttpMetaOps::checksum(IOChainContext & iocontext, std::string &checksm, const std::string &chk_algo){ internal_checksum(iocontext._context, iocontext._uri, iocontext._reqparams, checksm, chk_algo); } void HttpMetaOps::makeCollection(IOChainContext & iocontext){ internal_make_collection(iocontext._context, iocontext._uri, iocontext._reqparams); } void HttpMetaOps::move(IOChainContext & iocontext, const std::string & target_url){ internal_move(iocontext._context, iocontext._uri, iocontext._reqparams, target_url); } void HttpMetaOps::deleteResource(IOChainContext & iocontext){ internal_delete_resource(iocontext._context, iocontext._uri, iocontext._reqparams); } StatInfo & HttpMetaOps::statInfo(IOChainContext & iocontext, StatInfo &st_info){ struct stat st; memset(&st, 0, sizeof(struct stat)); getStatInfo(iocontext._context, iocontext._uri, iocontext._reqparams, st_info); return st_info; } bool HttpMetaOps::nextSubItem(IOChainContext &iocontext, std::string &entry_name, StatInfo &info){ return webdav_directory_listing(directoryItem, iocontext._context, iocontext._reqparams, iocontext._uri, stat_listing, entry_name, info); } ///////////////////////// ///////////////////////// bool is_a_bucket(const Uri & u){ const std::string & s = u.getPath(); return (std::find_if(s.begin(), s.end(), std::not1(StrUtil::isSlash())) == s.end()); // false if pathname does not match '\/+' } S3MetaOps::S3MetaOps() : HttpIOChain() {} S3MetaOps::~S3MetaOps(){} static bool is_s3_operation(IOChainContext & context){ const std::string & proto = context._uri.getProtocol(); const RequestProtocol::Protocol protocol_flag = context._reqparams->getProtocol(); return ( proto.compare(0, 2, "s3") ==0 || protocol_flag == RequestProtocol::AwsS3); } void internal_s3_creat_bucket(Context & c, const Uri & url, const RequestParams & params){ DavixError * tmp_err=NULL; PutRequest req(c, url, &tmp_err); checkDavixError(&tmp_err); req.setParameters(params); if( req.executeRequest(&tmp_err) < 0){ const int code = req.getRequestCode(); httpcodeToDavixException(code, davix_scope_meta(), "bucket creation failure"); } checkDavixError(&tmp_err); } void S3MetaOps::checksum(IOChainContext &iocontext, std::string &checksm, const std::string &chk_algo){ internal_checksum(iocontext._context, iocontext._uri, iocontext._reqparams, checksm, chk_algo); } void S3MetaOps::makeCollection(IOChainContext &iocontext){ if(is_s3_operation(iocontext)){ internal_s3_creat_bucket( iocontext._context, iocontext._uri, iocontext._reqparams); }else{ HttpIOChain::makeCollection(iocontext); } } void s3StatMapper(Context& context, const RequestParams* params, const Uri & uri, struct StatInfo& st_info){ const std::string scope = "Davix::s3StatMapper"; DavixError * tmp_err=NULL; HeadRequest req(context, uri, &tmp_err); // we need to modify it, hence copy RequestParams p(params); // we just need to know if target has anything inside it p.setS3MaxKey(1); if( tmp_err == NULL){ req.setParameters(p); req.executeRequest(&tmp_err); const int code = req.getRequestCode(); // if 404, target either doesn't exist or is a S3 "directory" if(code == 404){ // try to "list" target resource and see if there is anything inside it, if there is, then it's a directory Uri new_url = S3::s3UriTransformer(uri, p, true); DirHandle handle(new GetRequest(context, new_url, &tmp_err), new S3PropParser(params->getS3ListingMode(), uri.getPath())); dav_ssize_t s_resu=0; const int operation_timeout = p.getOperationTimeout()->tv_sec; HttpRequest & http_req = *(handle.request); XMLPropParser & parser = *(handle.parser); time_t timestamp_timeout = time(NULL) + ((operation_timeout)?(operation_timeout):180); http_req.setParameters(p); http_req.beginRequest(&tmp_err); checkDavixError(&tmp_err); check_file_status(http_req, scope); size_t prop_size = 0; do{ // first entry TRY_DAVIX{ s_resu = incremental_listdir_parsing(&http_req, &parser, 2048, scope); }CATCH_DAVIX(&tmp_err) if(tmp_err && (tmp_err->getStatus() == StatusCode::IsNotADirectory)){ std::ostringstream ss; ss << uri << " not found"; throw DavixException(scope, StatusCode::FileNotFound, ss.str()); } prop_size = parser.getProperties().size(); if(s_resu < 2048 && prop_size <1){ // verify request status : if req done + no data -> error throw DavixException(scope, StatusCode::ParsingError, "Invalid server response, not a S3 listing"); } if(timestamp_timeout < time(NULL)){ throw DavixException(scope, StatusCode::OperationTimeout, "Operation timeout triggered while getting S3 object's stats"); } }while( prop_size < 1); // prop < 1 means not enough data st_info.mode = 0755; st_info.mode |= S_IFDIR; } else if(code == 200){ // found something, must be a file not directory std::string length; std::string type; st_info.mode = 0755; if(uri.getPath() == "/") // is bucket st_info.mode |= S_IFDIR; else{ // is file st_info.mode |= S_IFREG; const dav_ssize_t s = req.getAnswerSize(); st_info.size = std::max(0,s); st_info.mtime = req.getLastModified(); } } else if(code == 500) throw DavixException(scope, StatusCode::UnknowError, "Internal Server Error triggered while attempting to get S3 object's stats"); } checkDavixError(&tmp_err); } // get statInfo StatInfo & S3MetaOps::statInfo(IOChainContext & iocontext, StatInfo & st_info){ if(is_s3_operation(iocontext)){ s3StatMapper(iocontext._context, iocontext._reqparams, iocontext._uri, st_info); return st_info; } else{ StatInfo & ref = HttpIOChain::statInfo(iocontext, st_info); return ref; } } bool s3_get_next_property(Ptr::Scoped & handle, std::string & name_entry, StatInfo & info){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> s3_get_next_property"); const size_t read_size = 2048; HttpRequest& req = *(handle->request); // setup env again XMLPropParser& parser = *(handle->parser); size_t prop_size = parser.getProperties().size(); ssize_t s_resu = read_size; while( prop_size == 0 && s_resu > 0){ // execute request only if no property are available // continue the parsing until one more result s_resu = incremental_listdir_parsing(&req, &parser, read_size, "S3::listing"); prop_size = parser.getProperties().size(); } if(prop_size == 0){ return false; // end of the request, end of the story } FileProperties & front = parser.getProperties().front(); name_entry.swap(front.filename); info = front.info; parser.getProperties().pop_front(); // clean the current element return true; } void s3_start_listing_query(Ptr::Scoped & handle, Context & context, const RequestParams* params, const Uri & url, const std::string & body){ (void) body; dav_ssize_t s_resu; DavixError* tmp_err=NULL; if(params->getS3ListingMode() == S3ListingMode::Hierarchical){ Uri new_url = S3::s3UriTransformer(url, params, true); handle.reset(new DirHandle(new GetRequest(context, new_url, &tmp_err), new S3PropParser(params->getS3ListingMode(), url.getPath()))); } else if(params->getS3ListingMode() == S3ListingMode::SemiHierarchical){ Uri new_url = S3::s3UriTransformer(url, params, false); handle.reset(new DirHandle(new GetRequest(context, new_url, &tmp_err), new S3PropParser(params->getS3ListingMode(), url.getPath()))); } else{ if(is_a_bucket(url) == false){ throw DavixException(davix_scope_directory_listing_str(), StatusCode::IsNotADirectory, "This is not a S3 bucket"); } handle.reset(new DirHandle(new GetRequest(context, url, &tmp_err), new S3PropParser())); } checkDavixError(&tmp_err); const int operation_timeout = params->getOperationTimeout()->tv_sec; HttpRequest & http_req = *(handle->request); XMLPropParser & parser = *(handle->parser); time_t timestamp_timeout = time(NULL) + ((operation_timeout)?(operation_timeout):180); http_req.setParameters(params); http_req.beginRequest(&tmp_err); checkDavixError(&tmp_err); check_file_status(http_req, davix_scope_directory_listing_str()); size_t prop_size = 0; do{ // first entry -> bucket informations s_resu = incremental_listdir_parsing(&http_req, &parser, 2048, davix_scope_directory_listing_str()); prop_size = parser.getProperties().size(); if(s_resu < 2048 && prop_size <1){ // verify request status : if req done + no data -> error throw DavixException(davix_scope_directory_listing_str(), StatusCode::ParsingError, "Invalid server response, not a S3 listing"); } if(timestamp_timeout < time(NULL)){ throw DavixException(davix_scope_directory_listing_str(), StatusCode::OperationTimeout, "Operation timeout triggered while directory listing"); } }while( prop_size < 1); // prop < 1 means not enough data const StatInfo & info = parser.getProperties().at(0).info; if( S_ISDIR(info.mode) == false){ std::ostringstream ss; ss << url << " is not a S3 bucket"; throw DavixException(davix_scope_directory_listing_str(), StatusCode::IsNotADirectory, ss.str()); }else{ parser.getProperties().pop_front(); // suppress the bucket entry } } bool s3_directory_listing(Ptr::Scoped & handle, Context & context, const RequestParams* params, const Uri & uri, const std::string & body, std::string & name_entry, StatInfo & info){ if(handle.get() == NULL){ s3_start_listing_query(handle, context, params, uri, body); } return s3_get_next_property(handle, name_entry, info); } bool S3MetaOps::nextSubItem(IOChainContext &iocontext, std::string &entry_name, StatInfo &info){ if(is_s3_operation(iocontext)){ return s3_directory_listing(directoryItem, iocontext._context, iocontext._reqparams, iocontext._uri, stat_listing, entry_name, info); }else{ return HttpIOChain::nextSubItem(iocontext, entry_name, info); } } } // Davix davix-R_0_5_0/src/fileops/davmeta.hpp000066400000000000000000000056261257152637300176600ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVMETA_HPP #define DAVMETA_HPP #include #include #include #include namespace Davix{ struct DirHandle; /// /// \brief The HttpMetaOps class /// /// The HttpMetaOps handle all meta-data operations related to HTTP/Webdav class HttpMetaOps : public HttpIOChain{ public: HttpMetaOps(); virtual ~HttpMetaOps(); // calculate hecksum virtual void checksum(IOChainContext & iocontext, std::string & checksm, const std::string & chk_algo); // delete resource virtual void deleteResource(IOChainContext & iocontext); // make collection virtual void makeCollection(IOChainContext & iocontext); // move/rename resource virtual void move(IOChainContext & iocontext, const std::string & target_url); // get statInfo virtual StatInfo & statInfo(IOChainContext & iocontext, StatInfo & st_info); virtual bool nextSubItem(IOChainContext &iocontext, std::string &entry_name, StatInfo &info); private: Ptr::Scoped directoryItem; }; /// The HttpMetaOps handle all meta-data operations related to Aws S3 class S3MetaOps : public HttpIOChain{ public: S3MetaOps(); virtual ~S3MetaOps(); // S3 + HTTP checksum computation virtual void checksum(IOChainContext & iocontext, std::string & checksm, const std::string & chk_algo); // get statInfo virtual StatInfo & statInfo(IOChainContext & iocontext, StatInfo & st_info); // make collection virtual void makeCollection(IOChainContext & iocontext); // listing virtual bool nextSubItem(IOChainContext &iocontext, std::string &entry_name, StatInfo &info); private: Ptr::Scoped directoryItem; }; /* retrieve a webdav propfind stat request to the given url @param req : http request where to executethe query @return vector of characters of the query content */ std::vector req_webdav_propfind(HttpRequest* req, DavixError** err); } // Davix #endif // DAVMETA_HPP davix-R_0_5_0/src/fileops/fileutils.cpp000066400000000000000000000070241257152637300202240ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "fileutils.hpp" namespace Davix { const std::string ans_header_byte_range("Content-Range"); const std::string ans_header_content_type("Content-Type"); const std::string ans_header_multi_part_value("multipart"); const std::string ans_header_boundary_field("boundary="); const std::string ans_header_content_length("Content-Length"); const std::string offset_value("bytes="); const std::string req_header_byte_range("Range"); int davixRequestToFileStatus(HttpRequest* req, const std::string & scope, DavixError** err){ const int reqcode = req->getRequestCode(); int ret = 0; if( httpcodeIsValid(reqcode) == false){ DavixError* tmp_err=NULL; httpcodeToDavixError(reqcode, scope, "",&tmp_err); if(tmp_err && tmp_err->getStatus() != StatusCode::OK){ DavixError::propagateError(err, tmp_err); ret = -1; }else{ DavixError::clearError(&tmp_err); } } return ret; } void check_file_status(HttpRequest & req, const std::string & scope){ const int code =req.getRequestCode(); if( httpcodeIsValid(code) == false){ httpcodeToDavixException(code, scope); } } void setup_offset_request(HttpRequest* req, const dav_off_t *start_len, const dav_size_t *size_read, const dav_size_t number_ops){ std::ostringstream buffer; buffer << offset_value; for(size_t i = 0; i 0) buffer << ","; if(size_read[i] > 0) buffer << start_len[i] << "-"<< (start_len[i]+size_read[i]-1); else buffer << start_len [i]<< "-"; } req->addHeaderField(req_header_byte_range, buffer.str()); } std::vector< std::pair > generateRangeHeaders(dav_size_t max_header_size, OffsetCallback & offset_provider){ std::vector< std::pair > range_rec; dav_off_t begin, end; int ret; std::string range_string; dav_size_t range_size =0; std::ostringstream buffer; range_string.reserve(max_header_size); range_string.append(offset_value); while( ( ret = offset_provider(begin, end)) >= 0){ buffer.str(""); buffer << begin << '-' << end; range_string.append(buffer.str()); range_size++; if(range_string.size() >= max_header_size){ range_rec.push_back(std::make_pair(range_size, range_string)); range_size = 0; range_string.assign(offset_value); }else{ range_string.append(","); } } if(range_size > 0) range_rec.push_back(std::make_pair(range_size, range_string)); return range_rec; } } // namespace Davix davix-R_0_5_0/src/fileops/fileutils.hpp000066400000000000000000000037711257152637300202360ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_FILEUTILS_HPP #define DAVIX_FILEUTILS_HPP #include #include #include namespace Davix { extern const std::string ans_header_byte_range; extern const std::string ans_header_content_type; extern const std::string ans_header_multi_part_value; extern const std::string ans_header_boundary_field; extern const std::string ans_header_content_length; extern const std::string req_header_byte_range; // take a HTTP request status and convert file status to common errcode int davixRequestToFileStatus(HttpRequest* req, const std::string & scope, DavixError** err); void check_file_status(HttpRequest & req, const std::string & scope); // configure Range request void setup_offset_request(HttpRequest* req, const dav_off_t *start_len, const dav_size_t *size_read, const dav_size_t number_ops); typedef boost::function OffsetCallback; std::vector< std::pair > generateRangeHeaders(dav_size_t max_header_size, OffsetCallback & offset_provider); } // namespace Davix #endif // DAVIX_FILEUTILS_HPP davix-R_0_5_0/src/fileops/httpiochain.cpp000066400000000000000000000104711257152637300205360ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "httpiochain.hpp" #include namespace Davix{ HttpIOChain::HttpIOChain() : _next(NULL), _start(this) { } HttpIOChain::~HttpIOChain(){} HttpIOChain* HttpIOChain::add(HttpIOChain* elem){ _next.reset(elem); if(_next.get() != NULL){ _next->_start = this->_start; } return _next.get(); } // calculate hecksum void HttpIOChain::checksum(IOChainContext & iocontext, std::string & checksm, const std::string & chk_algo){ CHAIN_FORWARD(checksum(iocontext, checksm, chk_algo)); } // calc replica std::vector & HttpIOChain::getReplicas(IOChainContext & iocontext, std::vector & vec){ CHAIN_FORWARD(getReplicas(iocontext, vec)); } // delete resource void HttpIOChain::deleteResource(IOChainContext & iocontext){ CHAIN_FORWARD(deleteResource(iocontext)); } // make collection void HttpIOChain::makeCollection(IOChainContext & iocontext){ CHAIN_FORWARD(makeCollection(iocontext)); } // move/rename resource void HttpIOChain::move(IOChainContext & iocontext, const std::string & target_url){ CHAIN_FORWARD(move(iocontext, target_url)); } StatInfo & HttpIOChain::statInfo(IOChainContext & iocontext, StatInfo &st_info){ CHAIN_FORWARD(statInfo(iocontext, st_info)); } bool HttpIOChain::nextSubItem(IOChainContext &iocontext, std::string &entry_name, StatInfo &info){ CHAIN_FORWARD(nextSubItem(iocontext, entry_name, info)); } bool HttpIOChain::open(IOChainContext & iocontext, int flags){ CHAIN_FORWARD(open(iocontext, flags)); } void HttpIOChain::prefetchInfo(IOChainContext & iocontext, off_t offset, dav_size_t size_read, advise_t adv){ CHAIN_FORWARD(prefetchInfo(iocontext, offset, size_read, adv)); } dav_ssize_t HttpIOChain::readFull(IOChainContext & iocontext, std::vector &buffer){ CHAIN_FORWARD(readFull(iocontext, buffer)); } dav_ssize_t HttpIOChain::readFull(IOChainContext & iocontext, std::string & str_buffer){ std::vector buffer; dav_ssize_t s = readFull(iocontext, buffer); str_buffer.assign(buffer.begin(), buffer.end()); return s; } // read to fd dav_ssize_t HttpIOChain::readToFd(IOChainContext & iocontext, int fd, dav_size_t size){ CHAIN_FORWARD(readToFd(iocontext, fd, size)); } dav_ssize_t HttpIOChain::preadVec(IOChainContext & iocontext, const DavIOVecInput *input_vec, DavIOVecOuput *output_vec, const dav_size_t count_vec){ CHAIN_FORWARD(preadVec(iocontext, input_vec, output_vec, count_vec)); } void HttpIOChain::resetIO(IOChainContext & iocontext){ CHAIN_FORWARD(resetIO(iocontext)); } dav_ssize_t HttpIOChain::pread(IOChainContext & iocontext, void *buf, dav_size_t count, dav_off_t offset){ CHAIN_FORWARD(pread(iocontext, buf,count, offset)); } dav_ssize_t HttpIOChain::read(IOChainContext & iocontext, void *buf, dav_size_t count){ CHAIN_FORWARD(read(iocontext, buf, count)); } dav_off_t HttpIOChain::lseek(IOChainContext & iocontext, dav_off_t offset, int flags){ CHAIN_FORWARD(lseek(iocontext, offset, flags)); } dav_ssize_t HttpIOChain::writeFromFd(IOChainContext & iocontext, int fd, dav_size_t size){ CHAIN_FORWARD(writeFromFd(iocontext, fd, size)); } dav_ssize_t HttpIOChain::writeFromCb(IOChainContext &iocontext, const DataProviderFun &func, dav_size_t size){ CHAIN_FORWARD(writeFromCb(iocontext, func, size)); } dav_ssize_t HttpIOChain::write(IOChainContext & iocontext, const void *buf, dav_size_t count){ CHAIN_FORWARD(write(iocontext, buf, count)); } } // Davix davix-R_0_5_0/src/fileops/httpiochain.hpp000066400000000000000000000120721257152637300205420ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef HTTPIOCHAIN_HPP #define HTTPIOCHAIN_HPP #include namespace Davix{ class HttpIOChain; #define CHAIN_FORWARD(X) \ do{ \ if(_next.get() != NULL){ \ return _next->X; \ } \ throw DavixException(davix_scope_io_buff(), StatusCode::OperationNonSupported, "I/O operation not supported"); \ }while(0) // parameter handler for any IO Chain operation struct IOChainContext{ IOChainContext(Context & c, const Uri & u, const RequestParams * p): _context(c), _uri(u), _reqparams(p), _end_time() { if(_reqparams->getOperationTimeout()->tv_sec > 0){ _end_time = Chrono::Clock(Chrono::Clock::Monolitic).now(); _end_time += Chrono::Duration(_reqparams->getOperationTimeout()->tv_sec); } } void checkTimeout(){ if( _end_time.isValid() && _end_time < Chrono::Clock(Chrono::Clock::Monolitic).now()){ std::ostringstream ss; ss << "operation timeout of " << _reqparams->getOperationTimeout()->tv_sec << "s expired"; throw DavixException(davix_scope_io_buff(), StatusCode::OperationTimeout, ss.str()); } } // context parameter Context& _context; Uri const & _uri; RequestParams const * _reqparams; // Operation parameter Chrono::TimePoint _end_time; }; // Davix IO chain // Complete I/O Stack implementation of Davix class HttpIOChain : NonCopyable{ public: HttpIOChain(); virtual ~HttpIOChain(); HttpIOChain* add(HttpIOChain* elem); /* * Meta data opts * **/ // calculate hecksum virtual void checksum(IOChainContext & iocontext, std::string & checksm, const std::string & chk_algo); // calc replica virtual std::vector & getReplicas(IOChainContext & iocontext, std::vector & vec); // delete resource virtual void deleteResource(IOChainContext & iocontext); // make collection virtual void makeCollection(IOChainContext & iocontext); // move/rename resource virtual void move(IOChainContext & iocontext, const std::string & target_url); // get statInfo virtual StatInfo & statInfo(IOChainContext & iocontext, StatInfo & st_info); // listing // return false if end of directory is reached virtual bool nextSubItem(IOChainContext & iocontext, std::string & entry_name, StatInfo & info); /* * I/O Layer **/ virtual bool open(IOChainContext & iocontext, int flags); virtual void prefetchInfo(IOChainContext & iocontext, off_t offset, dav_size_t size_read, advise_t adv); virtual dav_ssize_t readFull(IOChainContext & iocontext, std::vector & buffer); // overloaded version for string content virtual dav_ssize_t readFull(IOChainContext & iocontext, std::string & buffer); // read to fd virtual dav_ssize_t readToFd(IOChainContext & iocontext, int fd, dav_size_t size); virtual dav_ssize_t preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec); // reset file position and status virtual void resetIO(IOChainContext & iocontext); // position independant read operation, // similar to pread except that does not need open() before virtual dav_ssize_t pread(IOChainContext & iocontext, void* buf, dav_size_t count, dav_off_t offset); // sequential read of a file from begining to the end virtual dav_ssize_t read(IOChainContext & iocontext, void* buf, dav_size_t count); // lseek prototype virtual dav_off_t lseek(IOChainContext & iocontext, dav_off_t offset, int flags); // write the entire content from a file descriptor virtual dav_ssize_t writeFromFd(IOChainContext & iocontext, int fd, dav_size_t size); // wirte the entire content from a defined callback virtual dav_ssize_t writeFromCb(IOChainContext & iocontext, const DataProviderFun & func, dav_size_t size); // sequential write virtual dav_ssize_t write(IOChainContext & iocontext, const void* buf, dav_size_t count); protected: Ptr::Scoped _next; HttpIOChain* _start; }; } #endif // HTTPIOCHAIN_HPP davix-R_0_5_0/src/fileops/httpiovec.cpp000066400000000000000000000450571257152637300202410ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "httpiovec.hpp" #include #include #include using namespace StrUtil; // remove trailing crlf template dav_size_t trim_crlf (InputIterator first, InputIterator last, dav_size_t s) { dav_size_t ret = s; while (--last >= first) { if(*last == '\n' || *last == '\r'){ *last = '\0'; ret--; }else{ break; } } return ret; } namespace Davix{ const std::string HttpIoVec_scope(){ return "Davix::HttpIOVecOps"; } void HttpIoVecSetupErrorMultiPart(DavixError** err){ DavixError::setupError(err, HttpIoVec_scope(), StatusCode::InvalidServerResponse, "Invalid Multi-Part HTTP response"); } void HttpIoVecSetupErrorMultiPartTooLong(DavixError** err){ DavixError::setupError(err, HttpIoVec_scope(), StatusCode::InvalidServerResponse, "Invalid Multi-Part HTTP, Multi-part header too long"); } void HttpIoVecSetupErrorMultiPartBoundary(const std::string & boundary, DavixError** err){ DavixError::setupError(err, HttpIoVec_scope(), StatusCode::InvalidServerResponse, std::string("Invalid boundary for multipart http reponse :").append(boundary)); } void HttpIoVecSetupErrorMultiPartSize( DavixError** err, dav_off_t req_offset, dav_size_t req_size, dav_off_t ans_offset, dav_size_t ans_size){ std::ostringstream ss; ss << "Invalid server answer for multi part, request offset:"<< req_offset <<" size:"<< req_size << ", answer offset:"<< ans_offset<< " size:"<< ans_size; DavixError::setupError(err, HttpIoVec_scope(), StatusCode::InvalidServerResponse, ss.str()); } inline char* header_delimiter(char* buffer, dav_size_t len){ char* p = std::find(buffer, buffer + len, ':'); return (p < buffer + len)?p:NULL; } // Vector operation option provider int davIOVecProvider(const DavIOVecInput *input_vec, dav_ssize_t & counter, dav_ssize_t number, dav_off_t & begin, dav_off_t & end){ if(counter < number){ begin = input_vec[counter].diov_offset; end = std::max(begin + input_vec[counter].diov_size -1, begin); return ++counter; } return -1; } dav_ssize_t HttpIOVecOps::preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec){ if(count_vec ==0) return 0; if(count_vec ==1){ // one offset read request, no need of multi part const dav_ssize_t res= _start->pread(iocontext, input_vec->diov_buffer, input_vec->diov_size, input_vec->diov_offset); output_vec->diov_buffer = input_vec->diov_buffer; output_vec->diov_size= res; return res; } DavixError * tmp_err=NULL; dav_ssize_t tmp_ret=-1, ret = 0; ptrdiff_t p_diff=0; dav_ssize_t counter = 0; // generator of offset boost::function offsetProvider( boost::bind(davIOVecProvider, input_vec, counter, (dav_ssize_t) count_vec, _1, _2)); // header line need to be inferior to 8K on Apache2 / ngnix // in Addition, some S3 implementation limit the total header size to 4k.... // 3900 bytes maximum for the range seems to be a ood compromise std::vector< std::pair > vecRanges = generateRangeHeaders(3900, offsetProvider); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> getPartialVec operation for {} vectors", count_vec); for(std::vector< std::pair >::iterator it = vecRanges.begin(); it < vecRanges.end(); ++it){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " -> getPartialVec request for {} chunks", it->first); if(it->first == 1){ // one chunk only : no need of multi part tmp_ret = _start->pread( iocontext, (input_vec + p_diff)->diov_buffer, (input_vec+p_diff)->diov_size, (input_vec+p_diff)->diov_offset); (output_vec+ p_diff)->diov_size = tmp_ret; (output_vec+ p_diff)->diov_buffer = (input_vec + p_diff)->diov_buffer; p_diff += 1; ret += tmp_ret; }else{ GetRequest req (iocontext._context, iocontext._uri, &tmp_err); if(tmp_err == NULL){ RequestParams request_params(iocontext._reqparams); req.setParameters(request_params); req.addHeaderField(req_header_byte_range, it->second); if( (tmp_ret = readPartialBufferVecRequest(req, input_vec+ p_diff, output_vec+ p_diff, it->first, &tmp_err)) <0){ ret = -1; break; } p_diff += it->first; ret += tmp_ret; }else{ ret = -1; break; } } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, " <- getPartialVec operation for {} vectors", count_vec); checkDavixError(&tmp_err); return ret; } dav_ssize_t HttpIOVecOps::readPartialBufferVecRequest(HttpRequest & _req, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** err){ dav_ssize_t ret=-1; DavixError* tmp_err=NULL; DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, " -> Davix Vector operation"); if( _req.beginRequest(&tmp_err) == 0){ const int retcode = _req.getRequestCode(); switch(retcode){ case 206: // multipart req ret = parseMultipartRequest(_req, input_vec, output_vec, count_vec, &tmp_err); break; case 200: // classical req, simulate vector ops ret = simulateMultiPartRequest(_req, input_vec, output_vec, count_vec, &tmp_err); break; default: httpcodeToDavixError(_req.getRequestCode(),davix_scope_http_request(),", ", &tmp_err); } } DavixError::propagateError(err, tmp_err); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, " <- Davix Vector operation"); return ret; } int http_extract_boundary_from_content_type(const std::string & buffer, std::string & boundary, DavixError** err){ dav_size_t pos_bound; static const std::string delimiter = "\";"; if( (pos_bound= buffer.find(ans_header_boundary_field)) != std::string::npos){ std::vector tokens = tokenSplit(buffer.substr(pos_bound + ans_header_boundary_field.size()), delimiter); if( tokens.size() >= 1 && tokens[0].size() > 0 && tokens[0].size() <= 70){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Multi part boundary: {}", boundary); std::swap(boundary,tokens[0]); return 0; } } HttpIoVecSetupErrorMultiPart(err); return -1; } int get_multi_part_info(const HttpRequest& req, std::string & boundary, DavixError** err){ std::string buffer; if( req.getAnswerHeader(ans_header_content_type, buffer) == true // has content type && http_extract_boundary_from_content_type(buffer, boundary, err) == 0){ return 0; } HttpIoVecSetupErrorMultiPartBoundary(buffer, err); return -1; } // analyze header and try to find size of the part // return 0 -> not a content length header, return -1 : not a header or error, return 1 : success int find_header_params(char* buffer, dav_size_t buffer_len, dav_size_t* part_size, dav_off_t* part_offset){ static const std::string delimiter(" bytes-/\t"); char * p = header_delimiter(buffer, buffer_len); if(p == NULL) return -1; std::string header_type(buffer, p - buffer); if( compare_ncase(ans_header_byte_range, 0, p - buffer, buffer) !=0) // check header type return 0; std::vector tokens = tokenSplit(std::string(p+1),delimiter); // parse header if(tokens.size() < 2) return -1; long chunk_size[2]; for(int i =0; i <2;++i){ chunk_size[i]= strtol(tokens[i].c_str(), &p, 10); if(chunk_size[i] == LONG_MAX || chunk_size[i] < 0 || *p != '\0'){ errno =0; return -1; } } if(chunk_size[1] < chunk_size[0]) return -1; *part_offset= chunk_size[0]; *part_size = chunk_size[1]-chunk_size[0]+1; return 1; } inline dav_ssize_t parse_multi_part_header_line(HttpRequest& req, char* buffer, DavixError** err){ dav_ssize_t ret =0; if( (ret = req.readLine(buffer, DAVIX_READ_BLOCK_SIZE, err)) <0 ){ return -1; } ret= trim_crlf(buffer, buffer + ret, ret); return ret; } int parse_multi_part_header(HttpRequest& req, const std::string & boundary, ChunkInfo & info, int & n_try, DavixError** err){ dav_ssize_t ret =0; char buffer[DAVIX_READ_BLOCK_SIZE+1] = {0}; if(n_try > 100){ HttpIoVecSetupErrorMultiPartTooLong(err); return -1; } if( (ret = parse_multi_part_header_line(req, buffer, err)) <0 ){ return -1; } if(!info.bounded){ if(ret == 0) // start with crlf return parse_multi_part_header(req, boundary, info, ++n_try, err); if( is_a_start_boundary_part(buffer, DAVIX_READ_BLOCK_SIZE, boundary, err) == false) return -1; info.bounded = true; return parse_multi_part_header(req, boundary, info, ++n_try, err); } if( info.offset == 0 && info.size == 0){ if( find_header_params(buffer, ret, &(info.size), &(info.offset)) < 0) return -1; return parse_multi_part_header(req, boundary, info, ++n_try, err); } if(ret == 0) // end crlf return 0; HttpIoVecSetupErrorMultiPart(err); return -1; } dav_ssize_t copyChunk(HttpRequest & req, const DavIOVecInput *i, DavIOVecOuput* o, DavixError** err){ DavixError* tmp_err=NULL; dav_ssize_t ret; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest::copyChunk copy {} bytes with offset {}", i->diov_size, i->diov_offset); // if size ==0, request set to 1 byte due to server behavior, read the stupid byte and skip if( i->diov_size ==0){ char trash[2]; if( (ret = req.readSegment(trash, 1, &tmp_err)) > 0){ o->diov_buffer = i->diov_buffer; o->diov_size = 0; ret = 0; } } else if( ( ret = req.readSegment((char*)i->diov_buffer, i->diov_size, &tmp_err)) >0){ o->diov_buffer = i->diov_buffer; o->diov_size = ret; } if(tmp_err){ DavixError::propagateError(err, tmp_err); }else{ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest::copyChunk {} bytes copied with success",ret); } return ret; } dav_ssize_t HttpIOVecOps::parseMultipartRequest(HttpRequest & _req, const DavIOVecInput *input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** err){ std::string boundary; dav_ssize_t ret = 0, tmp_ret =0; dav_size_t off=0; DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest multi part parsing"); if(get_multi_part_info(_req, boundary, err) != 0 ){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Invalid Header Content info for multi part request"); HttpIoVecSetupErrorMultiPart(err); return -1; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest multi-part boundary {}", boundary); while(off < count_vec){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest try to find chunk offset:{} size {}", input_vec[off].diov_offset, input_vec[off].diov_size); ChunkInfo infos; int n_try = 0; if( (tmp_ret = parse_multi_part_header(_req, boundary, infos, n_try, err)) < 0){ return -1; } if(infos.offset == 0 && infos.size == 0 && infos.bounded == true){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest multi-part : end of the request found {} chunks treated on {}", off, count_vec); return ret; } if( input_vec[off].diov_size !=0 && (infos.offset != input_vec[off].diov_offset || infos.size != input_vec[off].diov_size )){ HttpIoVecSetupErrorMultiPartSize(err, input_vec[off].diov_offset, input_vec[off].diov_size, infos.offset, infos.size); return -1; } if( (tmp_ret = copyChunk(_req, &input_vec[off], &output_vec[off], err)) <0 ) return -1; ret += tmp_ret; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest chunk parsed with success, next chunk.."); off++; } // finish with success, dump the remaining part of the query to end the request properly char buffer[255]; while( _req.readBlock(buffer, 255, NULL) > 0); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Davix::parseMultipartRequest end {} {}", off, count_vec); return ret; } bool is_a_start_boundary_part(char* buffer, dav_size_t s_buff, const std::string & boundary, DavixError** err){ if(s_buff > 3){ char * p = buffer; if( *p == '-' && *(p+1)== '-'){ if( strcmp(buffer+2, boundary.c_str()) ==0){ return true; } } } DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Invalid boundary delimitation"); HttpIoVecSetupErrorMultiPart(err); return false; } struct ElemChunk{ ElemChunk(const DavIOVecInput* in, DavIOVecOuput* ou) : _in(in), _ou(ou), _cursor((char*) in->diov_buffer){ _ou->diov_size=0; // reset elem read status _ou->diov_buffer = _in->diov_buffer; } const DavIOVecInput *_in; DavIOVecOuput * _ou; char *_cursor; }; typedef std::pair PairChunk; typedef std::multimap MapChunk; // order the chunk by offset static void fill_map_chunk(MapChunk & m, const DavIOVecInput *input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec){ for(dav_size_t s = 0; s < count_vec; s++){ m.insert(PairChunk(input_vec[s].diov_offset, ElemChunk(&input_vec[s], &output_vec[s]))); } } static void balance_iterator_windows(MapChunk & m, MapChunk::iterator & start, MapChunk::iterator & end, dav_ssize_t pos, dav_ssize_t read_size){ dav_ssize_t size_part; dav_off_t off_part; for(;start != m.end();){ // move the it to first concerned block size_part = (*start).second._in->diov_size; off_part = (*start).second._in->diov_offset; if(pos > ((dav_ssize_t)off_part) + size_part) start++; else break; } const dav_ssize_t end_chunk_pos = pos + read_size; for(;end != m.end();){ off_part = (*end).second._in->diov_offset; if(end_chunk_pos > (dav_ssize_t)off_part ) end++; else break; } } static void fill_concerned_chunk_buffer(MapChunk & m, MapChunk::iterator & start, MapChunk::iterator & end, char* buffer, dav_ssize_t read_size, dav_ssize_t pos){ (void) m; for(MapChunk::iterator it = start; it != end; it++){ const dav_ssize_t size_part = (*it).second._in->diov_size; const dav_off_t off_part = (*it).second._in->diov_offset; const dav_ssize_t cur_chunk_size = (*it).second._ou->diov_size; const char* p_buff = (char*) (*it).second._ou->diov_buffer; const dav_ssize_t current_chunk_offset = ((dav_ssize_t) off_part + cur_chunk_size); const dav_ssize_t read_offset = current_chunk_offset - pos; const dav_ssize_t s_needed = std::min(size_part - cur_chunk_size, read_size - read_offset); if(s_needed > 0){ memcpy((void*) (p_buff + cur_chunk_size), buffer+ read_offset, s_needed); (*it).second._ou->diov_size += s_needed; } } } static dav_ssize_t sum_all_chunk_size(const MapChunk & cmap){ dav_ssize_t res =0; for(MapChunk::const_iterator it = cmap.begin(); it != cmap.end(); ++it){ res += (*it).second._ou->diov_size; } return res; } dav_ssize_t HttpIOVecOps::simulateMultiPartRequest(HttpRequest & _req, const DavIOVecInput *input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** err){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, " -> Davix vec : 200 full file, simulate vec io"); MapChunk cmap; dav_ssize_t total_read_size=0, tmp_read_size; char buffer[DAVIX_READ_BLOCK_SIZE]; fill_map_chunk(cmap, input_vec, output_vec, count_vec); MapChunk::iterator it_start=cmap.begin(),it_end = cmap.begin(); while( (tmp_read_size = _req.readBlock(buffer, DAVIX_READ_BLOCK_SIZE, err)) >0){ balance_iterator_windows(cmap, it_start, it_end, total_read_size, tmp_read_size); // re-balance the interested windows fill_concerned_chunk_buffer(cmap, it_start, it_end, buffer, tmp_read_size, total_read_size); // fill the interested window total_read_size += tmp_read_size; } if(tmp_read_size < 0) return -1; DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, " <- Davix vec : 200 full file, simulate vec io"); return sum_all_chunk_size(cmap); } } // Davix davix-R_0_5_0/src/fileops/httpiovec.hpp000066400000000000000000000063431257152637300202410ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef HTTPIOVEC_HPP #define HTTPIOVEC_HPP #include #include #include namespace Davix{ // simple chunk info handler struct ChunkInfo { ChunkInfo() : offset(0), size(0), bounded(false){} dav_off_t offset; dav_size_t size; bool bounded; }; //// /// \brief The HttpIOVecOps class /// /// the HttpIOVecOps io vec chain element handle all operations relative to Vector requests class HttpIOVecOps : public HttpIOChain { public: HttpIOVecOps(){} virtual ~HttpIOVecOps(){} dav_ssize_t preadVec(IOChainContext & iocontext, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec); private: dav_ssize_t readPartialBufferVecRequest(HttpRequest & req, const DavIOVecInput * input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** err); dav_ssize_t parseMultipartRequest(HttpRequest & req, const DavIOVecInput *input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** tmp_err); dav_ssize_t simulateMultiPartRequest(HttpRequest & req, const DavIOVecInput *input_vec, DavIOVecOuput * output_vec, const dav_size_t count_vec, DavixError** tmp_err); }; bool is_a_start_boundary_part(char* buffer, dav_size_t s_buff, const std::string & boundary, DavixError** err); int find_header_params(char* buffer, dav_size_t buffer_len, dav_size_t* part_size, dav_off_t* part_offset); int http_extract_boundary_from_content_type(const std::string & buffer, std::string & boundary, DavixError** err); int parse_multi_part_header(HttpRequest& req, const std::string & boundary, ChunkInfo & info, int & n_try, DavixError** err); int davIOVecProvider(const DavIOVecInput *input_vec, dav_ssize_t & counter, dav_ssize_t number, dav_off_t & begin, dav_off_t & end); void HttpIoVecSetupErrorMultiPart(DavixError** err); } // Davix #endif // HTTPIOVEC_HPP davix-R_0_5_0/src/fileops/iobuffmap.cpp000066400000000000000000000374131257152637300202010ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "iobuffmap.hpp" #include #include #include #include #include #include #include #include #include #include #include #include namespace Davix { dav_ssize_t read_truncated_segment_request(HttpRequest* req, void* buffer, dav_size_t size_read, dav_off_t off_set, DavixError**err); dav_ssize_t read_segment_request(HttpRequest* req, void* buffer, dav_size_t size_read, DavixError**err){ DavixError* tmp_err=NULL; dav_ssize_t ret, tmp_ret; char* p_buff =(char*) buffer; dav_size_t s_read= size_read; ret = tmp_ret = 0; DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Davix::IOMap::readSegment: want to read {} bytes ", size_read); do{ tmp_ret= req->readBlock(p_buff, s_read, &tmp_err); if(tmp_ret > 0){ // tmp_ret bytes readed ret += tmp_ret; } if(ret > 0 && ret < (dav_ssize_t) size_read){ p_buff+= tmp_ret; s_read -= tmp_ret; } }while( tmp_ret > 0 && ret < (dav_ssize_t) size_read); if(tmp_err){ DavixError::propagateError(err, tmp_err); return -1; } DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Davix::IOMap::readSegment: got {} bytes ", ret); return ret; } dav_ssize_t read_truncated_segment_request(HttpRequest* req, void* buffer, dav_size_t size_read, dav_off_t off_set, DavixError**err){ DavixError* tmp_err=NULL; dav_ssize_t ret=0, tmp_ret=0; const dav_ssize_t begin_offset = (dav_ssize_t) off_set; const dav_ssize_t ssize_read = size_read; char * p_buffer = (char*) buffer; while(ret < begin_offset && !tmp_err){ if( (ret + ssize_read) < begin_offset) // use buffer like trash for useless content tmp_ret = req->readBlock(p_buffer, size_read, &tmp_err); else tmp_ret = req->readBlock(p_buffer, begin_offset - ret, &tmp_err); if(tmp_ret == 0) return 0; ret += tmp_ret; } if(!tmp_err){ ret = read_segment_request(req, p_buffer, size_read, &tmp_err); } if(tmp_err){ DavixError::propagateError(err, tmp_err); ret = -1; } return ret; } int get_valid_cache_file(FILE** stream, DavixError** err){ if(stream == NULL){ DavixError::setupError(err, davix_scope_io_buff(), StatusCode::InvalidFileHandle, "Invalid file stream"); return -1; } if( *stream == NULL){ if( ( *stream = tmpfile() ) == NULL){ std::ostringstream ss; ss << "Error while file-cache creation: " << strerror(errno) << std::endl; DavixError::setupError(err, davix_scope_io_buff(), StatusCode::SystemError, ss.str().c_str()); return -1; } } return 0; } /////////////////////// /////////////////////// /////////////////////// HttpIO::HttpIO() { } HttpIO::~HttpIO(){ } // read to dynamically allocated buffer dav_ssize_t HttpIO::readFull(IOChainContext & iocontext, std::vector & buffer){ DavixError * tmp_err=NULL; dav_ssize_t ret = -1, total=0; DAVIX_SCOPE_TRACE(DAVIX_LOG_CHAIN, fun_readFull); GetRequest req (iocontext._context, iocontext._uri, &tmp_err); if(!tmp_err){ RequestParams params(iocontext._reqparams); req.setParameters(params); ret = req.beginRequest(&tmp_err); if(!tmp_err){ const dav_size_t s_chunk = (req.getAnswerSize() > 0)?(req.getAnswerSize()):DAVIX_BLOCK_SIZE; buffer.reserve(buffer.size()+ s_chunk); while ( (ret= req.readBlock( buffer, s_chunk, &tmp_err)) > 0){ total += (dav_size_t) ret; } if(!tmp_err && httpcodeIsValid(req.getRequestCode()) == false){ httpcodeToDavixError(req.getRequestCode(),davix_scope_io_buff(),"read error: ", &tmp_err); ret = -1; } } } checkDavixError(&tmp_err); return (ret>0)?total:-1; } dav_ssize_t HttpIO::pread(IOChainContext & iocontext, void *buf, dav_size_t count, dav_off_t offset){ DavixError * tmp_err=NULL; dav_ssize_t ret = -1; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "pread operation for {} with size {} and offset {}", iocontext._uri, count, offset); if(count ==0) return 0; HttpRequest req(iocontext._context, iocontext._uri, &tmp_err); if(tmp_err == NULL){ RequestParams params(iocontext._reqparams); req.setParameters(params); setup_offset_request(&req, &offset, &count,1); if(req.beginRequest(&tmp_err) ==0){ if(req.getRequestCode() == 416 ){ // out of file, end of file ret = 0; // end of file }else{ if(req.getRequestCode() == 206 ){ // partial request supported, just read ! ret = read_segment_request(&req, buf, count, &tmp_err); // clean remaining content char buffer[255]; while( req.readBlock(buffer, 255, NULL) > 0); }else if( req.getRequestCode() == 200){ // full request content -> skip useless content ret = read_truncated_segment_request(&req, buf, count, offset, &tmp_err); }else{ httpcodeToDavixError(req.getRequestCode(), davix_scope_http_request(),", while readding", &tmp_err); } } } req.endRequest(NULL); } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "end pread operation for {} ",iocontext._uri); checkDavixError(&tmp_err); return ret; } dav_ssize_t HttpIO::readToFd(IOChainContext & iocontext, int fd, dav_size_t read_size){ DavixError * tmp_err=NULL; dav_ssize_t ret = -1; DAVIX_SCOPE_TRACE(DAVIX_LOG_CHAIN, fun_readToFd); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "request size {}", read_size); GetRequest req (iocontext._context, iocontext._uri, &tmp_err); if(!tmp_err){ RequestParams params(iocontext._reqparams); req.setParameters(iocontext._reqparams); ret = req.beginRequest(&tmp_err); if(!tmp_err){ if(httpcodeIsValid(req.getRequestCode()) == false){ httpcodeToDavixError(req.getRequestCode(),davix_scope_io_buff(),"read error: ", &tmp_err); ret = -1; }else{ ret= req.readToFd(fd, read_size, &tmp_err); } } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "read size {}", ret); checkDavixError(&tmp_err); return ret; } static dav_ssize_t body_provider_wrapper(void *userdata, char *buffer, dav_size_t buflen){ DataProviderFun* cb = (DataProviderFun*) userdata; return (*cb)(buffer, buflen); } dav_ssize_t HttpIO::writeFromCb(IOChainContext &iocontext, const DataProviderFun & func, dav_size_t size){ DavixError * tmp_err=NULL; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "write size {}", size); PutRequest req (iocontext._context,iocontext._uri, &tmp_err); if(!tmp_err){ RequestParams params(iocontext._reqparams); req.setParameters(params); req.setRequestBody(&body_provider_wrapper, size, (void*) &func); req.executeRequest(&tmp_err); if(!tmp_err && httpcodeIsValid(req.getRequestCode()) == false){ httpcodeToDavixError(req.getRequestCode(), davix_scope_io_buff(), "write error: ", &tmp_err); } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "write result size {}", size); checkDavixError(&tmp_err); return size; } // position independant write operation, // similar to pwrite do not need open() before dav_ssize_t HttpIO::writeFromFd(IOChainContext & iocontext, int fd, dav_size_t size){ DavixError * tmp_err=NULL; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "write size {}", size); PutRequest req (iocontext._context,iocontext._uri, &tmp_err); if(!tmp_err){ RequestParams params(iocontext._reqparams); req.setParameters(params); req.setRequestBody(fd, 0, size); req.executeRequest(&tmp_err); if(!tmp_err && httpcodeIsValid(req.getRequestCode()) == false){ httpcodeToDavixError(req.getRequestCode(), davix_scope_io_buff(), "write error: ", &tmp_err); } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CHAIN, "write result size {}", size); checkDavixError(&tmp_err); return size; } ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// /// struct IOBufferLocalFile{ IOBufferLocalFile(int fd, const std::string & filepath): _fd(fd), _filepath(filepath){} virtual ~IOBufferLocalFile(){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Delete tmp file {}", _filepath); unlink(_filepath.c_str()); } int _fd; std::string _filepath; }; HttpIOBuffer::HttpIOBuffer() : HttpIOChain(), _file_size(0), _file_exist(false), _pos(false), _opened(false), _last_advise(AdviseAuto), _rwlock(), _read_pos(0), _read_endfile(false), _read_req(NULL) { } HttpIOBuffer::~HttpIOBuffer(){ delete _read_req; } IOBufferLocalFile* createLocalBuffer(){ char buffer[1024]; strcpy(buffer, "/tmp/.davix_tmp_file_XXXXXXXXXXXXXXXXXXXXXXXX"); int fd; if( (fd = mkstemp(buffer)) < 0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Error during temporary file creation for HTTPIO {}: {}", buffer, strerror(errno)); return NULL; } return new IOBufferLocalFile(fd, buffer); } bool HttpIOBuffer::open(IOChainContext & iocontext, int flags){ bool res = false; if(_opened) return true; struct StatInfo infos; try{ _start->statInfo(iocontext, infos); if( (flags & O_EXCL) && ( flags & O_CREAT)){ throw DavixException(davix_scope_io_buff(), StatusCode::FileExist, "file exist and O_EXCL flag usedin open"); }else{ _file_size = infos.size; _file_exist = true; _opened = true; } }catch(DavixException & e){ if(e.code() == StatusCode::FileNotFound && (flags & O_CREAT) && ((flags & O_RDWR) || (flags & O_WRONLY))){ _file_size = 0; _file_exist = false; _opened = true; _local.reset(createLocalBuffer()); }else{ throw e; } } DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "File open {}, size: {}", iocontext._uri, _file_size); return res; } dav_ssize_t HttpIOBuffer::read(IOChainContext & iocontext, void *buf, dav_size_t count){ boost::recursive_mutex::scoped_lock l(_rwlock); DavixError* tmp_err = NULL; dav_ssize_t ret =-1; if(_pos ==0) // reset read ahead offset to default if try to read a full file resetIO(iocontext); if(_pos == _read_pos && isAdviseFullRead()){ // try read ahead strategie ret = readInternal(iocontext, buf, count); }else{ // fallback on partial read ret = _start->pread(iocontext, buf, count, _pos); } if(ret > 0) _pos += ret; checkDavixError(&tmp_err); return ret; } dav_ssize_t HttpIOBuffer::readInternal(IOChainContext & iocontext, void *buffer, dav_size_t size_read){ dav_ssize_t ret = -1; DavixError * tmp_err=NULL; if(_read_endfile) return 0; if( _read_req == NULL && (_read_req = new HttpRequest(iocontext._context, iocontext._uri, &tmp_err)) != NULL && tmp_err == NULL ){ RequestParams params(iocontext._reqparams); _read_req->setParameters(params); if(_read_req->beginRequest(&tmp_err) ==0 && (_read_req->getRequestCode() != 200)){ httpcodeToDavixError(_read_req->getRequestCode(),davix_scope_http_request(),", while readding", &tmp_err); delete _read_req; _read_req = NULL; } if(tmp_err){ delete _read_req; _read_req = NULL; ret = -1; } } if(_read_req != NULL){ // valid request -> proceed to read ret = read_segment_request(_read_req, buffer, size_read, &tmp_err); if(ret > 0){ _read_pos += ret; if(ret < (dav_ssize_t) size_read){ // end of file _read_endfile =true; _read_req->endRequest(NULL); } } } if((_read_endfile || ret < 0) && _read_req){ delete _read_req; _read_req = NULL; } checkDavixError(&tmp_err); return ret; } void HttpIOBuffer::prefetchInfo(IOChainContext & iocontext, off_t offset, dav_size_t size_read, advise_t adv){ (void) iocontext; (void) offset; (void) size_read; _last_advise = adv; } void HttpIOBuffer::resetIO(IOChainContext & iocontext){ boost::recursive_mutex::scoped_lock l(_rwlock); if(_read_req){ delete _read_req; _read_req = NULL; } _read_pos =0; commitLocal(iocontext); } void HttpIOBuffer::commitLocal(IOChainContext & iocontext){ boost::recursive_mutex::scoped_lock l(_rwlock); if(_local.get()){ struct stat st; memset(&st,0, sizeof(struct stat)); fstat(_local->_fd, &st); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CHAIN, "Commit local file modifications, {} bytes", st.st_size); _start->writeFromFd(iocontext, _local->_fd, st.st_size); _local.reset(); } } dav_off_t HttpIOBuffer::lseek(IOChainContext & iocontext, dav_off_t offset, int flags){ (void) iocontext; boost::recursive_mutex::scoped_lock l(_rwlock); switch(flags){ case SEEK_CUR: _pos += offset; break; case SEEK_END: _pos = ( _file_size += offset); break; case SEEK_SET: default: _pos = offset; break; } return _pos; } dav_ssize_t HttpIOBuffer::write(IOChainContext & iocontext, const void *buf, dav_size_t count){ (void) iocontext; boost::recursive_mutex::scoped_lock l(_rwlock); dav_ssize_t ret =-1; dav_size_t write_len = count; if(_local.get() == NULL || !_opened){ throw DavixException(davix_scope_io_buff(), StatusCode::SystemError, "Impossible to write, I/O Error"); } do{ ret = pwrite(_local->_fd, buf, static_cast(count), _pos); if (ret == -1 && errno == EINTR) { continue; } else if (ret < 0) { throw DavixException(davix_scope_io_buff(), StatusCode::SystemError, std::string("Impossible to write to fd").append(strerror(errno))); } else { _pos += ret; write_len -= ret; } }while(write_len >0); return (count - write_len); } } // namespace Davix davix-R_0_5_0/src/fileops/iobuffmap.hpp000066400000000000000000000077471257152637300202150ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #pragma once #ifndef DAVIX_IOBUFFMAP_HPP #define DAVIX_IOBUFFMAP_HPP #include #include #include namespace Davix { // // Internal POSIX like to HTTP RW operation mapper // provides facilities for caching // /// RW operation mapped to pure HTTP ops class HttpIO : public HttpIOChain{ public: HttpIO(); virtual ~HttpIO(); // read to dynamically allocated buffer virtual dav_ssize_t readFull(IOChainContext & iocontext, std::vector & buffer); // position independant read operation, // similar to pread except that does not need open() before virtual dav_ssize_t pread(IOChainContext & iocontext, void* buf, dav_size_t count, dav_off_t offset); // read to fd virtual dav_ssize_t readToFd(IOChainContext & iocontext, int fd, dav_size_t size); virtual dav_ssize_t writeFromCb(IOChainContext &iocontext, const DataProviderFun &func, dav_size_t size); // position independant write operation, // similar to pwrite do not need open() before virtual dav_ssize_t writeFromFd(IOChainContext & iocontext, int fd, dav_size_t size); private: HttpIO(const HttpIO & ); HttpIO & operator=(const HttpIO & ); }; struct IOBufferLocalFile; /// /// RW operation with buffering support and POSIX like interface class HttpIOBuffer : public HttpIOChain{ public: HttpIOBuffer(); virtual ~HttpIOBuffer(); // open the file associated with the davix IOBuffMap // do a simple check if the file exist and try to anticipate the next ops virtual bool open(IOChainContext & iocontext, int flags); // virtual dav_ssize_t read(IOChainContext & iocontext, void* buf, dav_size_t count); // give information on the future operation for prefecting virtual void prefetchInfo(IOChainContext & iocontext, off_t offset, dav_size_t size_read, advise_t adv); // virtual dav_ssize_t write(IOChainContext & iocontext, const void* buf, dav_size_t count); // virtual dav_off_t lseek(IOChainContext & iocontext, dav_off_t offset, int flags); // virtual void resetIO(IOChainContext & iocontext); void commitLocal(IOChainContext & iocontext); protected: dav_size_t _file_size; bool _file_exist; dav_off_t _pos; bool _opened; advise_t _last_advise; // locker boost::recursive_mutex _rwlock; // write cache Ptr::Scoped _local; dav_off_t _read_pos; //curent read file offset bool _read_endfile; HttpRequest * _read_req; private: inline bool isAdviseFullRead(){ return (_last_advise == AdviseAuto || _last_advise == AdviseSequential); } dav_ssize_t readInternal(IOChainContext & iocontext, void *buffer, dav_size_t size_read); HttpIOBuffer(const HttpIOBuffer & ); HttpIOBuffer & operator=(const HttpIOBuffer & ); }; // create a single-ton filestream for cache from int get_valid_cache_file(FILE** stream, DavixError** err); dav_ssize_t read_segment_request(HttpRequest* req, void* buffer, dav_size_t size_read, DavixError**err); } // namespace Davix #endif // DAVIX_IOBUFFMAP_HPP davix-R_0_5_0/src/hooks/000077500000000000000000000000001257152637300151775ustar00rootroot00000000000000davix-R_0_5_0/src/hooks/davix_hooks.cpp000066400000000000000000000020201257152637300202130ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include namespace Davix{ HookList::HookList() : _pre_run_req(), _pre_send_req(), _pre_rece_req() {} } davix-R_0_5_0/src/libs/000077500000000000000000000000001257152637300150055ustar00rootroot00000000000000davix-R_0_5_0/src/libs/CMakeLists.txt000066400000000000000000000004321257152637300175440ustar00rootroot00000000000000# libs CMakefile for third party deps add_definitions(-DA_LIB_NAMESPACE=Davix) add_subdirectory(alibxx) add_subdirectory(datetime) SET(src_vector_chunk ${src_vector_chunk} PARENT_SCOPE) SET(src_crypto ${src_crypto} PARENT_SCOPE) SET(src_datetime ${src_datetime} PARENT_SCOPE) davix-R_0_5_0/src/libs/alibxx/000077500000000000000000000000001257152637300162745ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/CMakeLists.txt000066400000000000000000000004451257152637300210370ustar00rootroot00000000000000# libs CMakefile for A_LIB_NAMESPACE SET(ALIBXX_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE STRING "ALIBXX src dir") FILE(GLOB src_alibxx "${CMAKE_CURRENT_SOURCE_DIR}/*/*.cpp") add_definitions( -fPIC) if(SHARED_LIBRARY) add_library(alibxx_core STATIC ${src_alibxx}) endif(SHARED_LIBRARY) davix-R_0_5_0/src/libs/alibxx/algorithm/000077500000000000000000000000001257152637300202625ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/algorithm/algorithm.hpp000066400000000000000000000010151257152637300227560ustar00rootroot00000000000000#ifndef ALGORITHM_HPP #define ALGORITHM_HPP namespace A_LIB_NAMESPACE{ template _Iterator2 match_array(_Iterator1 begin_match, _Iterator1 end_match, _Iterator2 begin_resu, _Iterator2 end_resu, _Tvalue val){ do{ if(*begin_match == val) return begin_resu; begin_match++; begin_resu++; }while( begin_match < end_match && begin_resu < end_resu); return end_resu; } } #endif // ALGORITHM_HPP davix-R_0_5_0/src/libs/alibxx/alibxx.hpp000066400000000000000000000013311257152637300202720ustar00rootroot00000000000000#pragma once /** Alibxx is a simple library for CXX conveniences functions This library is under public domain: feel free to reuse, include and change the license Author: Devresse Adrien */ // define A_LIB_NAMESPACE to empty if not define // trigger compilation error if not defined properly #ifndef A_LIB_NAMESPACE #error "A_LIB_NAMESPACE need to be defined" #endif // pointer helpers #include "ptr/unique.hpp" // algorithm helpers #include "algorithm/algorithm.hpp" // type conversion #include "typeconv/typeconv.hpp" // containers #include "containers/cache.hpp" // chrono #include "chrono/timepoint.hpp" // str #include "str/format.hpp" // crypto #include "crypto/base64.hpp" #include "crypto/hmacsha1.hpp" davix-R_0_5_0/src/libs/alibxx/base_types.hpp000066400000000000000000000005711257152637300211460ustar00rootroot00000000000000#pragma once #include "alibxx.hpp" #include namespace A_LIB_NAMESPACE{ namespace Type{ // signed type typedef int8_t Byte; typedef int16_t Int16; typedef int32_t Int32; typedef int64_t Int64; // unsigned bytes typedef u_int8_t UByte; typedef u_int16_t UInt16; typedef u_int32_t UInt32; typedef u_int64_t UInt64; } // Type } // Alibxx Namespace davix-R_0_5_0/src/libs/alibxx/chrono/000077500000000000000000000000001257152637300175645ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/chrono/chrono_exception.hpp000066400000000000000000000005401257152637300236420ustar00rootroot00000000000000#pragma once #include namespace A_LIB_NAMESPACE{ class ChronoException: public std::exception{ public: ChronoException(const std::string & str) : message(str){} virtual ~ChronoException() throw(){} virtual const char* what() const throw(){ return message.c_str(); } private: std::string message; }; } davix-R_0_5_0/src/libs/alibxx/chrono/timepoint.cpp000066400000000000000000000055021257152637300223020ustar00rootroot00000000000000#include #include "timepoint.hpp" namespace A_LIB_NAMESPACE{ namespace Chrono { TimePoint::TimePoint() : t() { t.tv_nsec =0; t.tv_sec =0; } TimePoint::~TimePoint(){ } bool TimePoint::operator ==(const TimePoint & other) const{ return ( (t.tv_nsec == other.t.tv_nsec) && (t.tv_sec == other.t.tv_sec)); } bool TimePoint::operator<(const TimePoint & other) const{ return ( (t.tv_sec < other.t.tv_sec) || (( t.tv_sec == other.t.tv_sec) && (t.tv_nsec < other.t.tv_nsec))); } TimePoint & TimePoint::operator+=(const Duration & duration){ t.tv_sec += duration.t.tv_sec; t.tv_nsec += duration.t.tv_nsec; return *this; } TimePoint & TimePoint::operator-=(const Duration & duration){ t.tv_sec -= duration.t.tv_sec; t.tv_nsec -= duration.t.tv_nsec; return *this; } Duration TimePoint::operator-(const TimePoint & timepoint) const{ Duration d; if(*this < timepoint){ throw ChronoException("Negative duration between two TimePoint"); } d.t.tv_sec = (t.tv_sec - timepoint.t.tv_sec); d.t.tv_nsec = (t.tv_nsec - timepoint.t.tv_nsec); return d; } Type::UInt64 TimePoint::toTimestamp() const{ return static_cast(t.tv_sec); } bool TimePoint::isValid(){ return (t.tv_sec != 0 && t.tv_nsec != 0); } //////////////////////////////// //////////////////////////////// Duration::Duration(){ t.tv_sec =0; t.tv_nsec =0; } Duration::Duration(Type::UInt64 seconds){ t.tv_nsec =0; t.tv_sec = seconds; } Duration::~Duration(){ } Type::UInt64 Duration::toTimeValue() const{ return t.tv_sec; } /////////////////////////////// ////////////////////////////// static void get_time(Clock::Type clock_type, struct timespec & time_value){ #ifdef HAVE_CLOCK_GETTIME clockid_t t; switch(clock_type){ case Clock::Monolitic: t = CLOCK_MONOTONIC; break; default: t = CLOCK_REALTIME; break; } clock_gettime(t, &time_value); #elif HAVE_GETTIMEOFDAY // TODO: gettimeofday is vulnerable to time jump // need an OSX specific implementation using Mach micro kernel API struct timeval now; (void) gettimeofday(&now, NULL); time_value.tv_sec = now.tv_sec; time_value.tv_nsec = now.tv_usec * 1000; #else #error "No gettimeofday nor clock_gettime: No time support" #endif } Clock::Clock(Type clock_type, Precision tick) : _type(clock_type), _precision(tick){ (void) _precision; } Clock::~Clock(){ } TimePoint Clock::now() const{ TimePoint res; get_time(_type, res.t); return res; } std::ostream& operator<<(std::ostream& os, const Duration & d){ os << d.t.tv_sec; return os; } std::ostream& operator<<(std::ostream& os, const TimePoint & t){ os << t.t.tv_sec; return os; } } // namespace Chrono } davix-R_0_5_0/src/libs/alibxx/chrono/timepoint.hpp000066400000000000000000000040761257152637300223140ustar00rootroot00000000000000#pragma once #include #include #include "../base_types.hpp" #include "../operator.hpp" #include "../alibxx.hpp" #include "chrono_exception.hpp" namespace A_LIB_NAMESPACE{ namespace Chrono { class Clock; class Duration; class TimePoint; /// @class TimePoint /// represent a time position class TimePoint : public Operator::Equality, public Operator::Compare, public Operator::Subtractable, public Operator::Addable { public: TimePoint(); ~TimePoint(); bool operator==(const TimePoint & other) const; bool operator<(const TimePoint & other) const; // add time duration TimePoint & operator+=(const Duration & duration); TimePoint & operator-=(const Duration & duration); // extract duration from TimePoint // if time1 - time2 with time1 < time2 => throw ChronoException Duration operator-(const TimePoint & other) const; Type::UInt64 toTimestamp() const; bool isValid(); private: struct timespec t; friend class Clock; friend class Duration; friend std::ostream& operator<<(std::ostream& os, const TimePoint & t); }; class Duration{ public: Duration(); Duration(Type::UInt64 seconds); ~Duration(); /// return duration value in seconds Type::UInt64 toTimeValue() const; private: struct timespec t; friend class Clock; friend class TimePoint; friend std::ostream& operator<<(std::ostream& os, const Duration & d); }; class Clock{ public: enum Type{ Monolitic, RealTime }; enum Precision{ Second, MilliSecond, MicroSecond, NanoSecond }; Clock(Type clock_type, Precision tick = Second); ~Clock(); TimePoint now() const; private: Type _type; Precision _precision; }; std::ostream& operator<<(std::ostream& os, const Duration & d); std::ostream& operator<<(std::ostream& os, const TimePoint & d); } // namespace Chrono } // A_LIB_NAMESPACE davix-R_0_5_0/src/libs/alibxx/containers/000077500000000000000000000000001257152637300204415ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/containers/cache.hpp000066400000000000000000000054301257152637300222170ustar00rootroot00000000000000#pragma once #include #include #include #include #include #ifndef NO_BOOST_INCLUDE #include #include #include namespace A_LIB_NAMESPACE{ /// /// Thread Safe Cache container /// template > class Cache { typedef std::map > Map; typedef boost::shared_ptr shrPtr_type; public: Cache(size_t max_size = std::numeric_limits::max()) : cmp(CompareT()), map(cmp), _max_size(max_size), _m(){} ~Cache(){} shrPtr_type insert(const Key & key, Value* value){ return insert(key, shrPtr_type(value)); } /// /// \brief insert a new value into the cache, if an already existing one is mapped to this case, the old value is replaced /// \param key /// \param value /// \return /// shrPtr_type insert(const Key & key, const shrPtr_type & value){ boost::lock_guard l(_m); auto_clean(); std::pair< typename Map::iterator, bool > stored = map.insert(std::pair (key, value) ); if(stored.second) return (*stored.first).second; (*stored.first).second = value; return value; } /// /// \brief find a cached value, returned a NULL shared_pointer if not found /// \param key /// \return /// shrPtr_type find(const Key & key){ boost::lock_guard l(_m); typename Map::iterator it = map.find( key); if(it == map.end()) return shrPtr_type(); return it->second; } /// /// \brief getSize return the number of object sotred in the cache /// \return /// size_t getSize() const{ boost::lock_guard l(_m); return map.size(); } /// /// \brief remove an object from this cache and return its reference /// \param key /// \return /// shrPtr_type take( const Key & key){ boost::lock_guard l(_m); typename Map::iterator it = map.find( key); if(it == map.end()) return shrPtr_type(); map.erase(key); return it->second; } /// /// \brief erase an object from the cache /// \param key /// \return /// bool erase( const Key & key){ boost::lock_guard l(_m); return ( map.erase(key) != 0); } void clear(){ boost::lock_guard l(_m); map.clear(); } protected: CompareT cmp; Map map; size_t _max_size; mutable boost::mutex _m; void auto_clean(){ if(map.size() == _max_size){ map.clear(); } } }; } #endif davix-R_0_5_0/src/libs/alibxx/crypto/000077500000000000000000000000001257152637300176145ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/crypto/base64.cpp000066400000000000000000000071051257152637300214070ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "base64.hpp" #include namespace Base64{ static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; } std::string base64_decode(std::string const& encoded_string) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } } if (i) { for (j = i; j <4; j++) char_array_4[j] = 0; for (j = 0; j <4; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; } return ret; } } davix-R_0_5_0/src/libs/alibxx/crypto/base64.hpp000066400000000000000000000023111257152637300214060ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef BASE64_HPP #define BASE64_HPP /* base64.cpp and base64.hpp Modified version from René Nyffenegger version Public Domain */ #include namespace Base64{ std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); } #endif // BASE64_HPP davix-R_0_5_0/src/libs/alibxx/crypto/hmacsha1.cpp000066400000000000000000000030721257152637300220070ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hmacsha1.hpp" #ifdef HAVE_OPENSSL #include #include static std::string hmac_sha1_openssl(const std::string & key, const std::string & data){ unsigned char buffer_res[41]; unsigned int buffer_len= 40; HMAC(EVP_sha1(), (const unsigned char*)key.c_str(), key.size(), (const unsigned char*) data.c_str(), data.size(), buffer_res, &buffer_len); return std::string((char*) buffer_res, buffer_len); } #endif std::string hmac_sha1(const std::string & key, const std::string & data){ #ifdef HAVE_OPENSSL return hmac_sha1_openssl(key, data); #else #error "No support for hmac calculation" #endif } davix-R_0_5_0/src/libs/alibxx/crypto/hmacsha1.hpp000066400000000000000000000020671257152637300220170ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef HMACSHA1_HPP #define HMACSHA1_HPP #include #include std::string hmac_sha1(const std::string & key, const std::string & data); #endif // HMACSHA1_HPP davix-R_0_5_0/src/libs/alibxx/operator.hpp000066400000000000000000000016551257152637300206470ustar00rootroot00000000000000#pragma once #include "alibxx.hpp" namespace A_LIB_NAMESPACE{ namespace Operator { // need operator == template class Equality{ public: friend bool operator!=(const T& x, const O& y) { return !static_cast(x == y); } }; // need operator == and < template class Compare{ public: friend bool operator>(const T& x, const O& y) { return y < x; } friend bool operator<=(const T& x, const O& y) { return !static_cast(y < x); } friend bool operator>=(const T& x, const O& y) { return !static_cast(x < y); } }; // need operator += template class Addable{ public: friend T operator+(const T& x, const O& y) { T res(x); res+= y; return res; } }; template class Subtractable{ public: friend T operator-(const T& x, const O& y) { T res(x); res-= y; return res; } }; } } // A_LIB_NAMESPACE davix-R_0_5_0/src/libs/alibxx/ptr/000077500000000000000000000000001257152637300171015ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/ptr/unique.hpp000066400000000000000000000017001257152637300211160ustar00rootroot00000000000000#ifndef PTR_UNIQUE_HPP #define PTR_UNIQUE_HPP #include #include "../alibxx.hpp" namespace A_LIB_NAMESPACE{ namespace Ptr{ template class Scoped{ public: typedef T element_type; explicit Scoped(): _ptr(NULL){} explicit Scoped(T* p) : _ptr(p){} ~Scoped(){ delete _ptr;} inline T* release(){ T* r= _ptr; _ptr = NULL; return r; } inline void reset(T* p = NULL){ Scoped tmp(p); swap(tmp); } T& operator*(){ return *_ptr; } T* operator->(){ return _ptr; } bool operator==(const Scoped & other){ return (_ptr == other._ptr); } inline T* get(){ return _ptr; } inline void swap(Scoped & other){ std::swap(other._ptr, _ptr); } private: T* _ptr; Scoped(const Scoped & other); Scoped & operator=(const Scoped & other); }; } } #endif // UNIQUE_HPP davix-R_0_5_0/src/libs/alibxx/str/000077500000000000000000000000001257152637300171045ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/str/format.cpp000066400000000000000000001017051257152637300211040ustar00rootroot00000000000000/* Formatting library for C++ Copyright (c) 2012 - 2014, Victor Zverovich 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ // Disable useless MSVC warnings. #undef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #undef _SCL_SECURE_NO_WARNINGS #define _SCL_SECURE_NO_WARNINGS #include "format.hpp" #include #include #include #include #include #include namespace A_LIB_NAMESPACE { #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # ifdef __MINGW32__ # include # endif # include # undef ERROR #endif using fmt::LongLong; using fmt::ULongLong; using fmt::internal::Arg; // Check if exceptions are disabled. #if __GNUC__ && !__EXCEPTIONS # define FMT_EXCEPTIONS 0 #endif #if _MSC_VER && !_HAS_EXCEPTIONS # define FMT_EXCEPTIONS 0 #endif #ifndef FMT_EXCEPTIONS # define FMT_EXCEPTIONS 1 #endif #if FMT_EXCEPTIONS # define FMT_TRY try # define FMT_CATCH(x) catch (x) #else # define FMT_TRY if (true) # define FMT_CATCH(x) if (false) #endif #ifndef FMT_THROW # if FMT_EXCEPTIONS # define FMT_THROW(x) throw x # else # define FMT_THROW(x) assert(false) # endif #endif #if _MSC_VER # pragma warning(push) # pragma warning(disable: 4127) // conditional expression is constant #endif namespace { #ifndef _MSC_VER # define FMT_SNPRINTF snprintf #else // _MSC_VER inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) { va_list args; va_start(args, format); int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); va_end(args); return result; } # define FMT_SNPRINTF fmt_snprintf #endif // _MSC_VER // Checks if a value fits in int - used to avoid warnings about comparing // signed and unsigned integers. template struct IntChecker { template static bool fits_in_int(T value) { unsigned max = INT_MAX; return value <= max; } }; template <> struct IntChecker { template static bool fits_in_int(T value) { return value >= INT_MIN && value <= INT_MAX; } }; const char RESET_COLOR[] = "\x1b[0m"; typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef); // Portable thread-safe version of strerror. // Sets buffer to point to a string describing the error code. // This can be either a pointer to a string stored in buffer, // or a pointer to some static immutable string. // Returns one of the following values: // 0 - success // ERANGE - buffer is not large enough to store the error message // other - failure // Buffer should be at least of size 1. int safe_strerror( int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) { assert(buffer != 0 && buffer_size != 0); int result = 0; #if (defined _GNU_SOURCE) && (defined __USE_GNU) char *message = strerror_r(error_code, buffer, buffer_size); // If the buffer is full then the message is probably truncated. if (message == buffer && strlen(buffer) == buffer_size - 1) result = ERANGE; buffer = message; #elif (defined __MINGW32__) errno = 0; (void)buffer_size; buffer = strerror(error_code); result = errno; #elif (defined _WIN32) result = strerror_s(buffer, buffer_size, error_code); // If the buffer is full then the message is probably truncated. if (result == 0 && std::strlen(buffer) == buffer_size - 1) result = ERANGE; #else result = strerror_r(error_code, buffer, buffer_size); if (result == -1) result = errno; // glibc versions before 2.13 return result in errno. #endif return result; } void format_error_code(fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { // Report error code making sure that the output fits into // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential // bad_alloc. out.clear(); static const char SEP[] = ": "; static const char ERROR[] = "error "; fmt::internal::IntTraits::MainType ec_value = error_code; // Subtract 2 to account for terminating null characters in SEP and ERROR. std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR) + fmt::internal::count_digits(ec_value) - 2; if (message.size() <= fmt::internal::INLINE_BUFFER_SIZE - error_code_size) out << message << SEP; out << ERROR << error_code; assert(out.size() <= fmt::internal::INLINE_BUFFER_SIZE); } void report_error(FormatFunc func, int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { fmt::MemoryWriter full_message; func(full_message, error_code, message); // Use Writer::data instead of Writer::c_str to avoid potential memory // allocation. std::fwrite(full_message.data(), full_message.size(), 1, stderr); std::fputc('\n', stderr); } // IsZeroInt::visit(arg) returns true iff arg is a zero integer. class IsZeroInt : public fmt::internal::ArgVisitor { public: template bool visit_any_int(T value) { return value == 0; } }; // Parses an unsigned integer advancing s to the end of the parsed input. // This function assumes that the first character of s is a digit. template int parse_nonnegative_int(const Char *&s) { assert('0' <= *s && *s <= '9'); unsigned value = 0; do { unsigned new_value = value * 10 + (*s++ - '0'); // Check if value wrapped around. if (new_value < value) { value = UINT_MAX; break; } value = new_value; } while ('0' <= *s && *s <= '9'); if (value > INT_MAX) FMT_THROW(fmt::FormatError("number is too big")); return value; } inline void require_numeric_argument(const Arg &arg, char spec) { if (arg.type > Arg::LAST_NUMERIC_TYPE) { std::string message = fmt::format("format specifier '{}' requires numeric argument", spec); FMT_THROW(fmt::FormatError(message)); } } template void check_sign(const Char *&s, const Arg &arg) { char sign = static_cast(*s); require_numeric_argument(arg, sign); if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { FMT_THROW(fmt::FormatError(fmt::format( "format specifier '{}' requires signed argument", sign))); } ++s; } // Checks if an argument is a valid printf width specifier and sets // left alignment if it is negative. class WidthHandler : public fmt::internal::ArgVisitor { private: fmt::FormatSpec &spec_; public: explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {} unsigned visit_unhandled_arg() { FMT_THROW(fmt::FormatError("width is not integer")); return 0; } template unsigned visit_any_int(T value) { typedef typename fmt::internal::IntTraits::MainType UnsignedType; UnsignedType width = value; if (fmt::internal::is_negative(value)) { spec_.align_ = fmt::ALIGN_LEFT; width = 0 - width; } if (width > INT_MAX) FMT_THROW(fmt::FormatError("number is too big")); return static_cast(width); } }; class PrecisionHandler : public fmt::internal::ArgVisitor { public: unsigned visit_unhandled_arg() { FMT_THROW(fmt::FormatError("precision is not integer")); return 0; } template int visit_any_int(T value) { if (!IntChecker::is_signed>::fits_in_int(value)) FMT_THROW(fmt::FormatError("number is too big")); return static_cast(value); } }; // Converts an integer argument to an integral type T for printf. template class ArgConverter : public fmt::internal::ArgVisitor, void> { private: fmt::internal::Arg &arg_; wchar_t type_; public: ArgConverter(fmt::internal::Arg &arg, wchar_t type) : arg_(arg), type_(type) {} template void visit_any_int(U value) { bool is_signed = type_ == 'd' || type_ == 'i'; using fmt::internal::Arg; if (sizeof(T) <= sizeof(int)) { // Extra casts are used to silence warnings. if (is_signed) { arg_.type = Arg::INT; arg_.int_value = static_cast(static_cast(value)); } else { arg_.type = Arg::UINT; arg_.uint_value = static_cast( static_cast::Type>(value)); } } else { if (is_signed) { arg_.type = Arg::LONG_LONG; arg_.long_long_value = static_cast::Type>(value); } else { arg_.type = Arg::ULONG_LONG; arg_.ulong_long_value = static_cast::Type>(value); } } } }; // Converts an integer argument to char for printf. class CharConverter : public fmt::internal::ArgVisitor { private: fmt::internal::Arg &arg_; public: explicit CharConverter(fmt::internal::Arg &arg) : arg_(arg) {} template void visit_any_int(T value) { arg_.type = Arg::CHAR; arg_.int_value = static_cast(value); } }; // This function template is used to prevent compile errors when handling // incompatible string arguments, e.g. handling a wide string in a narrow // string formatter. template Arg::StringValue ignore_incompatible_str(Arg::StringValue); template <> inline Arg::StringValue ignore_incompatible_str( Arg::StringValue) { return Arg::StringValue(); } template <> inline Arg::StringValue ignore_incompatible_str( Arg::StringValue s) { return s; } } // namespace void fmt::SystemError::init( int error_code, StringRef format_str, ArgList args) { error_code_ = error_code; MemoryWriter w; internal::format_system_error(w, error_code, format(format_str, args)); std::runtime_error &base = *this; base = std::runtime_error(w.str()); } template int fmt::internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, T value) { if (width == 0) { return precision < 0 ? FMT_SNPRINTF(buffer, size, format, value) : FMT_SNPRINTF(buffer, size, format, precision, value); } return precision < 0 ? FMT_SNPRINTF(buffer, size, format, width, value) : FMT_SNPRINTF(buffer, size, format, width, precision, value); } template int fmt::internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, T value) { if (width == 0) { return precision < 0 ? swprintf(buffer, size, format, value) : swprintf(buffer, size, format, precision, value); } return precision < 0 ? swprintf(buffer, size, format, width, value) : swprintf(buffer, size, format, width, precision, value); } const char fmt::internal::DIGITS[] = "0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" "6061626364656667686970717273747576777879" "8081828384858687888990919293949596979899"; #define FMT_POWERS_OF_10(factor) \ factor * 10, \ factor * 100, \ factor * 1000, \ factor * 10000, \ factor * 100000, \ factor * 1000000, \ factor * 10000000, \ factor * 100000000, \ factor * 1000000000 const uint32_t fmt::internal::POWERS_OF_10_32[] = {0, FMT_POWERS_OF_10(1)}; const uint64_t fmt::internal::POWERS_OF_10_64[] = { 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(ULongLong(1000000000)), // Multiply several constants instead of using a single long long constant // to avoid warnings about C++98 not supporting long long. ULongLong(1000000000) * ULongLong(1000000000) * 10 }; void fmt::internal::report_unknown_type(char code, const char *type) { if (std::isprint(static_cast(code))) { FMT_THROW(fmt::FormatError( fmt::format("unknown format code '{}' for {}", code, type))); } FMT_THROW(fmt::FormatError( fmt::format("unknown format code '\\x{:02x}' for {}", static_cast(code), type))); } #ifdef _WIN32 fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { int length = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, 0, 0); static const char ERROR[] = "cannot convert string from UTF-8 to UTF-16"; if (length == 0) FMT_THROW(WindowsError(GetLastError(), ERROR)); buffer_.resize(length); length = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, &buffer_[0], length); if (length == 0) FMT_THROW(WindowsError(GetLastError(), ERROR)); } fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) { if (int error_code = convert(s)) { FMT_THROW(WindowsError(error_code, "cannot convert string from UTF-16 to UTF-8")); } } int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) { int length = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, 0, 0, 0, 0); if (length == 0) return GetLastError(); buffer_.resize(length); length = WideCharToMultiByte( CP_UTF8, 0, s.c_str(), -1, &buffer_[0], length, 0, 0); if (length == 0) return GetLastError(); return 0; } void fmt::WindowsError::init( int error_code, StringRef format_str, ArgList args) { error_code_ = error_code; MemoryWriter w; internal::format_windows_error(w, error_code, format(format_str, args)); std::runtime_error &base = *this; base = std::runtime_error(w.str()); } #endif void fmt::internal::format_system_error( fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { FMT_TRY { MemoryBuffer buffer; buffer.resize(INLINE_BUFFER_SIZE); for (;;) { char *system_message = &buffer[0]; int result = safe_strerror(error_code, system_message, buffer.size()); if (result == 0) { out << message << ": " << system_message; return; } if (result != ERANGE) break; // Can't get error message, report error code instead. buffer.resize(buffer.size() * 2); } } FMT_CATCH(...) {} format_error_code(out, error_code, message); } #ifdef _WIN32 void fmt::internal::format_windows_error( fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { class String { private: LPWSTR str_; public: String() : str_() {} ~String() { LocalFree(str_); } LPWSTR *ptr() { return &str_; } LPCWSTR c_str() const { return str_; } }; FMT_TRY { String system_message; if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(system_message.ptr()), 0, 0)) { UTF16ToUTF8 utf8_message; if (utf8_message.convert(system_message.c_str()) == ERROR_SUCCESS) { out << message << ": " << utf8_message; return; } } } FMT_CATCH(...) {} format_error_code(out, error_code, message); } #endif // An argument formatter. template class fmt::internal::ArgFormatter : public fmt::internal::ArgVisitor, void> { private: fmt::BasicFormatter &formatter_; fmt::BasicWriter &writer_; fmt::FormatSpec &spec_; const Char *format_; public: ArgFormatter( fmt::BasicFormatter &f,fmt::FormatSpec &s, const Char *fmt) : formatter_(f), writer_(f.writer()), spec_(s), format_(fmt) {} template void visit_any_int(T value) { writer_.write_int(value, spec_); } template void visit_any_double(T value) { writer_.write_double(value, spec_); } void visit_char(int value) { if (spec_.type_ && spec_.type_ != 'c') { spec_.flags_ |= CHAR_FLAG; writer_.write_int(value, spec_); return; } if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) FMT_THROW(FormatError("invalid format specifier for char")); typedef typename fmt::BasicWriter::CharPtr CharPtr; CharPtr out = CharPtr(); if (spec_.width_ > 1) { Char fill = static_cast(spec_.fill()); out = writer_.grow_buffer(spec_.width_); if (spec_.align_ == fmt::ALIGN_RIGHT) { std::fill_n(out, spec_.width_ - 1, fill); out += spec_.width_ - 1; } else if (spec_.align_ == fmt::ALIGN_CENTER) { out = writer_.fill_padding(out, spec_.width_, 1, fill); } else { std::fill_n(out + 1, spec_.width_ - 1, fill); } } else { out = writer_.grow_buffer(1); } *out = static_cast(value); } void visit_string(Arg::StringValue value) { writer_.write_str(value, spec_); } void visit_wstring(Arg::StringValue value) { writer_.write_str(ignore_incompatible_str(value), spec_); } void visit_pointer(const void *value) { if (spec_.type_ && spec_.type_ != 'p') fmt::internal::report_unknown_type(spec_.type_, "pointer"); spec_.flags_ = fmt::HASH_FLAG; spec_.type_ = 'x'; writer_.write_int(reinterpret_cast(value), spec_); } void visit_custom(Arg::CustomValue c) { c.format(&formatter_, c.value, &format_); } }; template template void fmt::BasicWriter::write_str( const Arg::StringValue &str, const FormatSpec &spec) { // Check if StrChar is convertible to Char. internal::CharTraits::convert(StrChar()); if (spec.type_ && spec.type_ != 's') internal::report_unknown_type(spec.type_, "string"); const StrChar *s = str.value; std::size_t size = str.size; if (size == 0) { if (!s) FMT_THROW(FormatError("string pointer is null")); if (*s) size = std::char_traits::length(s); } write_str(s, size, spec); } template inline Arg fmt::BasicFormatter::parse_arg_index(const Char *&s) { const char *error = 0; Arg arg = *s < '0' || *s > '9' ? next_arg(error) : get_arg(parse_nonnegative_int(s), error); if (error) { FMT_THROW(FormatError( *s != '}' && *s != ':' ? "invalid format string" : error)); } return arg; } Arg fmt::internal::FormatterBase::do_get_arg( unsigned arg_index, const char *&error) { Arg arg = args_[arg_index]; if (arg.type == Arg::NONE) error = "argument index out of range"; return arg; } inline Arg fmt::internal::FormatterBase::next_arg(const char *&error) { if (next_arg_index_ >= 0) return do_get_arg(next_arg_index_++, error); error = "cannot switch from manual to automatic argument indexing"; return Arg(); } inline Arg fmt::internal::FormatterBase::get_arg( unsigned arg_index, const char *&error) { if (next_arg_index_ <= 0) { next_arg_index_ = -1; return do_get_arg(arg_index, error); } error = "cannot switch from automatic to manual argument indexing"; return Arg(); } template void fmt::internal::PrintfFormatter::parse_flags( FormatSpec &spec, const Char *&s) { for (;;) { switch (*s++) { case '-': spec.align_ = ALIGN_LEFT; break; case '+': spec.flags_ |= SIGN_FLAG | PLUS_FLAG; break; case '0': spec.fill_ = '0'; break; case ' ': spec.flags_ |= SIGN_FLAG; break; case '#': spec.flags_ |= HASH_FLAG; break; default: --s; return; } } } template Arg fmt::internal::PrintfFormatter::get_arg( const Char *s, unsigned arg_index) { const char *error = 0; Arg arg = arg_index == UINT_MAX ? next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); if (error) FMT_THROW(FormatError(!*s ? "invalid format string" : error)); return arg; } template unsigned fmt::internal::PrintfFormatter::parse_header( const Char *&s, FormatSpec &spec) { unsigned arg_index = UINT_MAX; Char c = *s; if (c >= '0' && c <= '9') { // Parse an argument index (if followed by '$') or a width possibly // preceded with '0' flag(s). unsigned value = parse_nonnegative_int(s); if (*s == '$') { // value is an argument index ++s; arg_index = value; } else { if (c == '0') spec.fill_ = '0'; if (value != 0) { // Nonzero value means that we parsed width and don't need to // parse it or flags again, so return now. spec.width_ = value; return arg_index; } } } parse_flags(spec, s); // Parse width. if (*s >= '0' && *s <= '9') { spec.width_ = parse_nonnegative_int(s); } else if (*s == '*') { ++s; spec.width_ = WidthHandler(spec).visit(get_arg(s)); } return arg_index; } template void fmt::internal::PrintfFormatter::format( BasicWriter &writer, BasicStringRef format, const ArgList &args) { const Char *start = format.c_str(); set_args(args); const Char *s = start; while (*s) { Char c = *s++; if (c != '%') continue; if (*s == c) { write(writer, start, s); start = ++s; continue; } write(writer, start, s - 1); FormatSpec spec; spec.align_ = ALIGN_RIGHT; // Parse argument index, flags and width. unsigned arg_index = parse_header(s, spec); // Parse precision. if (*s == '.') { ++s; if ('0' <= *s && *s <= '9') { spec.precision_ = parse_nonnegative_int(s); } else if (*s == '*') { ++s; spec.precision_ = PrecisionHandler().visit(get_arg(s)); } } Arg arg = get_arg(s, arg_index); if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) spec.flags_ &= ~HASH_FLAG; if (spec.fill_ == '0') { if (arg.type <= Arg::LAST_NUMERIC_TYPE) spec.align_ = ALIGN_NUMERIC; else spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. } // Parse length and convert the argument to the required type. switch (*s++) { case 'h': if (*s == 'h') ArgConverter(arg, *++s).visit(arg); else ArgConverter(arg, *s).visit(arg); break; case 'l': if (*s == 'l') ArgConverter(arg, *++s).visit(arg); else ArgConverter(arg, *s).visit(arg); break; case 'j': ArgConverter(arg, *s).visit(arg); break; case 'z': ArgConverter(arg, *s).visit(arg); break; case 't': ArgConverter(arg, *s).visit(arg); break; case 'L': // printf produces garbage when 'L' is omitted for long double, no // need to do the same. break; default: --s; ArgConverter(arg, *s).visit(arg); } // Parse type. if (!*s) FMT_THROW(FormatError("invalid format string")); spec.type_ = static_cast(*s++); if (arg.type <= Arg::LAST_INTEGER_TYPE) { // Normalize type. switch (spec.type_) { case 'i': case 'u': spec.type_ = 'd'; break; case 'c': // TODO: handle wchar_t CharConverter(arg).visit(arg); break; } } start = s; // Format argument. switch (arg.type) { case Arg::INT: writer.write_int(arg.int_value, spec); break; case Arg::UINT: writer.write_int(arg.uint_value, spec); break; case Arg::LONG_LONG: writer.write_int(arg.long_long_value, spec); break; case Arg::ULONG_LONG: writer.write_int(arg.ulong_long_value, spec); break; case Arg::CHAR: { if (spec.type_ && spec.type_ != 'c') writer.write_int(arg.int_value, spec); typedef typename BasicWriter::CharPtr CharPtr; CharPtr out = CharPtr(); if (spec.width_ > 1) { Char fill = ' '; out = writer.grow_buffer(spec.width_); if (spec.align_ != ALIGN_LEFT) { std::fill_n(out, spec.width_ - 1, fill); out += spec.width_ - 1; } else { std::fill_n(out + 1, spec.width_ - 1, fill); } } else { out = writer.grow_buffer(1); } *out = static_cast(arg.int_value); break; } case Arg::DOUBLE: writer.write_double(arg.double_value, spec); break; case Arg::LONG_DOUBLE: writer.write_double(arg.long_double_value, spec); break; case Arg::CSTRING: arg.string.size = 0; writer.write_str(arg.string, spec); break; case Arg::STRING: writer.write_str(arg.string, spec); break; case Arg::WSTRING: writer.write_str(ignore_incompatible_str(arg.wstring), spec); break; case Arg::POINTER: if (spec.type_ && spec.type_ != 'p') internal::report_unknown_type(spec.type_, "pointer"); spec.flags_= HASH_FLAG; spec.type_ = 'x'; writer.write_int(reinterpret_cast(arg.pointer), spec); break; case Arg::CUSTOM: { if (spec.type_) internal::report_unknown_type(spec.type_, "object"); const void *s = "s"; arg.custom.format(&writer, arg.custom.value, &s); break; } default: assert(false); break; } } write(writer, start, s); } template const Char *fmt::BasicFormatter::format( const Char *&format_str, const Arg &arg) { const Char *s = format_str; FormatSpec spec; if (*s == ':') { if (arg.type == Arg::CUSTOM) { arg.custom.format(this, arg.custom.value, &s); return s; } ++s; // Parse fill and alignment. if (Char c = *s) { const Char *p = s + 1; spec.align_ = ALIGN_DEFAULT; do { switch (*p) { case '<': spec.align_ = ALIGN_LEFT; break; case '>': spec.align_ = ALIGN_RIGHT; break; case '=': spec.align_ = ALIGN_NUMERIC; break; case '^': spec.align_ = ALIGN_CENTER; break; } if (spec.align_ != ALIGN_DEFAULT) { if (p != s) { if (c == '}') break; if (c == '{') FMT_THROW(FormatError("invalid fill character '{'")); s += 2; spec.fill_ = c; } else ++s; if (spec.align_ == ALIGN_NUMERIC) require_numeric_argument(arg, '='); break; } } while (--p >= s); } // Parse sign. switch (*s) { case '+': check_sign(s, arg); spec.flags_ |= SIGN_FLAG | PLUS_FLAG; break; case '-': check_sign(s, arg); spec.flags_ |= MINUS_FLAG; break; case ' ': check_sign(s, arg); spec.flags_ |= SIGN_FLAG; break; } if (*s == '#') { require_numeric_argument(arg, '#'); spec.flags_ |= HASH_FLAG; ++s; } // Parse width and zero flag. if ('0' <= *s && *s <= '9') { if (*s == '0') { require_numeric_argument(arg, '0'); spec.align_ = ALIGN_NUMERIC; spec.fill_ = '0'; } // Zero may be parsed again as a part of the width, but it is simpler // and more efficient than checking if the next char is a digit. spec.width_ = parse_nonnegative_int(s); } // Parse precision. if (*s == '.') { ++s; spec.precision_ = 0; if ('0' <= *s && *s <= '9') { spec.precision_ = parse_nonnegative_int(s); } else if (*s == '{') { ++s; const Arg &precision_arg = parse_arg_index(s); if (*s++ != '}') FMT_THROW(FormatError("invalid format string")); ULongLong value = 0; switch (precision_arg.type) { case Arg::INT: if (precision_arg.int_value < 0) FMT_THROW(FormatError("negative precision")); value = precision_arg.int_value; break; case Arg::UINT: value = precision_arg.uint_value; break; case Arg::LONG_LONG: if (precision_arg.long_long_value < 0) FMT_THROW(FormatError("negative precision")); value = precision_arg.long_long_value; break; case Arg::ULONG_LONG: value = precision_arg.ulong_long_value; break; default: FMT_THROW(FormatError("precision is not integer")); } if (value > INT_MAX) FMT_THROW(FormatError("number is too big")); spec.precision_ = static_cast(value); } else { FMT_THROW(FormatError("missing precision specifier")); } if (arg.type != Arg::DOUBLE && arg.type != Arg::LONG_DOUBLE) { FMT_THROW(FormatError( "precision specifier requires floating-point argument")); } } // Parse type. if (*s != '}' && *s) spec.type_ = static_cast(*s++); } if (*s++ != '}') FMT_THROW(FormatError("missing '}' in format string")); start_ = s; // Format argument. internal::ArgFormatter(*this, spec, s - 1).visit(arg); return s; } template void fmt::BasicFormatter::format( BasicStringRef format_str, const ArgList &args) { const Char *s = start_ = format_str.c_str(); set_args(args); while (*s) { Char c = *s++; if (c != '{' && c != '}') continue; if (*s == c) { write(writer_, start_, s); start_ = ++s; continue; } if (c == '}') FMT_THROW(FormatError("unmatched '}' in format string")); write(writer_, start_, s - 1); Arg arg = parse_arg_index(s); s = format(s, arg); } write(writer_, start_, s); } void fmt::report_system_error( int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { report_error(internal::format_system_error, error_code, message); } #ifdef _WIN32 void fmt::report_windows_error( int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { report_error(internal::format_windows_error, error_code, message); } #endif void fmt::print(std::FILE *f, StringRef format_str, ArgList args) { MemoryWriter w; w.write(format_str, args); std::fwrite(w.data(), 1, w.size(), f); } void fmt::print(StringRef format_str, ArgList args) { print(stdout, format_str, args); } void fmt::print(std::ostream &os, StringRef format_str, ArgList args) { MemoryWriter w; w.write(format_str, args); os.write(w.data(), w.size()); } void fmt::print_colored(Color c, StringRef format, ArgList args) { char escape[] = "\x1b[30m"; escape[3] = '0' + static_cast(c); std::fputs(escape, stdout); print(format, args); std::fputs(RESET_COLOR, stdout); } int fmt::fprintf(std::FILE *f, StringRef format, ArgList args) { MemoryWriter w; printf(w, format, args); std::size_t size = w.size(); return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size); } // Explicit instantiations for char. template const char *fmt::BasicFormatter::format( const char *&format_str, const fmt::internal::Arg &arg); template void fmt::BasicFormatter::format( BasicStringRef format, const ArgList &args); template void fmt::internal::PrintfFormatter::format( BasicWriter &writer, BasicStringRef format, const ArgList &args); template int fmt::internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, double value); template int fmt::internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, unsigned width, int precision, long double value); // Explicit instantiations for wchar_t. template const wchar_t *fmt::BasicFormatter::format( const wchar_t *&format_str, const fmt::internal::Arg &arg); template void fmt::BasicFormatter::format( BasicStringRef format, const ArgList &args); template void fmt::internal::PrintfFormatter::format( BasicWriter &writer, BasicStringRef format, const ArgList &args); template int fmt::internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, double value); template int fmt::internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, long double value); #if _MSC_VER # pragma warning(pop) #endif } // end generic namespace davix-R_0_5_0/src/libs/alibxx/str/format.hpp000066400000000000000000002152231257152637300211120ustar00rootroot00000000000000/* Forked form cppformat (original author Victor Zverovich) */ #ifndef FMT_FORMAT_HPP_ #define FMT_FORMAT_HPP_ #include #include #include #include // for std::ptrdiff_t #include #include #include #include #include #include // define A_LIB_NAMESPACE to empty if not define // trigger compilation error if not defined properly #ifndef A_LIB_NAMESPACE #error "A_LIB_NAMESPACE need to be defined" #endif namespace A_LIB_NAMESPACE { #if _SECURE_SCL # include #endif #ifdef __GNUC__ # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) # define FMT_GCC_EXTENSION __extension__ // Disable warning about "long long" which is sometimes reported even // when using __extension__. # if FMT_GCC_VERSION >= 406 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wlong-long" # endif #else # define FMT_GCC_EXTENSION #endif #ifdef __GNUC_LIBSTD__ # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) #endif #ifdef __has_feature # define FMT_HAS_FEATURE(x) __has_feature(x) #else # define FMT_HAS_FEATURE(x) 0 #endif #ifdef __has_builtin # define FMT_HAS_BUILTIN(x) __has_builtin(x) #else # define FMT_HAS_BUILTIN(x) 0 #endif #ifndef FMT_USE_VARIADIC_TEMPLATES // Variadic templates are available in GCC since version 4.4 // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++ // since version 2013. # define FMT_USE_VARIADIC_TEMPLATES \ (FMT_HAS_FEATURE(cxx_variadic_templates) || \ (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || _MSC_VER >= 1800) #endif #ifndef FMT_USE_RVALUE_REFERENCES // Don't use rvalue references when compiling with clang and an old libstdc++ // as the latter doesn't provide std::move. # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402 # define FMT_USE_RVALUE_REFERENCES 0 # else # define FMT_USE_RVALUE_REFERENCES \ (FMT_HAS_FEATURE(cxx_rvalue_references) || \ (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || _MSC_VER >= 1600) # endif #endif #if FMT_USE_RVALUE_REFERENCES # include // for std::move #endif // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) # define FMT_NOEXCEPT(expr) noexcept(expr) #else # define FMT_NOEXCEPT(expr) #endif // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for a class #define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) namespace fmt { // Fix the warning about long long on older versions of GCC // that don't support the diagnostic pragma. FMT_GCC_EXTENSION typedef long long LongLong; FMT_GCC_EXTENSION typedef unsigned long long ULongLong; #if FMT_USE_RVALUE_REFERENCES using std::move; #endif template class BasicWriter; typedef BasicWriter Writer; typedef BasicWriter WWriter; template class BasicFormatter; template void format(BasicFormatter &f, const Char *&format_str, const T &value); /** \rst A string reference. It can be constructed from a C string or ``std::string``. You can use one of the following typedefs for common character types: +------------+-------------------------+ | Type | Definition | +============+=========================+ | StringRef | BasicStringRef | +------------+-------------------------+ | WStringRef | BasicStringRef | +------------+-------------------------+ This class is most useful as a parameter type to allow passing different types of strings to a function, for example:: template std::string format(StringRef format, const Args & ... args); format("{}", 42); format(std::string("{}"), 42); \endrst */ template class BasicStringRef { private: const Char *data_; std::size_t size_; public: /** Constructs a string reference object from a C string and a size. */ BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {} /** Constructs a string reference object from a C string computing the size with ``std::char_traits::length``. */ BasicStringRef(const Char *s) : data_(s), size_(std::char_traits::length(s)) {} /** Constructs a string reference from an `std::string` object. */ BasicStringRef(const std::basic_string &s) : data_(s.c_str()), size_(s.size()) {} /** Converts a string reference to an `std::string` object. */ operator std::basic_string() const { return std::basic_string(data_, size()); } /** Returns the pointer to a C string. */ const Char *c_str() const { return data_; } /** Returns the string size. */ std::size_t size() const { return size_; } friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) { return lhs.data_ == rhs.data_; } friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) { return lhs.data_ != rhs.data_; } }; typedef BasicStringRef StringRef; typedef BasicStringRef WStringRef; /** A formatting error such as invalid format string. */ class FormatError : public std::runtime_error { public: explicit FormatError(StringRef message) : std::runtime_error(message.c_str()) {} }; namespace internal { // The number of characters to store in the MemoryBuffer object itself // to avoid dynamic memory allocation. enum { INLINE_BUFFER_SIZE = 500 }; #if _SECURE_SCL // Use checked iterator to avoid warnings on MSVC. template inline stdext::checked_array_iterator make_ptr(T *ptr, std::size_t size) { return stdext::checked_array_iterator(ptr, size); } #else template inline T *make_ptr(T *ptr, std::size_t) { return ptr; } #endif // A buffer for POD types. It supports a subset of std::vector's operations. template class Buffer { private: FMT_DISALLOW_COPY_AND_ASSIGN(Buffer); protected: T *ptr_; std::size_t size_; std::size_t capacity_; Buffer(T *ptr = 0, std::size_t capacity = 0) : ptr_(ptr), size_(0), capacity_(capacity) {} virtual void grow(std::size_t size) = 0; public: virtual ~Buffer() {} // Returns the size of this buffer. std::size_t size() const { return size_; } // Returns the capacity of this buffer. std::size_t capacity() const { return capacity_; } // Resizes the buffer. If T is a POD type new elements are not initialized. void resize(std::size_t new_size) { if (new_size > capacity_) grow(new_size); size_ = new_size; } // Reserves space to store at least capacity elements. void reserve(std::size_t capacity) { if (capacity > capacity_) grow(capacity); } void clear() FMT_NOEXCEPT(true) { size_ = 0; } void push_back(const T &value) { if (size_ == capacity_) grow(size_ + 1); ptr_[size_++] = value; } // Appends data to the end of the buffer. void append(const T *begin, const T *end); T &operator[](std::size_t index) { return ptr_[index]; } const T &operator[](std::size_t index) const { return ptr_[index]; } }; template void Buffer::append(const T *begin, const T *end) { std::ptrdiff_t num_elements = end - begin; if (size_ + num_elements > capacity_) grow(size_ + num_elements); std::copy(begin, end, make_ptr(ptr_, capacity_) + size_); size_ += num_elements; } // A memory buffer for POD types with the first SIZE elements stored in // the object itself. template > class MemoryBuffer : private Allocator, public Buffer { private: T data_[SIZE]; // Free memory allocated by the buffer. void free() { if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_); } protected: void grow(std::size_t size); public: explicit MemoryBuffer(const Allocator &alloc = Allocator()) : Allocator(alloc), Buffer(data_, SIZE) {} ~MemoryBuffer() { free(); } #if FMT_USE_RVALUE_REFERENCES private: // Move data from other to this buffer. void move(MemoryBuffer &other) { Allocator &this_alloc = *this, &other_alloc = other; this_alloc = std::move(other_alloc); this->size_ = other.size_; this->capacity_ = other.capacity_; if (other.ptr_ == other.data_) { this->ptr_ = data_; std::copy(other.data_, other.data_ + this->size_, make_ptr(data_, this->capacity_)); } else { this->ptr_ = other.ptr_; // Set pointer to the inline array so that delete is not called // when freeing. other.ptr_ = other.data_; } } public: MemoryBuffer(MemoryBuffer &&other) { move(other); } MemoryBuffer &operator=(MemoryBuffer &&other) { assert(this != &other); free(); move(other); return *this; } #endif // Returns a copy of the allocator associated with this buffer. Allocator get_allocator() const { return *this; } }; template void MemoryBuffer::grow(std::size_t size) { std::size_t new_capacity = (std::max)(size, this->capacity_ + this->capacity_ / 2); T *new_ptr = this->allocate(new_capacity); // The following code doesn't throw, so the raw pointer above doesn't leak. std::copy(this->ptr_, this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity)); std::size_t old_capacity = this->capacity_; T *old_ptr = this->ptr_; this->capacity_ = new_capacity; this->ptr_ = new_ptr; // deallocate may throw (at least in principle), but it doesn't matter since // the buffer already uses the new storage and will deallocate it in case // of exception. if (old_ptr != data_) this->deallocate(old_ptr, old_capacity); } #ifndef _MSC_VER // Portable version of signbit. inline int getsign(double x) { // When compiled in C++11 mode signbit is no longer a macro but a function // defined in namespace std and the macro is undefined. # ifdef signbit return signbit(x); # else return std::signbit(x); # endif } // Portable version of isinf. # ifdef isinf inline int isinfinity(double x) { return isinf(x); } inline int isinfinity(long double x) { return isinf(x); } # else inline int isinfinity(double x) { return std::isinf(x); } inline int isinfinity(long double x) { return std::isinf(x); } # endif #else inline int getsign(double value) { if (value < 0) return 1; if (value == value) return 0; int dec = 0, sign = 0; char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); return sign; } inline int isinfinity(double x) { return !_finite(x); } #endif template struct IsLongDouble { enum {VALUE = 0}; }; template <> struct IsLongDouble { enum {VALUE = 1}; }; template class BasicCharTraits { public: #if _SECURE_SCL typedef stdext::checked_array_iterator CharPtr; #else typedef Char *CharPtr; #endif }; template class CharTraits; template <> class CharTraits : public BasicCharTraits { private: // Conversion from wchar_t to char is not allowed. static char convert(wchar_t); public: typedef const wchar_t *UnsupportedStrType; static char convert(char value) { return value; } // Formats a floating-point number. template static int format_float(char *buffer, std::size_t size, const char *format, unsigned width, int precision, T value); }; template <> class CharTraits : public BasicCharTraits { public: typedef const char *UnsupportedStrType; static wchar_t convert(char value) { return value; } static wchar_t convert(wchar_t value) { return value; } template static int format_float(wchar_t *buffer, std::size_t size, const wchar_t *format, unsigned width, int precision, T value); }; // Checks if a number is negative - used to avoid warnings. template struct SignChecker { template static bool is_negative(T value) { return value < 0; } }; template <> struct SignChecker { template static bool is_negative(T) { return false; } }; // Returns true if value is negative, false otherwise. // Same as (value < 0) but doesn't produce warnings if T is an unsigned type. template inline bool is_negative(T value) { return SignChecker::is_signed>::is_negative(value); } // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise. template struct TypeSelector { typedef uint32_t Type; }; template <> struct TypeSelector { typedef uint64_t Type; }; template struct IntTraits { // Smallest of uint32_t and uint64_t that is large enough to represent // all values of T. typedef typename TypeSelector::digits <= 32>::Type MainType; }; // MakeUnsigned::Type gives an unsigned type corresponding to integer type T. template struct MakeUnsigned { typedef T Type; }; #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \ template <> \ struct MakeUnsigned { typedef U Type; } FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char); FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char); FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short); FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned); FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long); FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong); void report_unknown_type(char code, const char *type); extern const uint32_t POWERS_OF_10_32[]; extern const uint64_t POWERS_OF_10_64[]; #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) // Returns the number of decimal digits in n. Leading zeros are not counted // except for n == 0 in which case count_digits returns 1. inline unsigned count_digits(uint64_t n) { // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12; return t - (n < POWERS_OF_10_64[t]) + 1; } # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) // Optional version of count_digits for better performance on 32-bit platforms. inline unsigned count_digits(uint32_t n) { uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12; return t - (n < POWERS_OF_10_32[t]) + 1; } # endif #else // Fallback version of count_digits used when __builtin_clz is not available. inline unsigned count_digits(uint64_t n) { unsigned count = 1; for (;;) { // Integer division is slow so do it for a group of four digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. if (n < 10) return count; if (n < 100) return count + 1; if (n < 1000) return count + 2; if (n < 10000) return count + 3; n /= 10000u; count += 4; } } #endif extern const char DIGITS[]; // Formats a decimal unsigned integer value writing into buffer. template inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) { --num_digits; while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. unsigned index = (value % 100) * 2; value /= 100; buffer[num_digits] = DIGITS[index + 1]; buffer[num_digits - 1] = DIGITS[index]; num_digits -= 2; } if (value < 10) { *buffer = static_cast('0' + value); return; } unsigned index = static_cast(value * 2); buffer[1] = DIGITS[index + 1]; buffer[0] = DIGITS[index]; } #ifdef _WIN32 // A converter from UTF-8 to UTF-16. // It is only provided for Windows since other systems support UTF-8 natively. class UTF8ToUTF16 { private: MemoryBuffer buffer_; public: explicit UTF8ToUTF16(StringRef s); operator WStringRef() const { return WStringRef(&buffer_[0], size()); } size_t size() const { return buffer_.size() - 1; } const wchar_t *c_str() const { return &buffer_[0]; } std::wstring str() const { return std::wstring(&buffer_[0], size()); } }; // A converter from UTF-16 to UTF-8. // It is only provided for Windows since other systems support UTF-8 natively. class UTF16ToUTF8 { private: MemoryBuffer buffer_; public: UTF16ToUTF8() {} explicit UTF16ToUTF8(WStringRef s); operator StringRef() const { return StringRef(&buffer_[0], size()); } size_t size() const { return buffer_.size() - 1; } const char *c_str() const { return &buffer_[0]; } std::string str() const { return std::string(&buffer_[0], size()); } // Performs conversion returning a system error code instead of // throwing exception on conversion error. This method may still throw // in case of memory allocation error. int convert(WStringRef s); }; #endif void format_system_error(fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT(true); #ifdef _WIN32 void format_windows_error(fmt::Writer &out, int error_code, fmt::StringRef message) FMT_NOEXCEPT(true); #endif // Computes max(Arg, 1) at compile time. It is used to avoid errors about // allocating an array of 0 size. template struct NonZero { enum { VALUE = Arg }; }; template <> struct NonZero<0> { enum { VALUE = 1 }; }; // The value of a formatting argument. It is a POD type to allow storage in // internal::MemoryBuffer. struct Value { template struct StringValue { const Char *value; std::size_t size; }; typedef void (*FormatFunc)( void *formatter, const void *arg, void *format_str_ptr); struct CustomValue { const void *value; FormatFunc format; }; union { int int_value; unsigned uint_value; LongLong long_long_value; ULongLong ulong_long_value; double double_value; long double long_double_value; const void *pointer; StringValue string; StringValue sstring; StringValue ustring; StringValue wstring; CustomValue custom; }; }; struct Arg : Value { enum Type { NONE, // Integer types should go first, INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, // followed by floating-point types. DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, CSTRING, STRING, WSTRING, POINTER, CUSTOM }; Type type; }; // Makes a Value object from any type. template class MakeValue : public Value { private: // The following two methods are private to disallow formatting of // arbitrary pointers. If you want to output a pointer cast it to // "void *" or "const void *". In particular, this forbids formatting // of "[const] volatile char *" which is printed as bool by iostreams. // Do not implement! template MakeValue(const T *value); template MakeValue(T *value); void set_string(StringRef str) { string.value = str.c_str(); string.size = str.size(); } void set_string(WStringRef str) { CharTraits::convert(wchar_t()); wstring.value = str.c_str(); wstring.size = str.size(); } // Formats an argument of a custom type, such as a user-defined class. template static void format_custom_arg( void *formatter, const void *arg, void *format_str_ptr) { format(*static_cast*>(formatter), *static_cast(format_str_ptr), *static_cast(arg)); } public: MakeValue() {} #define FMT_MAKE_VALUE(Type, field, TYPE) \ MakeValue(Type value) { field = value; } \ static uint64_t type(Type) { return Arg::TYPE; } FMT_MAKE_VALUE(bool, int_value, INT) FMT_MAKE_VALUE(short, int_value, INT) FMT_MAKE_VALUE(unsigned short, uint_value, UINT) FMT_MAKE_VALUE(int, int_value, INT) FMT_MAKE_VALUE(unsigned, uint_value, UINT) MakeValue(long value) { // To minimize the number of types we need to deal with, long is // translated either to int or to long long depending on its size. if (sizeof(long) == sizeof(int)) int_value = static_cast(value); else long_long_value = value; } static uint64_t type(long) { return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG; } MakeValue(unsigned long value) { if (sizeof(unsigned long) == sizeof(unsigned)) uint_value = static_cast(value); else ulong_long_value = value; } static uint64_t type(unsigned long) { return sizeof(unsigned long) == sizeof(unsigned) ? Arg::UINT : Arg::ULONG_LONG; } FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG) FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG) FMT_MAKE_VALUE(float, double_value, DOUBLE) FMT_MAKE_VALUE(double, double_value, DOUBLE) FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE) FMT_MAKE_VALUE(signed char, int_value, CHAR) FMT_MAKE_VALUE(unsigned char, int_value, CHAR) FMT_MAKE_VALUE(char, int_value, CHAR) MakeValue(wchar_t value) { int_value = internal::CharTraits::convert(value); } static uint64_t type(wchar_t) { return Arg::CHAR; } #define FMT_MAKE_STR_VALUE(Type, TYPE) \ MakeValue(Type value) { set_string(value); } \ static uint64_t type(Type) { return Arg::TYPE; } FMT_MAKE_VALUE(char *, string.value, CSTRING) FMT_MAKE_VALUE(const char *, string.value, CSTRING) FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) FMT_MAKE_STR_VALUE(const std::string &, STRING) FMT_MAKE_STR_VALUE(StringRef, STRING) FMT_MAKE_STR_VALUE(wchar_t *, WSTRING) FMT_MAKE_STR_VALUE(const wchar_t *, WSTRING) FMT_MAKE_STR_VALUE(const std::wstring &, WSTRING) FMT_MAKE_STR_VALUE(WStringRef, WSTRING) FMT_MAKE_VALUE(void *, pointer, POINTER) FMT_MAKE_VALUE(const void *, pointer, POINTER) template MakeValue(const T &value) { custom.value = &value; custom.format = &format_custom_arg; } template static uint64_t type(const T &) { return Arg::CUSTOM; } }; #define FMT_DISPATCH(call) static_cast(this)->call // An argument visitor. // To use ArgVisitor define a subclass that implements some or all of the // visit methods with the same signatures as the methods in ArgVisitor, // for example, visit_int(int). // Specify the subclass name as the Impl template parameter. Then calling // ArgVisitor::visit for some argument will dispatch to a visit method // specific to the argument type. For example, if the argument type is // double then visit_double(double) method of a subclass will be called. // If the subclass doesn't contain a method with this signature, then // a corresponding method of ArgVisitor will be called. // // Example: // class MyArgVisitor : public ArgVisitor { // public: // void visit_int(int value) { print("{}", value); } // void visit_double(double value) { print("{}", value ); } // }; // // ArgVisitor uses the curiously recurring template pattern: // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern template class ArgVisitor { public: Result visit_unhandled_arg() { return Result(); } Result visit_int(int value) { return FMT_DISPATCH(visit_any_int(value)); } Result visit_long_long(LongLong value) { return FMT_DISPATCH(visit_any_int(value)); } Result visit_uint(unsigned value) { return FMT_DISPATCH(visit_any_int(value)); } Result visit_ulong_long(ULongLong value) { return FMT_DISPATCH(visit_any_int(value)); } Result visit_char(int value) { return FMT_DISPATCH(visit_any_int(value)); } template Result visit_any_int(T) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit_double(double value) { return FMT_DISPATCH(visit_any_double(value)); } Result visit_long_double(long double value) { return FMT_DISPATCH(visit_any_double(value)); } template Result visit_any_double(T) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit_string(Arg::StringValue) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit_wstring(Arg::StringValue) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit_pointer(const void *) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit_custom(Arg::CustomValue) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit(const Arg &arg) { switch (arg.type) { default: assert(false); // Fall through. case Arg::INT: return FMT_DISPATCH(visit_int(arg.int_value)); case Arg::UINT: return FMT_DISPATCH(visit_uint(arg.uint_value)); case Arg::LONG_LONG: return FMT_DISPATCH(visit_long_long(arg.long_long_value)); case Arg::ULONG_LONG: return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); case Arg::DOUBLE: return FMT_DISPATCH(visit_double(arg.double_value)); case Arg::LONG_DOUBLE: return FMT_DISPATCH(visit_long_double(arg.long_double_value)); case Arg::CHAR: return FMT_DISPATCH(visit_char(arg.int_value)); case Arg::CSTRING: { Value::StringValue str = arg.string; str.size = 0; return FMT_DISPATCH(visit_string(str)); } case Arg::STRING: return FMT_DISPATCH(visit_string(arg.string)); case Arg::WSTRING: return FMT_DISPATCH(visit_wstring(arg.wstring)); case Arg::POINTER: return FMT_DISPATCH(visit_pointer(arg.pointer)); case Arg::CUSTOM: return FMT_DISPATCH(visit_custom(arg.custom)); } } }; class RuntimeError : public std::runtime_error { protected: RuntimeError() : std::runtime_error("") {} }; template class ArgFormatter; } // namespace internal /** An argument list. */ class ArgList { private: uint64_t types_; const internal::Value *values_; public: // Maximum number of arguments that can be passed in ArgList. enum { MAX_ARGS = 16 }; ArgList() : types_(0) {} ArgList(ULongLong types, const internal::Value *values) : types_(types), values_(values) {} /** Returns the argument at specified index. */ internal::Arg operator[](unsigned index) const { using internal::Arg; Arg arg; if (index >= MAX_ARGS) { arg.type = Arg::NONE; return arg; } unsigned shift = index * 4; uint64_t mask = 0xf; Arg::Type type = static_cast((types_ & (mask << shift)) >> shift); arg.type = type; if (type != Arg::NONE) { internal::Value &value = arg; value = values_[index]; } return arg; } }; struct FormatSpec; namespace internal { class FormatterBase { private: ArgList args_; int next_arg_index_; // Returns the argument with specified index. Arg do_get_arg(unsigned arg_index, const char *&error); protected: void set_args(const ArgList &args) { args_ = args; next_arg_index_ = 0; } // Returns the next argument. Arg next_arg(const char *&error); // Checks if manual indexing is used and returns the argument with // specified index. Arg get_arg(unsigned arg_index, const char *&error); template void write(BasicWriter &w, const Char *start, const Char *end) { if (start != end) w << BasicStringRef(start, end - start); } }; // A printf formatter. template class PrintfFormatter : private FormatterBase { private: void parse_flags(FormatSpec &spec, const Char *&s); // Returns the argument with specified index or, if arg_index is equal // to the maximum unsigned value, the next argument. Arg get_arg(const Char *s, unsigned arg_index = (std::numeric_limits::max)()); // Parses argument index, flags and width and returns the argument index. unsigned parse_header(const Char *&s, FormatSpec &spec); public: void format(BasicWriter &writer, BasicStringRef format, const ArgList &args); }; } // namespace internal // A formatter. template class BasicFormatter : private internal::FormatterBase { private: BasicWriter &writer_; const Char *start_; // Parses argument index and returns corresponding argument. internal::Arg parse_arg_index(const Char *&s); public: explicit BasicFormatter(BasicWriter &w) : writer_(w) {} BasicWriter &writer() { return writer_; } void format(BasicStringRef format_str, const ArgList &args); const Char *format(const Char *&format_str, const internal::Arg &arg); }; enum Alignment { ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC }; // Flags. enum { SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8, CHAR_FLAG = 0x10 // Argument has char type - used in error reporting. }; // An empty format specifier. struct EmptySpec {}; // A type specifier. template struct TypeSpec : EmptySpec { Alignment align() const { return ALIGN_DEFAULT; } unsigned width() const { return 0; } int precision() const { return -1; } bool flag(unsigned) const { return false; } char type() const { return TYPE; } char fill() const { return ' '; } }; // A width specifier. struct WidthSpec { unsigned width_; // Fill is always wchar_t and cast to char if necessary to avoid having // two specialization of WidthSpec and its subclasses. wchar_t fill_; WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} unsigned width() const { return width_; } wchar_t fill() const { return fill_; } }; // An alignment specifier. struct AlignSpec : WidthSpec { Alignment align_; AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) : WidthSpec(width, fill), align_(align) {} Alignment align() const { return align_; } int precision() const { return -1; } }; // An alignment and type specifier. template struct AlignTypeSpec : AlignSpec { AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} bool flag(unsigned) const { return false; } char type() const { return TYPE; } }; // A full format specifier. struct FormatSpec : AlignSpec { unsigned flags_; int precision_; char type_; FormatSpec( unsigned width = 0, char type = 0, wchar_t fill = ' ') : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} bool flag(unsigned f) const { return (flags_ & f) != 0; } int precision() const { return precision_; } char type() const { return type_; } }; // An integer format specifier. template , typename Char = char> class IntFormatSpec : public SpecT { private: T value_; public: IntFormatSpec(T value, const SpecT &spec = SpecT()) : SpecT(spec), value_(value) {} T value() const { return value_; } }; // A string format specifier. template class StrFormatSpec : public AlignSpec { private: const T *str_; public: StrFormatSpec(const T *str, unsigned width, wchar_t fill) : AlignSpec(width, fill), str_(str) {} const T *str() const { return str_; } }; /** Returns an integer format specifier to format the value in base 2. */ IntFormatSpec > bin(int value); /** Returns an integer format specifier to format the value in base 8. */ IntFormatSpec > oct(int value); /** Returns an integer format specifier to format the value in base 16 using lower-case letters for the digits above 9. */ IntFormatSpec > hex(int value); /** Returns an integer formatter format specifier to format in base 16 using upper-case letters for the digits above 9. */ IntFormatSpec > hexu(int value); /** \rst Returns an integer format specifier to pad the formatted argument with the fill character to the specified width using the default (right) numeric alignment. **Example**:: MemoryWriter out; out << pad(hex(0xcafe), 8, '0'); // out.str() == "0000cafe" \endrst */ template IntFormatSpec, Char> pad( int value, unsigned width, Char fill = ' '); #define FMT_DEFINE_INT_FORMATTERS(TYPE) \ inline IntFormatSpec > bin(TYPE value) { \ return IntFormatSpec >(value, TypeSpec<'b'>()); \ } \ \ inline IntFormatSpec > oct(TYPE value) { \ return IntFormatSpec >(value, TypeSpec<'o'>()); \ } \ \ inline IntFormatSpec > hex(TYPE value) { \ return IntFormatSpec >(value, TypeSpec<'x'>()); \ } \ \ inline IntFormatSpec > hexu(TYPE value) { \ return IntFormatSpec >(value, TypeSpec<'X'>()); \ } \ \ template \ inline IntFormatSpec > pad( \ IntFormatSpec > f, unsigned width) { \ return IntFormatSpec >( \ f.value(), AlignTypeSpec(width, ' ')); \ } \ \ /* For compatibility with older compilers we provide two overloads for pad, */ \ /* one that takes a fill character and one that doesn't. In the future this */ \ /* can be replaced with one overload making the template argument Char */ \ /* default to char (C++11). */ \ template \ inline IntFormatSpec, Char> pad( \ IntFormatSpec, Char> f, \ unsigned width, Char fill) { \ return IntFormatSpec, Char>( \ f.value(), AlignTypeSpec(width, fill)); \ } \ \ inline IntFormatSpec > pad( \ TYPE value, unsigned width) { \ return IntFormatSpec >( \ value, AlignTypeSpec<0>(width, ' ')); \ } \ \ template \ inline IntFormatSpec, Char> pad( \ TYPE value, unsigned width, Char fill) { \ return IntFormatSpec, Char>( \ value, AlignTypeSpec<0>(width, fill)); \ } FMT_DEFINE_INT_FORMATTERS(int) FMT_DEFINE_INT_FORMATTERS(long) FMT_DEFINE_INT_FORMATTERS(unsigned) FMT_DEFINE_INT_FORMATTERS(unsigned long) FMT_DEFINE_INT_FORMATTERS(LongLong) FMT_DEFINE_INT_FORMATTERS(ULongLong) /** \rst Returns a string formatter that pads the formatted argument with the fill character to the specified width using the default (left) string alignment. **Example**:: std::string s = str(MemoryWriter() << pad("abc", 8)); // s == "abc " \endrst */ template inline StrFormatSpec pad( const Char *str, unsigned width, Char fill = ' ') { return StrFormatSpec(str, width, fill); } inline StrFormatSpec pad( const wchar_t *str, unsigned width, char fill = ' ') { return StrFormatSpec(str, width, fill); } // Generates a comma-separated list with results of applying f to // numbers 0..n-1. # define FMT_GEN(n, f) FMT_GEN##n(f) # define FMT_GEN1(f) f(0) # define FMT_GEN2(f) FMT_GEN1(f), f(1) # define FMT_GEN3(f) FMT_GEN2(f), f(2) # define FMT_GEN4(f) FMT_GEN3(f), f(3) # define FMT_GEN5(f) FMT_GEN4(f), f(4) # define FMT_GEN6(f) FMT_GEN5(f), f(5) # define FMT_GEN7(f) FMT_GEN6(f), f(6) # define FMT_GEN8(f) FMT_GEN7(f), f(7) # define FMT_GEN9(f) FMT_GEN8(f), f(8) # define FMT_GEN10(f) FMT_GEN9(f), f(9) # define FMT_GEN11(f) FMT_GEN10(f), f(10) # define FMT_GEN12(f) FMT_GEN11(f), f(11) # define FMT_GEN13(f) FMT_GEN12(f), f(12) # define FMT_GEN14(f) FMT_GEN13(f), f(13) # define FMT_GEN15(f) FMT_GEN14(f), f(14) namespace internal { inline uint64_t make_type() { return 0; } template inline uint64_t make_type(const T &arg) { return MakeValue::type(arg); } #if FMT_USE_VARIADIC_TEMPLATES template inline uint64_t make_type(const Arg &first, const Args & ... tail) { return make_type(first) | (make_type(tail...) << 4); } #else struct ArgType { uint64_t type; ArgType() : type(0) {} template ArgType(const T &arg) : type(make_type(arg)) {} }; # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType() inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) | (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) | (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) | (t12.type << 48) | (t13.type << 52) | (t14.type << 56); } #endif } // namespace internal # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n # define FMT_MAKE_ARG_TYPE(n) T##n # define FMT_MAKE_ARG(n) const T##n &v##n # define FMT_MAKE_REF_char(n) fmt::internal::MakeValue(v##n) # define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeValue(v##n) #if FMT_USE_VARIADIC_TEMPLATES // Defines a variadic function returning void. # define FMT_VARIADIC_VOID(func, arg_type) \ template \ void func(arg_type arg1, const Args & ... args) { \ const fmt::internal::Value values[ \ fmt::internal::NonZero::VALUE] = { \ fmt::internal::MakeValue(args)... \ }; \ func(arg1, ArgList(fmt::internal::make_type(args...), values)); \ } // Defines a variadic constructor. # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ template \ ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ using fmt::internal::MakeValue; \ const fmt::internal::Value values[ \ fmt::internal::NonZero::VALUE] = { \ MakeValue(args)... \ }; \ func(arg0, arg1, ArgList(fmt::internal::make_type(args...), values)); \ } #else # define FMT_MAKE_REF(n) fmt::internal::MakeValue(v##n) # define FMT_MAKE_REF2(n) v##n // Defines a wrapper for a function taking one argument of type arg_type // and n additional arguments of arbitrary types. # define FMT_WRAP1(func, arg_type, n) \ template \ inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ const fmt::internal::Value vals[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ func(arg1, fmt::ArgList( \ fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), vals)); \ } // Emulates a variadic function returning void on a pre-C++11 compiler. # define FMT_VARIADIC_VOID(func, arg_type) \ FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \ FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \ FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \ FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \ FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10) # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \ template \ ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ const fmt::internal::Value vals[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ func(arg0, arg1, fmt::ArgList( \ fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), vals)); \ } // Emulates a variadic constructor on a pre-C++11 compiler. # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \ FMT_CTOR(ctor, func, arg0_type, arg1_type, 10) #endif // Generates a comma-separated list with results of applying f to pairs // (argument, index). #define FMT_FOR_EACH1(f, x0) f(x0, 0) #define FMT_FOR_EACH2(f, x0, x1) \ FMT_FOR_EACH1(f, x0), f(x1, 1) #define FMT_FOR_EACH3(f, x0, x1, x2) \ FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2) #define FMT_FOR_EACH4(f, x0, x1, x2, x3) \ FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3) #define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \ FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4) #define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \ FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5) #define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \ FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6) #define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \ FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7) #define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \ FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8) #define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9) /** An error returned by an operating system or a language runtime, for example a file opening error. */ class SystemError : public internal::RuntimeError { private: void init(int error_code, StringRef format_str, ArgList args); protected: int error_code_; typedef char Char; // For FMT_VARIADIC_CTOR. SystemError() {} public: /** \rst Constructs a :cpp:class:`fmt::SystemError` object with the description of the form "**: **", where ** is the formatted message and ** is the system message corresponding to the error code. *error_code* is a system error code as given by ``errno``. \endrst */ SystemError(int error_code, StringRef message) { init(error_code, message, ArgList()); } FMT_VARIADIC_CTOR(SystemError, init, int, StringRef) int error_code() const { return error_code_; } }; /** \rst This template provides operations for formatting and writing data into a character stream. The output is stored in a buffer provided by a subclass such as :cpp:class:`fmt::BasicMemoryWriter`. You can use one of the following typedefs for common character types: +---------+----------------------+ | Type | Definition | +=========+======================+ | Writer | BasicWriter | +---------+----------------------+ | WWriter | BasicWriter | +---------+----------------------+ \endrst */ template class BasicWriter { private: // Output buffer. internal::Buffer &buffer_; FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter); typedef typename internal::CharTraits::CharPtr CharPtr; #if _SECURE_SCL // Returns pointer value. static Char *get(CharPtr p) { return p.base(); } #else static Char *get(Char *p) { return p; } #endif // Fills the padding around the content and returns the pointer to the // content area. static CharPtr fill_padding(CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill); // Grows the buffer by n characters and returns a pointer to the newly // allocated area. CharPtr grow_buffer(std::size_t n) { std::size_t size = buffer_.size(); buffer_.resize(size + n); return internal::make_ptr(&buffer_[size], n); } // Prepare a buffer for integer formatting. CharPtr prepare_int_buffer(unsigned num_digits, const EmptySpec &, const char *prefix, unsigned prefix_size) { unsigned size = prefix_size + num_digits; CharPtr p = grow_buffer(size); std::copy(prefix, prefix + prefix_size, p); return p + size - 1; } template CharPtr prepare_int_buffer(unsigned num_digits, const Spec &spec, const char *prefix, unsigned prefix_size); // Formats an integer. template void write_int(T value, Spec spec); // Formats a floating-point number (double or long double). template void write_double(T value, const FormatSpec &spec); // Writes a formatted string. template CharPtr write_str( const StrChar *s, std::size_t size, const AlignSpec &spec); template void write_str( const internal::Arg::StringValue &str, const FormatSpec &spec); // This method is private to disallow writing a wide string to a // char stream and vice versa. If you want to print a wide string // as a pointer as std::ostream does, cast it to const void*. // Do not implement! void operator<<(typename internal::CharTraits::UnsupportedStrType); friend class internal::ArgFormatter; friend class internal::PrintfFormatter; protected: /** Constructs a ``BasicWriter`` object. */ explicit BasicWriter(internal::Buffer &b) : buffer_(b) {} public: /** Destroys a ``BasicWriter`` object. */ virtual ~BasicWriter() {} /** Returns the total number of characters written. */ std::size_t size() const { return buffer_.size(); } /** Returns a pointer to the output buffer content. No terminating null character is appended. */ const Char *data() const FMT_NOEXCEPT(true) { return &buffer_[0]; } /** Returns a pointer to the output buffer content with terminating null character appended. */ const Char *c_str() const { std::size_t size = buffer_.size(); buffer_.reserve(size + 1); buffer_[size] = '\0'; return &buffer_[0]; } /** Returns the content of the output buffer as an `std::string`. */ std::basic_string str() const { return std::basic_string(&buffer_[0], buffer_.size()); } /** \rst Writes formatted data. *args* is an argument list representing arbitrary arguments. **Example**:: MemoryWriter out; out.write("Current point:\n"); out.write("({:+f}, {:+f})", -3.14, 3.14); This will write the following output to the ``out`` object: .. code-block:: none Current point: (-3.140000, +3.140000) The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str` methods. See also :ref:`syntax`. \endrst */ void write(BasicStringRef format, ArgList args) { BasicFormatter(*this).format(format, args); } FMT_VARIADIC_VOID(write, BasicStringRef) BasicWriter &operator<<(int value) { return *this << IntFormatSpec(value); } BasicWriter &operator<<(unsigned value) { return *this << IntFormatSpec(value); } BasicWriter &operator<<(long value) { return *this << IntFormatSpec(value); } BasicWriter &operator<<(unsigned long value) { return *this << IntFormatSpec(value); } BasicWriter &operator<<(LongLong value) { return *this << IntFormatSpec(value); } /** Formats *value* and writes it to the stream. */ BasicWriter &operator<<(ULongLong value) { return *this << IntFormatSpec(value); } BasicWriter &operator<<(double value) { write_double(value, FormatSpec()); return *this; } /** Formats *value* using the general format for floating-point numbers (``'g'``) and writes it to the stream. */ BasicWriter &operator<<(long double value) { write_double(value, FormatSpec()); return *this; } /** Writes a character to the stream. */ BasicWriter &operator<<(char value) { buffer_.push_back(value); return *this; } BasicWriter &operator<<(wchar_t value) { buffer_.push_back(internal::CharTraits::convert(value)); return *this; } /** Writes *value* to the stream. */ BasicWriter &operator<<(fmt::BasicStringRef value) { const Char *str = value.c_str(); buffer_.append(str, str + value.size()); return *this; } template BasicWriter &operator<<(IntFormatSpec spec) { internal::CharTraits::convert(FillChar()); write_int(spec.value(), spec); return *this; } template BasicWriter &operator<<(const StrFormatSpec &spec) { const StrChar *s = spec.str(); // TODO: error if fill is not convertible to Char write_str(s, std::char_traits::length(s), spec); return *this; } void clear() FMT_NOEXCEPT(true) { buffer_.clear(); } }; template template typename BasicWriter::CharPtr BasicWriter::write_str( const StrChar *s, std::size_t size, const AlignSpec &spec) { CharPtr out = CharPtr(); if (spec.width() > size) { out = grow_buffer(spec.width()); Char fill = static_cast(spec.fill()); if (spec.align() == ALIGN_RIGHT) { std::fill_n(out, spec.width() - size, fill); out += spec.width() - size; } else if (spec.align() == ALIGN_CENTER) { out = fill_padding(out, spec.width(), size, fill); } else { std::fill_n(out + size, spec.width() - size, fill); } } else { out = grow_buffer(size); } std::copy(s, s + size, out); return out; } template typename BasicWriter::CharPtr BasicWriter::fill_padding( CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill) { std::size_t padding = total_size - content_size; std::size_t left_padding = padding / 2; Char fill_char = static_cast(fill); std::fill_n(buffer, left_padding, fill_char); buffer += left_padding; CharPtr content = buffer; std::fill_n(buffer + content_size, padding - left_padding, fill_char); return content; } template template typename BasicWriter::CharPtr BasicWriter::prepare_int_buffer( unsigned num_digits, const Spec &spec, const char *prefix, unsigned prefix_size) { unsigned width = spec.width(); Alignment align = spec.align(); Char fill = static_cast(spec.fill()); if (spec.precision() > static_cast(num_digits)) { // Octal prefix '0' is counted as a digit, so ignore it if precision // is specified. if (prefix_size > 0 && prefix[prefix_size - 1] == '0') --prefix_size; unsigned number_size = prefix_size + spec.precision(); AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); if (number_size >= width) return prepare_int_buffer(num_digits, subspec, prefix, prefix_size); buffer_.reserve(width); unsigned fill_size = width - number_size; if (align != ALIGN_LEFT) { CharPtr p = grow_buffer(fill_size); std::fill(p, p + fill_size, fill); } CharPtr result = prepare_int_buffer( num_digits, subspec, prefix, prefix_size); if (align == ALIGN_LEFT) { CharPtr p = grow_buffer(fill_size); std::fill(p, p + fill_size, fill); } return result; } unsigned size = prefix_size + num_digits; if (width <= size) { CharPtr p = grow_buffer(size); std::copy(prefix, prefix + prefix_size, p); return p + size - 1; } CharPtr p = grow_buffer(width); CharPtr end = p + width; if (align == ALIGN_LEFT) { std::copy(prefix, prefix + prefix_size, p); p += size; std::fill(p, end, fill); } else if (align == ALIGN_CENTER) { p = fill_padding(p, width, size, fill); std::copy(prefix, prefix + prefix_size, p); p += size; } else { if (align == ALIGN_NUMERIC) { if (prefix_size != 0) { p = std::copy(prefix, prefix + prefix_size, p); size -= prefix_size; } } else { std::copy(prefix, prefix + prefix_size, end - size); } std::fill(p, end - size, fill); p = end; } return p - 1; } template template void BasicWriter::write_int(T value, Spec spec) { unsigned prefix_size = 0; typedef typename internal::IntTraits::MainType UnsignedType; UnsignedType abs_value = value; char prefix[4] = ""; if (internal::is_negative(value)) { prefix[0] = '-'; ++prefix_size; abs_value = 0 - abs_value; } else if (spec.flag(SIGN_FLAG)) { prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' '; ++prefix_size; } switch (spec.type()) { case 0: case 'd': { unsigned num_digits = internal::count_digits(abs_value); CharPtr p = prepare_int_buffer( num_digits, spec, prefix, prefix_size) + 1 - num_digits; internal::format_decimal(get(p), abs_value, num_digits); break; } case 'x': case 'X': { UnsignedType n = abs_value; if (spec.flag(HASH_FLAG)) { prefix[prefix_size++] = '0'; prefix[prefix_size++] = spec.type(); } unsigned num_digits = 0; do { ++num_digits; } while ((n >>= 4) != 0); Char *p = get(prepare_int_buffer( num_digits, spec, prefix, prefix_size)); n = abs_value; const char *digits = spec.type() == 'x' ? "0123456789abcdef" : "0123456789ABCDEF"; do { *p-- = digits[n & 0xf]; } while ((n >>= 4) != 0); break; } case 'b': case 'B': { UnsignedType n = abs_value; if (spec.flag(HASH_FLAG)) { prefix[prefix_size++] = '0'; prefix[prefix_size++] = spec.type(); } unsigned num_digits = 0; do { ++num_digits; } while ((n >>= 1) != 0); Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; do { *p-- = '0' + (n & 1); } while ((n >>= 1) != 0); break; } case 'o': { UnsignedType n = abs_value; if (spec.flag(HASH_FLAG)) prefix[prefix_size++] = '0'; unsigned num_digits = 0; do { ++num_digits; } while ((n >>= 3) != 0); Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; do { *p-- = '0' + (n & 7); } while ((n >>= 3) != 0); break; } default: internal::report_unknown_type( spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer"); break; } } template template void BasicWriter::write_double( T value, const FormatSpec &spec) { // Check type. char type = spec.type(); bool upper = false; switch (type) { case 0: type = 'g'; break; case 'e': case 'f': case 'g': case 'a': break; case 'F': #ifdef _MSC_VER // MSVC's printf doesn't support 'F'. type = 'f'; #endif // Fall through. case 'E': case 'G': case 'A': upper = true; break; default: internal::report_unknown_type(type, "double"); break; } char sign = 0; // Use getsign instead of value < 0 because the latter is always // false for NaN. if (internal::getsign(static_cast(value))) { sign = '-'; value = -value; } else if (spec.flag(SIGN_FLAG)) { sign = spec.flag(PLUS_FLAG) ? '+' : ' '; } if (value != value) { // Format NaN ourselves because sprintf's output is not consistent // across platforms. std::size_t size = 4; const char *nan = upper ? " NAN" : " nan"; if (!sign) { --size; ++nan; } CharPtr out = write_str(nan, size, spec); if (sign) *out = sign; return; } if (internal::isinfinity(value)) { // Format infinity ourselves because sprintf's output is not consistent // across platforms. std::size_t size = 4; const char *inf = upper ? " INF" : " inf"; if (!sign) { --size; ++inf; } CharPtr out = write_str(inf, size, spec); if (sign) *out = sign; return; } std::size_t offset = buffer_.size(); unsigned width = spec.width(); if (sign) { buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); if (width > 0) --width; ++offset; } // Build format string. enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg Char format[MAX_FORMAT_SIZE]; Char *format_ptr = format; *format_ptr++ = '%'; unsigned width_for_sprintf = width; if (spec.flag(HASH_FLAG)) *format_ptr++ = '#'; if (spec.align() == ALIGN_CENTER) { width_for_sprintf = 0; } else { if (spec.align() == ALIGN_LEFT) *format_ptr++ = '-'; if (width != 0) *format_ptr++ = '*'; } if (spec.precision() >= 0) { *format_ptr++ = '.'; *format_ptr++ = '*'; } if (internal::IsLongDouble::VALUE) *format_ptr++ = 'L'; *format_ptr++ = type; *format_ptr = '\0'; // Format using snprintf. Char fill = static_cast(spec.fill()); for (;;) { std::size_t size = buffer_.capacity() - offset; #if _MSC_VER // MSVC's vsnprintf_s doesn't work with zero size, so reserve // space for at least one extra character to make the size non-zero. // Note that the buffer's capacity will increase by more than 1. if (size == 0) { buffer_.reserve(offset + 1); size = buffer_.capacity() - offset; } #endif Char *start = &buffer_[offset]; int n = internal::CharTraits::format_float( start, size, format, width_for_sprintf, spec.precision(), value); if (n >= 0 && offset + n < buffer_.capacity()) { if (sign) { if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || *start != ' ') { *(start - 1) = sign; sign = 0; } else { *(start - 1) = fill; } ++n; } if (spec.align() == ALIGN_CENTER && spec.width() > static_cast(n)) { unsigned width = spec.width(); CharPtr p = grow_buffer(width); std::copy(p, p + n, p + (width - n) / 2); fill_padding(p, spec.width(), n, fill); return; } if (spec.fill() != ' ' || sign) { while (*start == ' ') *start++ = fill; if (sign) *(start - 1) = sign; } grow_buffer(n); return; } // If n is negative we ask to increase the capacity by at least 1, // but as std::vector, the buffer grows exponentially. buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1); } } /** \rst This template provides operations for formatting and writing data into a character stream. The output is stored in a memory buffer that grows dynamically. You can use one of the following typedefs for common character types and the standard allocator: +---------------+-----------------------------------------------+ | Type | Definition | +===============+===============================================+ | MemoryWriter | BasicWriter> | +---------------+-----------------------------------------------+ | WMemoryWriter | BasicWriter> | +---------------+-----------------------------------------------+ **Example**:: MemoryWriter out; out << "The answer is " << 42 << "\n"; out.write("({:+f}, {:+f})", -3.14, 3.14); This will write the following output to the ``out`` object: .. code-block:: none The answer is 42 (-3.140000, +3.140000) The output can be converted to an ``std::string`` with ``out.str()`` or accessed as a C string with ``out.c_str()``. \endrst */ template > class BasicMemoryWriter : public BasicWriter { private: internal::MemoryBuffer buffer_; public: explicit BasicMemoryWriter(const Allocator& alloc = Allocator()) : BasicWriter(buffer_), buffer_(alloc) {} #if FMT_USE_RVALUE_REFERENCES /** Constructs a ``BasicMemoryWriter`` object moving the content of the other object to it. */ BasicMemoryWriter(BasicMemoryWriter &&other) : BasicWriter(buffer_), buffer_(std::move(other.buffer_)) { } /** Moves the content of the other ``BasicMemoryWriter`` object to this one. */ BasicMemoryWriter &operator=(BasicMemoryWriter &&other) { buffer_ = std::move(other.buffer_); return *this; } #endif }; typedef BasicMemoryWriter MemoryWriter; typedef BasicMemoryWriter WMemoryWriter; // Formats a value. template void format(BasicFormatter &f, const Char *&format_str, const T &value) { std::basic_ostringstream os; os << value; internal::Arg arg; internal::Value &arg_value = arg; std::basic_string str = os.str(); arg_value = internal::MakeValue(str); arg.type = internal::Arg::STRING; format_str = f.format(format_str, arg); } // Reports a system error without throwing an exception. // Can be used to report errors from destructors. void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT(true); #ifdef _WIN32 /** A Windows error. */ class WindowsError : public SystemError { private: void init(int error_code, StringRef format_str, ArgList args); public: /** \rst Constructs a :cpp:class:`fmt::WindowsError` object with the description of the form "**: **", where ** is the formatted message and ** is the system message corresponding to the error code. *error_code* is a Windows error code as given by ``GetLastError``. \endrst */ WindowsError(int error_code, StringRef message) { init(error_code, message, ArgList()); } FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef) }; // Reports a Windows error without throwing an exception. // Can be used to report errors from destructors. void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT(true); #endif enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; /** Formats a string and prints it to stdout using ANSI escape sequences to specify color (experimental). Example: PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23; */ void print_colored(Color c, StringRef format, ArgList args); /** \rst Formats arguments and returns the result as a string. **Example**:: std::string message = format("The answer is {}", 42); \endrst */ inline std::string format(StringRef format_str, ArgList args) { MemoryWriter w; w.write(format_str, args); return w.str(); } inline std::wstring format(WStringRef format_str, ArgList args) { WMemoryWriter w; w.write(format_str, args); return w.str(); } /** \rst Prints formatted data to the file *f*. **Example**:: print(stderr, "Don't {}!", "panic"); \endrst */ void print(std::FILE *f, StringRef format_str, ArgList args); /** \rst Prints formatted data to ``stdout``. **Example**:: print("Elapsed time: {0:.2f} seconds", 1.23); \endrst */ void print(StringRef format_str, ArgList args); /** \rst Prints formatted data to the stream *os*. **Example**:: print(cerr, "Don't {}!", "panic"); \endrst */ void print(std::ostream &os, StringRef format_str, ArgList args); template void printf(BasicWriter &w, BasicStringRef format, ArgList args) { internal::PrintfFormatter().format(w, format, args); } /** \rst Formats arguments and returns the result as a string. **Example**:: std::string message = fmt::sprintf("The answer is %d", 42); \endrst */ inline std::string sprintf(StringRef format, ArgList args) { MemoryWriter w; printf(w, format, args); return w.str(); } /** \rst Prints formatted data to the file *f*. **Example**:: fmt::fprintf(stderr, "Don't %s!", "panic"); \endrst */ int fprintf(std::FILE *f, StringRef format, ArgList args); /** \rst Prints formatted data to ``stdout``. **Example**:: fmt::printf("Elapsed time: %.2f seconds", 1.23); \endrst */ inline int printf(StringRef format, ArgList args) { return fprintf(stdout, format, args); } /** Fast integer formatter. */ class FormatInt { private: // Buffer should be large enough to hold all digits (digits10 + 1), // a sign and a null character. enum {BUFFER_SIZE = std::numeric_limits::digits10 + 3}; mutable char buffer_[BUFFER_SIZE]; char *str_; // Formats value in reverse and returns the number of digits. char *format_decimal(ULongLong value) { char *buffer_end = buffer_ + BUFFER_SIZE - 1; while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. unsigned index = (value % 100) * 2; value /= 100; *--buffer_end = internal::DIGITS[index + 1]; *--buffer_end = internal::DIGITS[index]; } if (value < 10) { *--buffer_end = static_cast('0' + value); return buffer_end; } unsigned index = static_cast(value * 2); *--buffer_end = internal::DIGITS[index + 1]; *--buffer_end = internal::DIGITS[index]; return buffer_end; } void FormatSigned(LongLong value) { ULongLong abs_value = static_cast(value); bool negative = value < 0; if (negative) abs_value = 0 - abs_value; str_ = format_decimal(abs_value); if (negative) *--str_ = '-'; } public: explicit FormatInt(int value) { FormatSigned(value); } explicit FormatInt(long value) { FormatSigned(value); } explicit FormatInt(LongLong value) { FormatSigned(value); } explicit FormatInt(unsigned value) : str_(format_decimal(value)) {} explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {} explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {} /** Returns the number of characters written to the output buffer. */ std::size_t size() const { return buffer_ - str_ + BUFFER_SIZE - 1; } /** Returns a pointer to the output buffer content. No terminating null character is appended. */ const char *data() const { return str_; } /** Returns a pointer to the output buffer content with terminating null character appended. */ const char *c_str() const { buffer_[BUFFER_SIZE - 1] = '\0'; return str_; } /** Returns the content of the output buffer as an `std::string`. */ std::string str() const { return std::string(str_, size()); } }; // Formats a decimal integer value writing into buffer and returns // a pointer to the end of the formatted string. This function doesn't // write a terminating null character. template inline void format_decimal(char *&buffer, T value) { typename internal::IntTraits::MainType abs_value = value; if (internal::is_negative(value)) { *buffer++ = '-'; abs_value = 0 - abs_value; } if (abs_value < 100) { if (abs_value < 10) { *buffer++ = static_cast('0' + abs_value); return; } unsigned index = static_cast(abs_value * 2); *buffer++ = internal::DIGITS[index]; *buffer++ = internal::DIGITS[index + 1]; return; } unsigned num_digits = internal::count_digits(abs_value); internal::format_decimal(buffer, abs_value, num_digits); buffer += num_digits; } } #if FMT_GCC_VERSION // Use the system_header pragma to suppress warnings about variadic macros // because suppressing -Wvariadic-macros with the diagnostic pragma doesn't // work. It is used at the end because we want to suppress as little warnings // as possible. # pragma GCC system_header #endif // This is used to work around VC++ bugs in handling variadic macros. #define FMT_EXPAND(args) args // Returns the number of arguments. // Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s. #define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N()) #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__)) #define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N #define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 #define FMT_CONCAT(a, b) a##b #define FMT_FOR_EACH_(N, f, ...) \ FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) #define FMT_FOR_EACH(f, ...) \ FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__)) #define FMT_ADD_ARG_NAME(type, index) type arg##index #define FMT_GET_ARG_NAME(type, index) arg##index #if FMT_USE_VARIADIC_TEMPLATES # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ template \ ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ const Args & ... args) { \ using fmt::internal::Value; \ const Value values[fmt::internal::NonZero::VALUE] = { \ fmt::internal::MakeValue(args)... \ }; \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ fmt::internal::make_type(args...), values)); \ } #else // Defines a wrapper for a function taking __VA_ARGS__ arguments // and n additional arguments of arbitrary types. # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \ template \ inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ FMT_GEN(n, FMT_MAKE_ARG)) { \ const fmt::internal::Value vals[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), vals)); \ } # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \ call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \ } \ FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \ FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__) #endif // FMT_USE_VARIADIC_TEMPLATES /** \rst Defines a variadic function with the specified return type, function name and argument types passed as variable arguments to this macro. **Example**:: void print_error(const char *file, int line, const char *format, fmt::ArgList args) { fmt::print("{}: {}: ", file, line); fmt::print(format, args); } FMT_VARIADIC(void, print_error, const char *, int, const char *) ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that don't implement variadic templates. You don't have to use this macro if you don't need legacy compiler support and can use variadic templates directly:: template void print_error(const char *file, int line, const char *format, const Args & ... args) { fmt::print("{}: {}: ", file, line); fmt::print(format, args...); } \endrst */ #define FMT_VARIADIC(ReturnType, func, ...) \ FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) #define FMT_VARIADIC_W(ReturnType, func, ...) \ FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) namespace fmt { FMT_VARIADIC(std::string, format, StringRef) FMT_VARIADIC_W(std::wstring, format, WStringRef) FMT_VARIADIC(void, print, StringRef) FMT_VARIADIC(void, print, std::FILE *, StringRef) FMT_VARIADIC(void, print, std::ostream &, StringRef) FMT_VARIADIC(void, print_colored, Color, StringRef) FMT_VARIADIC(std::string, sprintf, StringRef) FMT_VARIADIC(int, printf, StringRef) FMT_VARIADIC(int, fprintf, std::FILE *, StringRef) } // Restore warnings. #if FMT_GCC_VERSION >= 406 # pragma GCC diagnostic pop #endif } // end generic namespace #endif // FMT_FORMAT_HPP_ davix-R_0_5_0/src/libs/alibxx/typeconv/000077500000000000000000000000001257152637300201435ustar00rootroot00000000000000davix-R_0_5_0/src/libs/alibxx/typeconv/typeconv.hpp000066400000000000000000000103211257152637300225200ustar00rootroot00000000000000#pragma once #include #include #include #include #include #include "typeconv_exception.hpp" #include "../base_types.hpp" namespace A_LIB_NAMESPACE{ namespace{ template void check_sign(Unsigned val, const std::string & orig_string){ if( val > static_cast(std::numeric_limits::max()) && orig_string.find('-') != std::string::npos){ throw TypeConvException("Negative value to unsigned value"); } } template DestType numerical_cast_safe(SourceType val){ if(val < static_cast(std::numeric_limits::min()) || val > static_cast(std::numeric_limits::max())){ throw TypeConvException("Overflow in numerical conversion"); } return static_cast(val); } template inline void check_overflow_integral(Integral val, int errcode){ if( (val == std::numeric_limits::min() || val ==std::numeric_limits::max()) && ( errcode == ERANGE || errcode == EINVAL)){ errno =0; throw TypeConvException("Overflow during type converstion from string to integral value"); } } inline void check_strto_error(char * end_str, const std::string & str){ if( str.size() ==0 || *end_str != '\0'){ errno =0; throw TypeConvException("Invalid type converstion from string to integral value"); } } } template struct toType{ T operator()(const S & val){ (void) val; throw TypeConvException("Invalid type converstion: no specialization"); } }; template <> struct toType{ unsigned long long operator()(const std::string & str){ char* end_str = NULL; errno =0; const unsigned long long ret = strtoull(str.c_str(), &end_str, 10); check_overflow_integral(ret, errno); check_strto_error(end_str,str); check_sign(ret, str); return ret; } }; template <> struct toType{ long long operator()(const std::string & str){ char* end_str = NULL; errno =0; const long long ret = strtoll(str.c_str(), &end_str, 10); check_overflow_integral(ret, errno); check_strto_error(end_str,str); return ret; } }; template <> struct toType{ unsigned long operator()(const std::string & str){ char* end_str = NULL; errno =0; const unsigned long ret = strtoul(str.c_str(), &end_str, 10); check_overflow_integral(ret, errno); check_strto_error(end_str,str); check_sign(ret, str); return ret; } }; template <> struct toType{ unsigned long operator()(const std::string & str){ char* end_str = NULL; errno =0; const long ret = strtol(str.c_str(), &end_str, 10); check_overflow_integral(ret, errno); check_strto_error(end_str,str); return ret; } }; template <> struct toType{ unsigned int operator()(const std::string & str){ char* end_str = NULL; errno =0; const unsigned long ret = strtoul(str.c_str(), &end_str, 10); check_overflow_integral(ret, errno); check_strto_error(end_str,str); check_sign(ret, str); return numerical_cast_safe(ret); } }; template <> struct toType{ int operator()(const std::string & str){ char* end_str = NULL; errno =0; const long ret = strtol(str.c_str(), &end_str, 10); check_overflow_integral(ret, errno); check_strto_error(end_str,str); return numerical_cast_safe(ret); } }; template struct toType{ std::string operator()(const S & val){ S ret; ss.str(""); ss << val; if(ss.fail()){ throw TypeConvException("Invalid type converstion from string to "); } return ret.str(); } std::ostringstream ss; }; } davix-R_0_5_0/src/libs/alibxx/typeconv/typeconv_exception.hpp000066400000000000000000000005461257152637300246060ustar00rootroot00000000000000#pragma once #include namespace A_LIB_NAMESPACE{ class TypeConvException: public std::exception{ public: TypeConvException(const std::string & str) : message(str){} virtual ~TypeConvException() throw(){} virtual const char* what() const throw(){ return message.c_str(); } private: std::string message; }; } davix-R_0_5_0/src/libs/containers/000077500000000000000000000000001257152637300171525ustar00rootroot00000000000000davix-R_0_5_0/src/libs/containers/Adevpp.h000066400000000000000000000033731257152637300205500ustar00rootroot00000000000000#ifndef alibxx_CACHE_H #define alibxx_CACHE_H #include #include #include #include #include #include #include namespace alibxx{ template > class Cache { typedef std::map > Map; typedef boost::shared_ptr shrPtr_type; public: Cache() : cmp(CompareT()), map(cmp){} shrPtr_type insert(const Key & key, T* value){ return insert(key, shrPtr_type(value)); } shrPtr_type insert(const Key & key, const shrPtr_type & value){ boost::lock_guard l(m); Map::iterator it = map.find( key); if(it == Map::end()) return map.insert(std::pair (key, value) ).second; it->second = value; return value; } shrPtr_type find(const Key & key){ boost::lock_guard l(m); Map::iterator it = map.find( key); if(it == Map::end()) return shrPtr_type(); return *it; } size_t getSize() const{ boost::lock_guard l(m); return map.size(); } shrPtr_type take( const Key & key){ boost::lock_guard l(m); Map::iterator it = map.find( key); if(it == Map::end()) return shrPtr_type(); map.erase(key); return *it; } bool erase( const Key & key){ boost::lock_guard l(m); return ( map.erase(key) != 0); } void clear(){ boost::lock_guard l(m); map.clear(); } private: CompareT cmp; Map map; boost::mutex m; }; } #endif // alibxx_H davix-R_0_5_0/src/libs/containers/CMakeLists.txt000066400000000000000000000002201257152637300217040ustar00rootroot00000000000000# libs CMakefile for third party deps FILE(GLOB _src_vector_chunk "vector_chunk*") SET(src_vector_chunk ${_src_vector_chunk} PARENT_SCOPE) davix-R_0_5_0/src/libs/datetime/000077500000000000000000000000001257152637300166015ustar00rootroot00000000000000davix-R_0_5_0/src/libs/datetime/CMakeLists.txt000066400000000000000000000001551257152637300213420ustar00rootroot00000000000000# main file for src FILE(GLOB _src_datetime "*.cpp") SET(src_datetime ${_src_datetime} PARENT_SCOPE) davix-R_0_5_0/src/libs/datetime/datetime_utils.cpp000066400000000000000000000060041257152637300223210ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "datetime_utils.hpp" time_t parse_http_date(const char* http_date){ // TODO : possible issue with timezone != GMT, static const char rfc1123[] = "%a, %d %b %Y %H:%M:%S GMT"; struct tm tm; memset(&tm,0, sizeof(struct tm)); const char * p = strptime(http_date, rfc1123, &tm); if ( p == NULL || *p != '\0'){ return -1; } return mktime(&tm) - timezone;; } time_t parse_iso8601date(const char* iso_date){ // TODO : refactor to a regex parser.. ISO8601 b******* is impossible to parse correctly with strptime struct tm tm_time; char* p, *end_p; memset(&tm_time,0, sizeof(struct tm )); if( ( (p = strptime(iso_date, "%Y-%m-%dT%H:%M:%SZ", &tm_time) ) == NULL || *p != '\0') && ( (p = strptime(iso_date, "%Y-%m-%dT%H:%M:%S", &tm_time) ) == NULL || *p != '.' || *(iso_date + strlen(iso_date) -1) != 'Z' )){ if( (p = strptime(iso_date, "%Y-%m-%dT%H:%M:%S", &tm_time) ) != NULL && (*p == '+' || *p == '-') ){ struct tm tm_time_offset; memset(&tm_time_offset,0, sizeof(struct tm )); if( ( ( end_p= strptime(p+1, "%H:%M", &tm_time_offset)) == NULL || *end_p != '\0' ) && ( (end_p =strptime(p+1, "%H%M", &tm_time_offset)) == NULL || *end_p != '\0' ) ) return -1; if( *p =='+'){ tm_time.tm_hour += tm_time_offset.tm_hour; tm_time.tm_min += tm_time_offset.tm_min; } else{ tm_time.tm_hour -= tm_time_offset.tm_hour; tm_time.tm_min -= tm_time_offset.tm_min; } }else{ return -1; } } return mktime(&tm_time) - timezone; } time_t parse_standard_date(const char* http_date){ if(strchr(http_date, ',') != NULL){ // detect if rfc date or iso8601 date return parse_http_date(http_date); }else{ return parse_iso8601date(http_date); } } davix-R_0_5_0/src/libs/datetime/datetime_utils.hpp000066400000000000000000000032741257152637300223340ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) 2013 Adrien Devresse , CERN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DATETIME_UTILS_HPP #define DATETIME_UTILS_HPP #include #include #define DATETIME_UTILS_PARSE_ERROR 1 #define DATETIME_UTILS_CONV_ERROR 2 /** parse an http standard date to a posix time @param http_date http string of the date @return posix time or -1 if error occures */ time_t parse_http_date(const char* http_date); /** parse a iso 8601 date to a posix time @param iso8601_date http string of the date @param err : Gerror error report system @return posix time or -1 if error occures and err is set */ time_t parse_iso8601date(const char* http_date); /** parse both of iso 8601 and http standard date to a posix time @param http or iso8601 date @return posix time or -1 if error occures */ time_t parse_standard_date(const char* http_date); #endif // DATETIME_UTILS_HPP davix-R_0_5_0/src/libs/time_utils.h000066400000000000000000000035171257152637300173420ustar00rootroot00000000000000#pragma once #ifndef _TIME_UTILS_H #define _TIME_UTILS_H /** similar to timeradd, timercmp, etc... function but for timerspec */ #define timespec_cmp(a, b, CMP) \ (((a)->tv_sec == (b)->tv_sec) ? \ ((a)->tv_nsec CMP (b)->tv_nsec) : \ ((a)->tv_sec CMP (b)->tv_sec)) #define timespec_add(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \ if ((result)->tv_nsec > 1000000000) { \ ++(result)->tv_sec; \ (result)->tv_nsec -= 1000000000; \ } \ } while (0) #define timespec_clear(a) \ do { \ (a)->tv_sec = 0; \ (a)->tv_nsec = 0; \ } while (0) #define timespec_isset(a) \ ( ((a)->tv_sec != 0 || (a)->tv_nsec != 0) ) #define timespec_copy(a,b) \ do { \ (a)->tv_sec = (b)->tv_sec; \ (a)->tv_nsec = (b)->tv_nsec; \ } while (0) #endif davix-R_0_5_0/src/modules/000077500000000000000000000000001257152637300155245ustar00rootroot00000000000000davix-R_0_5_0/src/modules/copy/000077500000000000000000000000001257152637300164765ustar00rootroot00000000000000davix-R_0_5_0/src/modules/copy/CMakeLists.txt000066400000000000000000000074111257152637300212410ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.6) IF (ENABLE_THIRD_PARTY_COPY) INCLUDE (CheckLibraryExists) pkg_check_modules(GSOAP_SSL_PKG REQUIRED "gsoapssl++") FIND_PACKAGE(gSOAP REQUIRED) MESSAGE(STATUS "Using gsoapssl flags ${GSOAP_SSL_PKG_CFLAGS}") # Compile the WSDL for 1.1.0 ADD_CUSTOM_COMMAND (OUTPUT typemap.dat COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/delegation/typemap.dat ${CMAKE_CURRENT_BINARY_DIR}/typemap.dat) ADD_CUSTOM_COMMAND ( OUTPUT delegation1.h COMMAND ${GSOAP_WSDL2H} -j -s -I/usr/share/gsoap/import/ -o${CMAKE_CURRENT_BINARY_DIR}/delegation1.h ${CMAKE_CURRENT_SOURCE_DIR}/delegation/delegation-1.1.0.wsdl -qdelegation1 DEPENDS typemap.dat) ADD_CUSTOM_COMMAND ( OUTPUT delegation1C.cpp delegation1Client.cpp COMMAND ${GSOAP_SOAPCPP2} -L -C -x -w -I/usr/share/gsoap/import/ ${CMAKE_CURRENT_BINARY_DIR}/delegation1.h -pdelegation1 -qdelegation1 DEPENDS delegation1.h) # Compile the WSDL for 2.0.0 ADD_CUSTOM_COMMAND ( OUTPUT delegation2.h COMMAND ${GSOAP_WSDL2H} -j -s -I/usr/share/gsoap/import/ -o${CMAKE_CURRENT_BINARY_DIR}/delegation2.h ${CMAKE_CURRENT_SOURCE_DIR}/delegation/delegation-2.0.0.wsdl -qdelegation2 DEPENDS typemap.dat) ADD_CUSTOM_COMMAND ( OUTPUT delegation2C.cpp delegation2Client.cpp COMMAND ${GSOAP_SOAPCPP2} -C -x -w -I/usr/share/gsoap/import/ ${CMAKE_CURRENT_BINARY_DIR}/delegation2.h -n DEPENDS delegation2.h) # Need to generate some utility functions in the global namespace ADD_CUSTOM_COMMAND (OUTPUT env.h COMMAND touch env.h) ADD_CUSTOM_COMMAND (OUTPUT envC.cpp COMMAND ${GSOAP_SOAPCPP2} ${CMAKE_CURRENT_BINARY_DIR}/env.h -penv DEPENDS env.h) # Includes INCLUDE_DIRECTORIES (${CMAKE_CURRENT_BINARY_DIR} ${GSOAP_INCLUDE_DIR}) # link LINK_DIRECTORIES( ${DAVIX_PKG_LIBRARY_DIRS}) ADD_DEFINITIONS(${GSOAP_SSL_PKG_CFLAGS}) # Build third party copy as a static library FILE(GLOB src_copy "*.cpp") FILE(GLOB src_dlg "delegation/*.cpp") ADD_LIBRARY (davix_copy SHARED ${src_copy} ${src_dlg} ${CMAKE_CURRENT_BINARY_DIR}/delegation1C.cpp ${CMAKE_CURRENT_BINARY_DIR}/delegation1Client.cpp ${CMAKE_CURRENT_BINARY_DIR}/delegation2C.cpp ${CMAKE_CURRENT_BINARY_DIR}/delegation2Client.cpp ${CMAKE_CURRENT_BINARY_DIR}/envC.cpp) TARGET_LINK_LIBRARIES(davix_copy libdavix ${GSOAP_SSL_PKG_LIBRARIES} z) SET_TARGET_PROPERTIES(davix_copy PROPERTIES VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} SOVERSION ${VERSION_MAJOR} CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "davix_copy") INSTALL(TARGETS davix_copy DESTINATION ${LIB_INSTALL_DIR}) add_PkgConfigFile_for_Library("davix_copy.pc" davix_copy HEADER_DIRS "davix" CFLAGS " -D_FILE_OFFSET_BITS=64 " DESCRIPTION "Davix, High level WebDav/HTTP library. Third party copy library." ) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/davix_copy.pc DESTINATION ${PKGCONFIG_FILES_DIR}) ENDIF (ENABLE_THIRD_PARTY_COPY) davix-R_0_5_0/src/modules/copy/copy.cpp000066400000000000000000000273471257152637300201710ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 "copy_internal.hpp" #include "delegation/delegation.hpp" #include using namespace Davix; const std::string COPY_SCOPE = "Davix::HttpThirdPartyCopy"; // Gets the real location of uri respect to ref // uri can be absolute or relative to ref static std::string _full_url(const std::string ref, const std::string& uri) { std::string final; if (uri.find("://") != std::string::npos) { final = uri; } else if (uri[0] == '/') { size_t colon = ref.find(':'); size_t slash = std::string::npos; if (colon != std::string::npos) slash = ref.find('/', colon + 3); if (slash != std::string::npos) { std::string base = ref.substr(0, slash); final = base + uri; } } else { final = ref + uri; } return final; } // Same as _full_url, but it makes sure // that the destination is https static std::string _full_delegation_endpoint(const std::string& ref, const std::string& uri, DavixError** err) { std::string final = _full_url(ref, uri); if (final.substr(7).compare("http://") == 0) { DavixError::setupError(err, COPY_SCOPE, StatusCode::OperationNonSupported, std::string("Plain http can not be used for delegation: ") + uri); final.clear(); } return final; } DavixCopy::DavixCopy(Context &c, const RequestParams *params): d_ptr(NULL) { d_ptr = new DavixCopyInternal(c, params); } DavixCopy::~DavixCopy() { delete d_ptr; } void DavixCopy::copy(const Uri &source, const Uri &destination, unsigned nstreams, DavixError **error) { d_ptr->copy(source, destination, nstreams, error); } void DavixCopy::setPerformanceCallback(PerformanceCallback callback, void *udata) { d_ptr->setPerformanceCallback(callback, udata); } void DavixCopyInternal::setPerformanceCallback(DavixCopy::PerformanceCallback callback, void *udata) { perfCallback = callback; perfCallbackUdata = udata; } void DavixCopyInternal::copy(const Uri &src, const Uri &dst, unsigned nstreams, DavixError **error) { //std::string nextSrc(src.getString()), prevSrc(src.getString()); //std::string destination(dst.getString()); std::string nextSrc, prevSrc, destination; std::string delegationEndpoint; DavixError *internalError = NULL; bool isS3endpoint = false; // set source and destination according to copy method if(parameters->getCopyMode() == CopyMode::Push){ nextSrc = src.getString(); prevSrc = src.getString(); destination = dst.getString(); }else if(parameters->getCopyMode() == CopyMode::Pull){ nextSrc = dst.getString(); prevSrc = dst.getString(); destination = src.getString(); } // nstreams as string char nstreamsStr[16]; snprintf(nstreamsStr, sizeof(nstreamsStr), "%u", nstreams); // Need a copy so we can modify it Davix::RequestParams requestParams(parameters); requestParams.setTransparentRedirectionSupport(false); size_t start_pos; // if destination is s3 endpoint, change prefix to http(s) and pre-sign the request as a PUT if(destination.compare(0,2,"s3") == 0){ destination.replace(0, 2, "http"); time_t expiration_time = time(NULL) +3600; Davix::HeaderVec vec; Uri tmp; if (parameters->getCopyMode() == CopyMode::Pull) tmp = Davix::S3::tokenizeRequest(requestParams, "GET", destination, vec, expiration_time); else tmp = Davix::S3::tokenizeRequest(requestParams, "PUT", destination, vec, expiration_time); destination = tmp.getString(); isS3endpoint = true; } // Perform COPY hopping through redirections HttpRequest* request = NULL; do { nextSrc = _full_url(prevSrc, nextSrc); prevSrc = nextSrc; if (request) { request->discardBody(&internalError); if (!internalError) request->endRequest(&internalError); if (internalError) { DavixError::propagatePrefixedError(error, internalError, __func__); break; } } delete request; DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Hop: {}", nextSrc); request = context.createRequest(nextSrc, &internalError); if (internalError) { DavixError::propagatePrefixedError(error, internalError, __func__); break; } request->setRequestMethod("COPY"); if(parameters->getCopyMode() == CopyMode::Push){ request->addHeaderField("Destination", destination); }else if(parameters->getCopyMode() == CopyMode::Pull){ request->addHeaderField("Source", destination); } request->addHeaderField("X-Number-Of-Streams", nstreamsStr); // for lcgdm-dav, ask for secure redirection in all cases for COPY request->addHeaderField("Secure-Redirection", "1"); // for lcgdm-dav -> S3, add NoHead flag to suppress final head-to-close request if(isS3endpoint) request->addHeaderField("Copy-Flags", "NoHead"); request->setParameters(requestParams); request->beginRequest(&internalError); if (internalError) { DavixError::propagatePrefixedError(error, internalError, __func__); break; } // If we get a X-Delegate-To, before continuing, delegate if (request->getAnswerHeader("X-Delegate-To", delegationEndpoint)) { delegationEndpoint = _full_delegation_endpoint(nextSrc, delegationEndpoint, &internalError); if (internalError) { DavixError::propagatePrefixedError(error, internalError, __func__); break; } DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Got delegation endpoint: {}", delegationEndpoint.c_str()); std::string dlg_id = DavixDelegation::delegate(context, delegationEndpoint, parameters, &internalError); if (internalError) { DavixError::propagatePrefixedError(error, internalError, __func__); break; } DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Got delegation ID {}", dlg_id.c_str()); dlg_id.clear(); } } while (request->getAnswerHeader("Location", nextSrc)); if (!*error) { int responseStatus = request->getRequestCode(); if (responseStatus == 404) { DavixError::setupError(error, COPY_SCOPE, StatusCode::FileNotFound, "Could not COPY. File not found"); } else if (responseStatus == 403) { DavixError::setupError(error, COPY_SCOPE, StatusCode::PermissionRefused, "Could not COPY. Permission denied."); } else if (responseStatus == 501) { DavixError::setupError(error, COPY_SCOPE, StatusCode::OperationNonSupported, "Could not COPY. The source service does not support it"); } else if (responseStatus >= 405) { DavixError::setupError(error, COPY_SCOPE, StatusCode::OperationNonSupported, "Could not COPY. The source service does not allow it"); } else if (responseStatus == 400) { std::string err_msg(request->getAnswerContentVec().begin(), request->getAnswerContentVec().end()); DavixError::setupError(error, COPY_SCOPE, StatusCode::InvalidArgument, fmt::format("Could not COPY. The server rejected the request: {}", err_msg)); } else if (responseStatus >= 300) { std::ostringstream msg; msg << "Could not COPY. Unknown error code: " << responseStatus; DavixError::setupError(error, COPY_SCOPE, StatusCode::UnknowError, msg.str()); } } // Did we fail? if (*error) return; // Finished hopping std::string finalSource = nextSrc; // Just wait for it to finish monitorPerformanceMarkers(request, error); request->endRequest(error); delete request; } void DavixCopyInternal::monitorPerformanceMarkers(Davix::HttpRequest *request, Davix::DavixError **error) { Davix::DavixError* daverr = NULL; char buffer[1024], *p; dav_ssize_t line_len; PerformanceMarker holder; PerformanceData performance; time_t lastPerfCallback = time(NULL); while ((line_len = request->readLine(buffer, sizeof(buffer), &daverr)) >= 0 && !daverr) { buffer[line_len] = '\0'; if (line_len > 0) DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Received: {}", buffer); // Skip heading whitespaces p = buffer; while (*p && p < buffer + sizeof(buffer) && isspace(*p)) ++p; if (strncasecmp("Perf Marker", p, 11) == 0) { memset(&holder, 0, sizeof(holder)); } else if (strncasecmp("Timestamp:", p, 10) == 0) { holder.latest = atol(p + 10); } else if (strncasecmp("Stripe Index:", p, 13) == 0) { holder.index = atoi(p + 13); } else if (strncasecmp("Stripe Bytes Transferred:", p, 25) == 0) { holder.transferred = atol(p + 26); } else if (strncasecmp("Total Stripe Count:", p, 19) == 0) { holder.count = atoi(p + 20); } else if (strncasecmp("End", p, 3) == 0) { performance.update(holder); time_t now = time(NULL); if (now - lastPerfCallback >= 1) { if (this->perfCallback) this->perfCallback(performance, this->perfCallbackUdata); lastPerfCallback = now; } } else if (strncasecmp("success", p, 7) == 0) { break; } else if (strncasecmp("aborted", p, 7) == 0) { Davix::DavixError::setupError(error, COPY_SCOPE, StatusCode::Canceled, "Transfer aborted in the remote end"); break; } else if (strncasecmp("failed", p, 6) == 0 || strncasecmp("failure", p, 7) == 0) { Davix::DavixError::setupError(error, COPY_SCOPE, StatusCode::RemoteError, std::string("Transfer failed: ") + p); break; } else if(line_len> 0) { DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_GRID, "Unknown performance marker, ignoring: {}", buffer); } } } davix-R_0_5_0/src/modules/copy/copy_internal.hpp000066400000000000000000000036111257152637300220560ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_COPY_INTERNAL_HPP #define DAVIX_COPY_INTERNAL_HPP #include extern const std::string COPY_SCOPE; // Internal struct to hold data class Davix::DavixCopyInternal { public: DavixCopyInternal(Davix::Context& ctx, const Davix::RequestParams *params): context(ctx), parameters(params), perfCallback(NULL), perfCallbackUdata(NULL) { } void copy(const Davix::Uri &source, const Davix::Uri &destination, unsigned nstreams, Davix::DavixError **error); void setPerformanceCallback(DavixCopy::PerformanceCallback callback, void *udata); protected: Davix::Context &context; const Davix::RequestParams *parameters; DavixCopy::PerformanceCallback perfCallback; void *perfCallbackUdata; void monitorPerformanceMarkers(Davix::HttpRequest *request, Davix::DavixError **error); private: DavixCopyInternal(const DavixCopyInternal&); DavixCopyInternal& operator = (const DavixCopyInternal&); }; #endif //DAVIX_COPY_INTERNAL_HPP davix-R_0_5_0/src/modules/copy/delegation/000077500000000000000000000000001257152637300206115ustar00rootroot00000000000000davix-R_0_5_0/src/modules/copy/delegation/GRSTx509MakeProxyCert.cpp000066400000000000000000000306411257152637300252040ustar00rootroot00000000000000/* Copyright (c) 2002-7, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: o Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. o 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. --------------------------------------------------------------- For more information about GridSite: http://www.gridsite.org/ --------------------------------------------------------------- */ #include #include #include #include #include "GRSTx509MakeProxyCert.h" #define GRST_BACKDATE_SECONDS 300 #define GRST_PROXYCERTINFO_OID "1.3.6.1.5.5.7.1.14" #define GRST_KEYUSAGE_OID "2.5.29.15" static void mpcerror(FILE *debugfp, const char *msg) { if (debugfp != NULL) { fputs(msg, debugfp); ERR_print_errors_fp(debugfp); } } static time_t GRSTasn1TimeToTimeT(const unsigned char *asn1time, size_t len) { char zone; struct tm time_tm; if (len == 0) len = strlen((const char*)asn1time); if ((len != 13) && (len != 15)) return 0; /* dont understand */ if ((len == 13) && ((sscanf((const char*)asn1time, "%02d%02d%02d%02d%02d%02d%c", &(time_tm.tm_year), &(time_tm.tm_mon), &(time_tm.tm_mday), &(time_tm.tm_hour), &(time_tm.tm_min), &(time_tm.tm_sec), &zone) != 7) || (zone != 'Z'))) return 0; /* dont understand */ if ((len == 15) && ((sscanf((const char*)asn1time, "20%02d%02d%02d%02d%02d%02d%c", &(time_tm.tm_year), &(time_tm.tm_mon), &(time_tm.tm_mday), &(time_tm.tm_hour), &(time_tm.tm_min), &(time_tm.tm_sec), &zone) != 7) || (zone != 'Z'))) return 0; /* dont understand */ /* time format fixups */ if (time_tm.tm_year < 90) time_tm.tm_year += 100; --(time_tm.tm_mon); return timegm(&time_tm); } int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, char *reqtxt, char *cert, char *key, int minutes) /// /// The proxy chain is returned in *proxychain. If debugfp is non-NULL, /// errors are output to that file pointer. The proxy will expired in /// the given number of minutes starting from the current time. { char *ptr, *certchain, s[41]; static unsigned char pci_str[] = { 0x30, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x01, 0 }, kyu_str[] = { 0x03, 0x02, 0x03, X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_KEY_ENCIPHERMENT | X509v3_KU_KEY_AGREEMENT, 0 }; int i, ncerts, any_rfc_proxies = 0; long serial = 1234, ptrlen; EVP_PKEY *pkey, *CApkey; const EVP_MD *digest; X509 **certs = NULL; X509_REQ *req; X509_NAME *name, *CAsubject, *newsubject; X509_NAME_ENTRY *ent; ASN1_OBJECT *pci_obj = NULL, *kyu_obj; ASN1_OCTET_STRING *pci_oct, *kyu_oct; X509_EXTENSION *pci_ex, *kyu_ex; FILE *fp; BIO *reqmem, *certmem; time_t notAfter; /* read in the request */ reqmem = BIO_new(BIO_s_mem()); BIO_puts(reqmem, reqtxt); if (!(req = PEM_read_bio_X509_REQ(reqmem, NULL, NULL, NULL))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error reading request from BIO memory\n"); BIO_free(reqmem); return GRST_RET_FAILED; } BIO_free(reqmem); /* verify signature on the request */ if (!(pkey = X509_REQ_get_pubkey(req))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error getting public key from request\n"); X509_REQ_free(req); return GRST_RET_FAILED; } if (X509_REQ_verify(req, pkey) != 1) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error verifying signature on certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* read in the signing certificate */ if (!(fp = fopen(cert, "r"))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error opening signing certificate file\n"); X509_REQ_free(req); return GRST_RET_FAILED; } ncerts = 1; while (1) { certs = (X509 **) realloc(certs, (sizeof(X509 *)) * (ncerts+1)); if (certs == NULL) mpcerror(debugfp, "GRSTx509MakeProxyCert(): no memory\n"); if ((certs[ncerts] = PEM_read_X509(fp, NULL, NULL, NULL)) == NULL) break; ncerts++; } if (ncerts == 1) /* zeroth cert with be new proxy cert */ { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error reading signing certificate file\n"); X509_REQ_free(req); return GRST_RET_FAILED; } fclose(fp); fp = NULL; CAsubject = X509_get_subject_name(certs[1]); /* read in the CA private key */ if (!(fp = fopen(key, "r"))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error reading signing private key file\n"); X509_REQ_free(req); return GRST_RET_FAILED; } if (!(CApkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error reading signing private key in file\n"); X509_REQ_free(req); return GRST_RET_FAILED; } fclose(fp); /* get subject name */ if (!(name = X509_REQ_get_subject_name(req))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error getting subject name from request\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* create new certificate */ if (!(certs[0] = X509_new())) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error creating X509 object\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* set version number for the certificate (X509v3) and the serial number We now use 2 = v3 for the GSI proxy, rather than the old Globus behaviour of 3 = v4. See Savannah Bug #53721 */ if (X509_set_version(certs[0], 2L) != 1) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error setting certificate version\n"); X509_REQ_free(req); return GRST_RET_FAILED; } ASN1_INTEGER_set(X509_get_serialNumber(certs[0]), (long) time(NULL)); if (!(name = X509_get_subject_name(certs[1]))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error getting subject name from CA certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } if (X509_set_issuer_name(certs[0], name) != 1) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error setting issuer name of certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* set public key in the certificate */ if (X509_set_pubkey(certs[0], pkey) != 1) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error setting public key of the certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* set duration for the certificate */ if (!(X509_gmtime_adj(X509_get_notBefore(certs[0]), -GRST_BACKDATE_SECONDS))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error setting beginning time of the certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } if (!(X509_gmtime_adj(X509_get_notAfter(certs[0]), 60 * minutes))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error setting ending time of the certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* go through chain making sure this proxy is not longer lived */ pci_obj = OBJ_txt2obj(GRST_PROXYCERTINFO_OID, 0); notAfter = GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[0])), 0); for (i=1; i < ncerts; ++i) { if (notAfter > GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[i])), 0)) { notAfter = GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter(certs[i])), 0); ASN1_UTCTIME_set(X509_get_notAfter(certs[0]), notAfter); } if (X509_get_ext_by_OBJ(certs[i], pci_obj, -1) > 0) any_rfc_proxies = 1; } /* if any earlier proxies are RFC 3820, then new proxy must be an RFC 3820 proxy too with the required extensions */ if (any_rfc_proxies) { /* key usage */ kyu_obj = OBJ_txt2obj(GRST_KEYUSAGE_OID, 0); kyu_ex = X509_EXTENSION_new(); X509_EXTENSION_set_object(kyu_ex, kyu_obj); ASN1_OBJECT_free(kyu_obj); X509_EXTENSION_set_critical(kyu_ex, 1); kyu_oct = ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(kyu_oct, kyu_str, strlen((const char*)kyu_str)); X509_EXTENSION_set_data(kyu_ex, kyu_oct); ASN1_OCTET_STRING_free(kyu_oct); X509_add_ext(certs[0], kyu_ex, -1); X509_EXTENSION_free(kyu_ex); /* proxy certificate info */ pci_ex = X509_EXTENSION_new(); X509_EXTENSION_set_object(pci_ex, pci_obj); X509_EXTENSION_set_critical(pci_ex, 1); pci_oct = ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(pci_oct, pci_str, strlen((const char*)pci_str)); X509_EXTENSION_set_data(pci_ex, pci_oct); ASN1_OCTET_STRING_free(pci_oct); X509_add_ext(certs[0], pci_ex, -1); X509_EXTENSION_free(pci_ex); } ASN1_OBJECT_free(pci_obj); /* set issuer and subject name of the cert from the req and the CA */ if (any_rfc_proxies) /* user CN=number rather than CN=proxy */ { snprintf(s, sizeof(s), "%ld", (long) time(NULL)); ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("commonName"), MBSTRING_ASC, (unsigned char*)s, -1); } else ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("commonName"), MBSTRING_ASC, (unsigned char*)"proxy", -1); newsubject = X509_NAME_dup(CAsubject); X509_NAME_add_entry(newsubject, ent, -1, 0); if (X509_set_subject_name(certs[0], newsubject) != 1) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error setting subject name of certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } X509_NAME_free(newsubject); X509_NAME_ENTRY_free(ent); /* sign the certificate with the signing private key */ if (EVP_PKEY_type(CApkey->type) == EVP_PKEY_RSA) digest = EVP_md5(); else { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error checking signing private key for a valid digest\n"); X509_REQ_free(req); return GRST_RET_FAILED; } if (!(X509_sign(certs[0], CApkey, digest))) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error signing certificate\n"); X509_REQ_free(req); return GRST_RET_FAILED; } /* store the completed certificate chain */ certchain = strdup(""); for (i=0; i < ncerts; ++i) { certmem = BIO_new(BIO_s_mem()); if (PEM_write_bio_X509(certmem, certs[i]) != 1) { mpcerror(debugfp, "GRSTx509MakeProxyCert(): error writing certificate to memory BIO\n"); X509_REQ_free(req); return GRST_RET_FAILED; } ptrlen = BIO_get_mem_data(certmem, &ptr); certchain = (char*)realloc(certchain, strlen((const char*)certchain) + ptrlen + 1); strncat(certchain, ptr, ptrlen); BIO_free(certmem); X509_free(certs[i]); } if (certs) free (certs); EVP_PKEY_free(pkey); EVP_PKEY_free(CApkey); X509_REQ_free(req); *proxychain = certchain; return GRST_RET_OK; } davix-R_0_5_0/src/modules/copy/delegation/GRSTx509MakeProxyCert.h000066400000000000000000000037731257152637300246570ustar00rootroot00000000000000/* Copyright (c) 2002-7, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: o Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. o 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. --------------------------------------------------------------- For more information about GridSite: http://www.gridsite.org/ --------------------------------------------------------------- */ #ifndef GRST_X509_MAKE_PROXY_CERT_HPP #define GRST_X509_MAKE_PROXY_CERT_HPP // Everything ok (= OpenSSL X509_V_OK) #define GRST_RET_OK 0 // Failed for unspecified reason #define GRST_RET_FAILED 1000 /** Extracted from Gridsite (prior to canl-c) to avoid unnecessary dependencies */ int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, char *reqtxt, char *cert, char *key, int minutes); #endif davix-R_0_5_0/src/modules/copy/delegation/delegation-1.1.0.wsdl000066400000000000000000000507021257152637300242560ustar00rootroot00000000000000 The cause of the delegation exception on the server side. New proxy certificate request, containing the certificate request and a generated delegation ID. The new RFC 3280 style proxy certificate request in PEM format with Base64 encoding. The ID associated with the new delegation session. The ID of the new delegation session, specified by the client. The ID can be empty. The new RFC 3280 style proxy certificate request in PEM format with Base64 encoding. The ID of an already existing delegation session, initiated by getProxyReq() or getNewProxyReq(). RFC 3280 style proxy certificate, signed by the client, in PEM format with Base64 encoding. The ID of an already existing delegation session, where the client wants to renew the delegated credential. The new RFC 3280 style proxy certificate request, which is to replace the existing one, in PEM format with Base64 encoding. The server side generated ID of the new delegation session and the new RFC 3280 style proxy certificate request in PEM format with Base64 encoding. The ID of an already existing delegation session to be queried. The date and time when the delegated credentials will expire. The ID of an already existing delegation session to be destroyed. Delegation interface. Starts the delegation procedure by asking for a certificate signing request from the server. The server answers with a certificate signing request which includes the public key for the new delegated credentials. putProxy() has to be called to finish the procedure. Check if a delegation ID was provided. If not, generate a delegation id by hashing the client DN and client VOMS attributes. Check if the delegation ID already exists in the storage-area. If it does (a credential renewal is happening), check existing info (DN and VOMS attributes) against client info. Throw exception if they do not match. Create a new private/public key-pair (see also Key Generation Semantics). Generate a new proxy certificate request. Store private key and cert request in storage-cache-area, along with the requesting DN and VOMS attributes. The client's DN and VOMS attributes do not match the stored ones, i.e. the client is not authorized. Starts the delegation procedure by asking for a certificate signing request from the server. The server answers with a certificate signing request which includes the public key for the new delegated credentials. putProxy() has to be called to finish the procedure. Generate a delegation ID by hashing the client DN and client VOMS attributes. Check if the delegation ID already exists in the storage-area. If it does, check existing info (DN and VOMS attributes) against client info. Throw exception if they do not match, because then this is the rare case of hash collision, i.e. two different clients are mapped to the same delegation ID. Create a new private/public key-pair (see also Key Generation Semantics). Generate a new certificate request. Store private key and cert request in storage-cache-area, along with the requesting DN and VOMS attributes. There were already credentials associated to the delegation ID. Finishes the delegation procedure by sending the signed proxy certificate to the server. Check if a delegation ID was provided. If not, generate a delegation id by hashing the client DN and client VOMS attributes. Check if the delegation ID already exists in the storage-area. If it does, check existing info (DN and VOMS attributes) against client info. Throw exception if it does not match. Check, if client information matches proxy information. Check given proxy against private key of delegation ID in storage-cache-area. If they do not match, throw exception. Store proxy in storage-area and clean up the storage-cache-area. There were no cached credentials associated to the delegation ID (neither getNewProxyReq() nor renewProxyReq() was called previously), or the client's DN and VOMS attributes do not match the stored ones, i.e. the client is not authorized. Restarts the delegation procedure by asking for a certificate signing request from the server for an already existing delegation ID. The server answers with a certificate signing request which includes the public key for new delegated credentials. putProxy() has to be called to finish the procedure. Check if a delegation ID was provided. If not, generate a delegation id by hashing the client DN and client VOMS attributes. Check if the delegation ID already exists in the storage-area. If it does not, then throw an exception. Check if the existing info (DN and VOMS attributes) against client info. Throw exception if they do not match. Create a new private/public key-pair (see also Key Generation Semantics). Generate a new certificate request. Store private key and cert request in storage-cache-area, along with the requesting DN and VOMS attributes. There were no credentials associated to the delegation ID, or the client's DN and VOMS attributes do not match the stored ones, i.e. the client is not authorized. Returns the termination (expiration) date and time of the credential, associated with the given delegaion ID. If there was no delegation ID, then generate one by hashing the client DN and client VOMS attributes. There were no credentials associated to the delegation ID, or the client's DN and VOMS attributes do not match the stored ones, i.e. the client is not authorized. Destroys the delegated credentials associated with the given delegation ID immediately. If there was no delegation ID, then generate one by hashing the client DN and client VOMS attributes. There were no credentials associated to the delegation ID, or the client's DN and VOMS attributes do not match the stored ones, i.e. the client is not authorized. davix-R_0_5_0/src/modules/copy/delegation/delegation-2.0.0.wsdl000066400000000000000000000312351257152637300242560ustar00rootroot00000000000000 davix-R_0_5_0/src/modules/copy/delegation/delegation.cpp000066400000000000000000000214321257152637300234320ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 "delegation2H.h" #include "delegation.hpp" #include "../auth/davixx509cred_internal.hpp" #include using namespace Davix; const std::string Davix::DELEGATION_SCOPE = "Davix::HttpThirdPartyCopy::Delegation"; SOAP_NMAC struct Namespace namespaces[] = { {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-envelope", NULL}, {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/*/soap-encoding", NULL}, {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, {"tns", "http://www.gridsite.org/namespaces/delegation-1", NULL, NULL}, {"tns2", "http://www.gridsite.org/namespaces/delegation-2", NULL, NULL}, {NULL, NULL, NULL, NULL} }; // Timestamp from ASN1 representation static int get_timestamp_from_asn1(ASN1_TIME* asn1) { char* data = (char*) ASN1_STRING_data(asn1); size_t len = strlen(data); struct tm time_tm; char zone = 0; memset(&time_tm, 0, sizeof(struct tm)); if (len == 11 && sscanf(data, "%02d%02d%02d%02d%02d%c", &(time_tm.tm_year), &(time_tm.tm_mon), &(time_tm.tm_mday), &(time_tm.tm_hour), &(time_tm.tm_min), &zone) != 7) { } else if (len == 13 && sscanf(data, "%02d%02d%02d%02d%02d%02d%c", &(time_tm.tm_year), &(time_tm.tm_mon), &(time_tm.tm_mday), &(time_tm.tm_hour), &(time_tm.tm_min), &(time_tm.tm_sec), &zone) != 7) { return 0; } else if (len == 15 && sscanf(data, "20%02d%02d%02d%02d%02d%02d%c", &(time_tm.tm_year), &(time_tm.tm_mon), &(time_tm.tm_mday), &(time_tm.tm_hour), &(time_tm.tm_min), &(time_tm.tm_sec), &zone) != 7) { return 0; } if (zone != 'Z') return 0; if (time_tm.tm_year < 90) time_tm.tm_year += 100; --(time_tm.tm_mon); return timegm(&time_tm); } // Remaining lifetime from the given certificate static int get_cert_remaining_life(const std::string& cert) { FILE* f = fopen(cert.c_str(), "r"); if (f == NULL) return 0; X509 *x509_cert = PEM_read_X509(f, NULL, NULL, NULL); if (x509_cert == NULL) return 0; ASN1_TIME* expiration = X509_get_notAfter(x509_cert); int expiration_timestamp = get_timestamp_from_asn1(expiration); X509_free(x509_cert); return (expiration_timestamp - time(NULL)) / 60; } // Puts into ucred the credentials paths // Puts into capath the CA directory // Returns true if the path should be removed at the end // Sets err on error bool DavixDelegation::get_credentials(const Davix::RequestParams& params, std::string& ucred, std::string&passwd, std::string& capath, int* lifetime, DavixError** err) { X509Credential credentials = params.getClientCertX509(); if (!credentials.hasCert()) { std::pair x509callback = params.getClientCertCallbackX509(); if (!x509callback.first) { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::CredentialNotFound, "No callback set for getting credentials. Can not delegate"); return false; } SessionInfo sess; x509callback.first(x509callback.second, sess, &credentials, err); if (err && *err) return false; } std::string ucert, ukey; if (!X509CredentialExtra::get_x509_info(credentials, &ucert, &ukey, &passwd)) { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, std::string("Third party copy only supports PEM certificates")); return false; } const std::vector &capathList = params.listCertificateAuthorityPath(); if (capathList.size() > 0) capath = capathList[0]; // Delegation lifetime (in minutes!) int cert_remaining_life = get_cert_remaining_life(ucert); int delegation_max_life = 12 * 60; // 12 hours // Delegated proxy lifetime should be shorter than the current lifetime! *lifetime = std::min(cert_remaining_life, delegation_max_life) - 1; // Should at least remain one minute if (*lifetime <= 1) { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, std::string("The certificate expired or has less than two minutes left!")); return false; } // Cert and key need to be in the same file if (ucert == ukey) { ucred.assign(ucert); return false; } else { FILE *ifp, *ofp; int fd; int c; char* aux = strdup("/tmp/.XXXXXX"); fd = mkstemp(aux); ofp = fdopen(fd, "w"); ifp = fopen(ukey.c_str(), "r"); while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); fclose(ifp); ifp = fopen(ukey.c_str(), "r"); while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); fclose(ifp); fclose(ofp); ucred.assign(aux); free(aux); return true; } } // Guess the delegation version that should be used static int get_delegation_version(const std::string& ucred, const std::string& passwd, const std::string& capath, const std::string& dlg_endpoint, DavixError** err) { struct soap *soap_v; char err_buffer[512]; int version = -1; soap_v = soap_new(); if (soap_ssl_client_context(soap_v, SOAP_SSL_DEFAULT, ucred.c_str(), passwd.c_str(), ucred.c_str(), capath.c_str(), NULL) == 0) { delegation2::tns2__getVersionResponse response; delegation2::soap_call_tns2__getVersion(soap_v, dlg_endpoint.c_str(), "http://www.gridsite.org/namespaces/delegation-2", response); if (soap_v->error == 0) { version = atoi(response.getVersionReturn); } else { // Assume version 1 (does not implement the version method) version = 1; } } else { soap_sprint_fault(soap_v, err_buffer, sizeof(err_buffer)); DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, std::string("Could not connect to the delegation endpoint: ") + err_buffer); } soap_free(soap_v); soap_done(soap_v); return version; } static void triggerHooks(Context & context, RequestParams & params){ RequestPreRunHook preRun = context.getHook(); Uri u; HttpRequest tmp_req(context, u, NULL); if(preRun){ // force the run of the hook on req + params preRun(params, tmp_req, u); } } // Perform delegation, abstracting the version that is running on the server std::string DavixDelegation::delegate(Context & context, const std::string &dlg_endpoint, const RequestParams& _p, Davix::DavixError** err) { std::string ucreds, capath, passwd; int lifetime; RequestParams params(_p); triggerHooks(context, params); get_credentials(params, ucreds, passwd, capath, &lifetime, err); if (*err) return std::string(); // Initialize SSL ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); // Figure out the version int delegation_version = get_delegation_version(ucreds, passwd, capath, dlg_endpoint, err); if (*err) return std::string(); DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Delegation version: {}", delegation_version); switch (delegation_version) { case 1: return delegate_v1(context, dlg_endpoint, params, ucreds, passwd, capath, lifetime, err); case 2: return delegate_v2(context, dlg_endpoint, params, ucreds, passwd, capath, lifetime, err); default: { std::ostringstream err_msg; err_msg << "Unknown delegation version: " << delegation_version; DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, err_msg.str()); } } return std::string(); } davix-R_0_5_0/src/modules/copy/delegation/delegation.hpp000066400000000000000000000040311257152637300234330ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_DELEGATION_HPP #define DAVIX_DELEGATION_HPP #include #include namespace Davix { extern const std::string DELEGATION_SCOPE; // Need a class so it can be frieds with Session class DavixDelegation { public: static std::string delegate(Context & context, const std::string &dlg_endpoint, const Davix::RequestParams& params, Davix::DavixError** err); private: static bool get_credentials(const RequestParams& params, std::string& ucred, std::string& passwd, std::string& capath, int *lifetime, DavixError** err); static std::string delegate_v1(Context & context, const std::string &dlg_endpoint, const Davix::RequestParams& params, const std::string& ucred, const std::string& passwd, const std::string& capath, int lifetime, Davix::DavixError** err); static std::string delegate_v2(Context & context, const std::string &dlg_endpoint, const Davix::RequestParams& params, const std::string& ucred, const std::string& passwd, const std::string& capath, int lifetime, Davix::DavixError** err); }; } #endif davix-R_0_5_0/src/modules/copy/delegation/delegation1.cpp000066400000000000000000000117431257152637300235170ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "delegation1H.h" #include "delegation.hpp" #include "GRSTx509MakeProxyCert.h" using namespace Davix; /// Do the delegation std::string DavixDelegation::delegate_v1(Context & context, const std::string &dlg_endpint, const RequestParams& params, const std::string& ucred, const std::string& passwd, const std::string& capath, int lifetime, DavixError** err) { (void) context; (void) params; std::string delegation_id; std::string reqtxt; char* certtxt = NULL; struct soap *soap_get = NULL, *soap_put = NULL; delegation1::tns__getNewProxyReqResponse getNewProxyReqResponse; delegation1::tns__putProxyResponse putProxyResponse; const char* url = dlg_endpint.c_str(); char err_buffer[512]; size_t err_aux; // Request a new delegation ID soap_get = soap_new(); soap_get->keep_alive = 1; if (soap_ssl_client_context(soap_get, SOAP_SSL_DEFAULT, ucred.c_str(), passwd.c_str(), ucred.c_str(), capath.c_str(), NULL) == 0) { soap_call_tns__getNewProxyReq(soap_get, url, "http://www.gridsite.org/namespaces/delegation-1", getNewProxyReqResponse); if(soap_get->error == 0) { reqtxt = getNewProxyReqResponse.getNewProxyReqReturn->proxyRequest; delegation_id = getNewProxyReqResponse.getNewProxyReqReturn->delegationID; // Generate proxy if (GRSTx509MakeProxyCert(&certtxt, stderr, (char*)reqtxt.c_str(), (char*)ucred.c_str(), (char*)ucred.c_str(), lifetime) == GRST_RET_OK) { // Submit the proxy soap_put = soap_new(); if (soap_ssl_client_context(soap_put, SOAP_SSL_DEFAULT, ucred.c_str(), passwd.c_str(), ucred.c_str(), capath.c_str(), NULL) == 0) { soap_call_tns__putProxy(soap_put, url, "http://www.gridsite.org/namespaces/delegation-1", (char*)delegation_id.c_str(), certtxt, putProxyResponse); if (soap_put->error) { // Could not PUT err_aux = snprintf(err_buffer, sizeof(err_buffer), "Could not PUT the proxy: "); soap_sprint_fault(soap_put, err_buffer + err_aux, sizeof(err_buffer) - err_aux); DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, err_buffer); } } else { // soap_put ssl error err_aux = snprintf(err_buffer, sizeof(err_buffer), "Connection error on proxy put: "); soap_sprint_fault(soap_put, err_buffer + err_aux, sizeof(err_buffer) - err_aux); DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, err_buffer); } soap_free(soap_put); } else { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, std::string("Could not generate the proxy: ") + err_buffer); } } else { // Could not get ID err_aux = snprintf(err_buffer, sizeof(err_buffer), "Could not get proxy request: "); soap_sprint_fault(soap_get, err_buffer + err_aux, sizeof(err_buffer) - err_aux); DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, std::string("Could not get the delegation id: ") + err_buffer); } } else { // soap_get ssl error err_aux = snprintf(err_buffer, sizeof(err_buffer), "Could not connect to get the proxy request: "); soap_sprint_fault(soap_get, err_buffer + err_aux, sizeof(err_buffer) - err_aux); DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, std::string("Could not connect to the delegation endpoint: ") + err_buffer); } // Clean soap_get soap_free(soap_get); free(certtxt); // Return delegation ID return delegation_id; } davix-R_0_5_0/src/modules/copy/delegation/delegation2.cpp000066400000000000000000000141271257152637300235170ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "delegation.hpp" #include "delegation2H.h" #include #include "GRSTx509MakeProxyCert.h" using namespace Davix; using namespace delegation2; static void err2davix(struct soap* soap, DavixError** err, const std::string& prefix) { char err_buffer[512]; soap_sprint_fault(soap, err_buffer, sizeof(err_buffer)); DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, prefix + err_buffer); } static bool get_delegated_credentials(struct soap* soap, const std::string& endpoint, const std::string& dlg_id, time_t* lifetime) { struct tns2__getTerminationTimeResponse resp; char *dlg_id_ptr = soap_strdup(soap, dlg_id.c_str()); if (SOAP_OK != soap_call_tns2__getTerminationTime(soap, endpoint.c_str(), NULL, dlg_id_ptr, resp)) { char err_buffer[512]; soap_sprint_fault(soap, err_buffer, sizeof(err_buffer)); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_GRID, "Could not retrieve delegated credentials: {}", err_buffer); return false; } *lifetime = resp._getTerminationTimeReturn - time(NULL); return true; } static void renew_proxy(struct soap* soap, const std::string& endpoint, const std::string& ucred, const std::string& dlg_id, int lifetime, bool force, DavixError** err) { int ret; char* dlg_id_ptr = soap_strdup(soap, dlg_id.c_str()); //char *sdelegationID = (char *) "", *localproxy, *certtxt, *; char *certtxt, *scerttxt; std::string certreq; struct tns2__getProxyReqResponse get_resp; struct tns2__renewProxyReqResponse renew_resp; struct tns2__putProxyResponse put_resp; if (force) { DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Renew proxy request"); ret = soap_call_tns2__renewProxyReq(soap, endpoint.c_str(), NULL, dlg_id_ptr, renew_resp); if (SOAP_OK != ret) { err2davix(soap, err, "Renewal failed"); return; } certreq = renew_resp._renewProxyReqReturn; } /* if it was forced and failed, or if it was not forced at all */ if (certreq.empty()) { DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Get proxy request"); /* there was no proxy, or not forcing -- the normal path */ ret = soap_call_tns2__getProxyReq(soap, endpoint.c_str(), NULL, dlg_id_ptr, get_resp); if (SOAP_OK != ret) { err2davix(soap, err, "Renewal failed"); return; } certreq = get_resp._getProxyReqReturn; } /* generating a certificate from the request */ if (!certreq.empty()) { DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Sign proxy request"); ret = GRSTx509MakeProxyCert(&certtxt, stderr, (char*)certreq.c_str(), (char*)ucred.c_str(), (char*)ucred.c_str(), lifetime); } else { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, "Could not get a request"); return; } if (ret != GRST_RET_OK) { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, "GRSTx509MakeProxyCert failed"); return; } scerttxt = soap_strdup(soap, certtxt); if (!scerttxt) { DavixError::setupError(err, DELEGATION_SCOPE, StatusCode::DelegationError, "Could not duplicate"); return; } DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Put new proxy"); if (SOAP_OK != soap_call_tns2__putProxy(soap, endpoint.c_str(), NULL, dlg_id_ptr, scerttxt, put_resp)) { err2davix(soap, err, "Renewal failed"); return; } } std::string DavixDelegation::delegate_v2(Context & context, const std::string &dlg_endpoint, const Davix::RequestParams& params, const std::string& ucred, const std::string& passwd, const std::string& capath, int lifetime, Davix::DavixError** err) { (void) context; (void) params; struct soap* soap; soap = soap_new(); std::string dlg_id = "1234"; if (soap_ssl_client_context(soap, SOAP_SSL_DEFAULT, ucred.c_str(), passwd.c_str(), ucred.c_str(), capath.c_str(), NULL) != 0) { err2davix(soap, err, "Could not connect to the delegation endpoint: "); return std::string(); } // Check if there is already a delegation done bool renew_delegation = false; bool new_delegation = false; time_t delegated_lifetime; if(!get_delegated_credentials(soap, dlg_endpoint, dlg_id, &delegated_lifetime)) { DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "No delegated credentials on the storage"); new_delegation = true; } else if (delegated_lifetime < lifetime) { DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Need to renew the credentials, {} > {}", lifetime, delegated_lifetime); renew_delegation = true; } else { DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_GRID, "Remaining life of the delegated credentials: {}", delegated_lifetime); } if (new_delegation || renew_delegation) renew_proxy(soap, dlg_endpoint, ucred, dlg_id, lifetime, renew_delegation, err); soap_free(soap); soap_done(soap); if (*err) return std::string(); else return dlg_id; } davix-R_0_5_0/src/modules/copy/delegation/typemap.dat000066400000000000000000000001551257152637300227630ustar00rootroot00000000000000tns="http://www.gridsite.org/namespaces/delegation-1" tns2="http://www.gridsite.org/namespaces/delegation-2" davix-R_0_5_0/src/modules/copy/perfmarker.cpp000066400000000000000000000054401257152637300213430ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include using namespace Davix; PerformanceMarker::PerformanceMarker(): index(0), count(0), begin(0), latest(0), transferred(0), transferAvg(0), transferInstant(0) { // Nothing } PerformanceData::PerformanceData(): begin(0), latest(0), markers() { // Nothing } PerformanceData::~PerformanceData() { } void PerformanceData::update(const PerformanceMarker& in) { if (markers.size() != in.count) markers.resize(in.count); if (in.index < 0 || in.index > markers.size()) return; PerformanceMarker& marker = markers[in.index]; if (marker.begin == 0) marker.begin = in.latest; // Calculate differences time_t absElapsed = in.latest - marker.begin; time_t diffElapsed = in.latest - marker.latest; off_t diffSize = in.transferred - marker.transferred; // Update marker.index = in.index; marker.count = in.count; marker.latest = in.latest; marker.transferred = in.transferred; if (absElapsed) marker.transferAvg = marker.transferred / absElapsed; if (diffElapsed) marker.transferInstant = diffSize / diffElapsed; if (begin == 0 || begin < marker.begin) begin = marker.begin; if (latest < marker.latest) latest = marker.latest; } time_t PerformanceData::absElapsed() const { return latest - begin; } off_t PerformanceData::avgTransfer(void) const { off_t total = 0; for (int i = 0; i < markers.size(); ++i) total += markers[i].transferAvg; return total; } off_t PerformanceData::diffTransfer() const { off_t total = 0; for (size_t i = 0; i < markers.size(); ++i) total += markers[i].transferInstant; return total; } off_t PerformanceData::totalTransferred() const { off_t total = 0; for (size_t i = 0; i < markers.size(); ++i) total += markers[i].transferred; return total; } davix-R_0_5_0/src/modules/modules_profiles.cpp000066400000000000000000000075771257152637300216230ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "modules_profiles.hpp" #include #include #include #include namespace Davix{ struct GridEnv{ std::string cert_path; std::string key_path; std::string ca_path; }; GridEnv createGridEnv(){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "Enable GRID profile for DAVIX"); GridEnv env; env.ca_path = EnvUtils::getEnv("X509_CERT_DIR", "/etc/grid-security/certificates/"); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "Add CA path {} to valid CA path list", env.ca_path); std::string proxy = EnvUtils::getEnv("X509_USER_PROXY", std::string()); if(proxy.size() ==0){ proxy = fmt::format("/tmp/x509up_u{}", geteuid()); if(access(proxy.c_str(), R_OK) !=0){ DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_CORE, "Unable to read proxy file {}", proxy); proxy.clear(); } } if(proxy.size() > 0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "Define {} proxy certificate for use", proxy); env.cert_path = env.key_path = proxy; }else{ // No proxy, load simply creds env.key_path = EnvUtils::getEnv("X509_USER_KEY", std::string()); env.cert_path = EnvUtils::getEnv("X509_USER_CERT", std::string()); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "Define to use GRID key {} and GRID cert {} ", env.key_path, env.cert_path); } return env; } void awesomeGridHook(RequestParams& p, HttpRequest & req, Uri & u, RequestPreRunHook previous_hook, GridEnv env_grid){ // initialize environment // add grid CA path if(env_grid.ca_path.size() >0){ p.addCertificateAuthorityPath(env_grid.ca_path); } // if no cert auth configured, configure one if(env_grid.key_path.size() > 0){ X509Credential x509; DavixError* tmp_err=NULL; if( x509.loadFromFilePEM(env_grid.key_path, env_grid.cert_path, "", &tmp_err) <0){ DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_CORE, "Impossible to load GRID certificate {} {}: {}", env_grid.key_path, env_grid.cert_path, tmp_err->getErrMsg()); if(tmp_err){ std::cerr << "("<< tmp_err->getErrScope() <<") Error: "<< tmp_err->getErrMsg() << std::endl; DavixError::clearError(&tmp_err); } }else{ // in current state, GRID profiles ignore all manually defined callbacks p.setClientCertCallbackX509(NULL, NULL); p.setClientCertX509(x509); } } if(previous_hook){ previous_hook(p, req, u); } } void loadGridProfile(Context & context){ GridEnv grid_env = createGridEnv(); RequestPreRunHook previous_hook = context.getHook(); RequestPreRunHook new_hook = std::bind(awesomeGridHook, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, previous_hook, grid_env); context.setHook(new_hook); } } davix-R_0_5_0/src/modules/modules_profiles.hpp000066400000000000000000000021661257152637300216150ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef MODULES_PROFILES_HPP #define MODULES_PROFILES_HPP namespace Davix{ class Context; // load grid profile, setup all required environment and hooks void loadGridProfile(Context & context); } #endif // MODULES_PROFILES_HPP davix-R_0_5_0/src/neon/000077500000000000000000000000001257152637300150135ustar00rootroot00000000000000davix-R_0_5_0/src/neon/CMakeLists.txt000066400000000000000000000000311257152637300175450ustar00rootroot00000000000000# main file for src davix-R_0_5_0/src/neon/neonrequest.cpp000066400000000000000000000714251257152637300201000ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "neonrequest.hpp" #include #include #include #include #include #include #include namespace Davix { class NEONSessionExtended : public NEONSession{ public: NEONSessionExtended(NEONRequest* r, const Uri &uri, const RequestParams &p, DavixError **err) : NEONSession(r->_c, uri, p, err), _r(r) { if(get_ne_sess() != NULL){ ne_hook_pre_send(get_ne_sess(), NEONRequest::neon_hook_pre_send, (void*)r); ne_hook_post_headers(get_ne_sess(), NEONRequest::neon_hook_pre_rec, (void*) r); } } virtual ~NEONSessionExtended(){ if(get_ne_sess() != NULL){ ne_unhook_pre_send(get_ne_sess(), NEONRequest::neon_hook_pre_send, (void*)_r); ne_unhook_post_headers(get_ne_sess(), NEONRequest::neon_hook_pre_rec, (void*) _r); } } private: NEONRequest* _r; }; void configureRequestParamsProto(const Uri &uri, RequestParams ¶ms){ if(params.getProtocol() == RequestProtocol::Auto){ const std::string & proto = uri.getProtocol(); if( proto.compare(0,2,"s3") ==0){ params.setProtocol(RequestProtocol::AwsS3); }else if ( proto.compare(0, 3,"dav") ==0){ params.setProtocol(RequestProtocol::Webdav); } } } void neon_generic_error_mapper(int ne_status, StatusCode::Code & code, std::string & str){ switch(ne_status){ case NE_OK: code = StatusCode::OK; str= "Status Ok"; break; case NE_LOOKUP: code = StatusCode::NameResolutionFailure; str= "Domain name resolution failed"; break; case NE_AUTH: code = StatusCode::AuthenticationError; str= "Authentification failed on server"; break; case NE_PROXYAUTH: code = StatusCode::AuthenticationError; str= "Authentification failed on proxy"; break; case NE_CONNECT: code = StatusCode::ConnectionProblem; str= "Could not connect to server"; break; case NE_TIMEOUT: code = StatusCode::ConnectionTimeout; str= "Connection timed out"; break; case NE_FAILED: code = StatusCode::SessionCreationError; str= "The precondition failed"; break; case NE_RETRY: code = StatusCode::RedirectionNeeded; str= "Retry Request"; break; default: code= StatusCode::UnknowError; str= "Unknow Error from libneon"; } } // convert neon_simple_request error to davix code, void neon_simple_req_code_to_davix_code(int ne_status, ne_session* sess, const std::string & scope, DavixError** err){ StatusCode::Code code; std::string str; switch(ne_status){ case NE_ERROR:{ const char * str_error = ne_get_error(sess); if(strstr(str_error, "404") != NULL){ code = StatusCode::FileNotFound; }else if(strstr(str_error, "401") != NULL || strstr(str_error, "403") != NULL){ code = StatusCode::PermissionRefused; }else{ code = StatusCode::ConnectionProblem; } str = std::string("(Neon): ").append(str_error); break; } default: neon_generic_error_mapper(ne_status, code, str); } DavixError::setupError(err,scope, code, str); } NEONRequest::NEONRequest(HttpRequest & h, Context& context, const Uri & uri_req) : _req_flag(RequestFlag::IdempotentRequest), params(), _neon_sess(), _req(NULL), _current( new Uri(uri_req)), _orig(_current), _number_try(0), _total_read_size(0), _last_read(-1), _vec(), _vec_line(), _content_ptr(), _content_len(0), _content_offset(0), _content_body(), _fd_content(-1), _content_provider(), _ans_size(-1), _expiration_time(), _request_type("GET"), _h(h), _c(context), req_started(false), req_running(false), _last_request_flag(0), _headers_field(){ } NEONRequest::~NEONRequest(){ // safe destruction of the request resetRequest(); } void NEONRequest::cancelSessionReuse(){ // if session registered // cancel any re-use of the session // if(_neon_sess.get() != NULL){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Connection problem: eradicate session"); _neon_sess->disable_session_reuse(); } } void NEONRequest::resetRequest(){ if(req_running) { endRequest(NULL); } freeRequest(); } int NEONRequest::createRequest(DavixError** err){ if(_req){ resetRequest(); } boost::shared_ptr redir_url = ContextExplorer::SessionFactoryFromContext(_c).redirectionResolve(_request_type, *_current); if(redir_url.get() != NULL){ _current.swap(redir_url); } if( instanceSession(err) < 0) return -1; _req= ne_request_create(_neon_sess->get_ne_sess(), _request_type.c_str(), _current->getPathAndQuery().c_str()); configureRequest(); return 0; } int NEONRequest::instanceSession(DavixError** err){ DavixError * tmp_err=NULL; _neon_sess.reset(static_cast(new NEONSessionExtended(this, *_current, params, &tmp_err))); if(tmp_err){ _neon_sess.reset(NULL); DavixError::propagateError(err, tmp_err); return -1; } return 0; } ssize_t NEONRequest::neon_body_content_provider(void* userdata, char* buffer, size_t buflen){ NEONRequest* req = static_cast(userdata); return (ssize_t) req->_content_provider.callback(req->_content_provider.udata, buffer, buflen); } bool NEONRequest::checkTimeout(DavixError **err){ if(_expiration_time.isValid() && _expiration_time < Chrono::Clock(Chrono::Clock::Monolitic).now()){ std::ostringstream ss; ss << "timeout of " << params.getOperationTimeout()->tv_sec << "s"; DavixError::setupError(err, davix_scope_http_request(), StatusCode::OperationTimeout, ss.str()); return true; } return false; } void NEONRequest::configureRequest(){ // reconfigure protos configureRequestParamsProto(*_current, params); std::copy(params.getHeaders().begin(), params.getHeaders().end(), std::back_inserter(_headers_field)); // configure S3 params if needed if(params.getProtocol() == RequestProtocol::AwsS3) configureS3params(); // setup timeout if(_expiration_time.isValid() == false && params.getOperationTimeout()->tv_sec != 0){ using namespace Chrono; _expiration_time = Clock(Clock::Monolitic).now() + Duration(params.getOperationTimeout()->tv_sec); } // setup headers for(size_t i=0; i< _headers_field.size(); ++i){ ne_add_request_header(_req, _headers_field[i].first.c_str(), _headers_field[i].second.c_str()); } // setup flags ne_set_request_flag(_req, NE_REQFLAG_EXPECT100, _req_flag & RequestFlag::SupportContinue100); ne_set_request_flag(_req, NE_REQFLAG_IDEMPOTENT, _req_flag & RequestFlag::IdempotentRequest); // configure connexion parameters for PUT request if( (_req_flag & RequestFlag::SupportContinue100) == true) _neon_sess->disable_session_reuse(); if(_fd_content > 0){ ne_set_request_body_fd(_req, _fd_content, _content_offset, _content_len); }else if(_content_provider.callback) { ne_set_request_body_provider(_req, _content_len, &neon_body_content_provider, this); }else if(_content_ptr && _content_len >0){ ne_set_request_body_buffer(_req, _content_ptr, _content_len); } } void NEONRequest::configureS3params(){ HeaderVec vec = _headers_field; S3::signRequest(params, _request_type, *_current, vec); vec.swap(_headers_field); } int NEONRequest::processRedirection(int neonCode, DavixError **err){ int end_status = -1; if (this->params.getTransparentRedirectionSupport()) { if( neonCode != NE_OK && neonCode != NE_RETRY && neonCode != NE_REDIRECT){ req_started= req_running = false; createError(neonCode, err); return -1; } ne_discard_response(_req); // Get a valid redirection, drop request content _last_read =0; end_status = ne_end_request(_req); // submit the redirection if(redirectRequest(err) <0){ // accept redirection return -1; } end_status = NE_RETRY; } else { end_status = 0; } return end_status; } int NEONRequest::startRequest(DavixError **err){ if( createRequest(err) < 0) return -1; return negotiateRequest(err); } int NEONRequest::negotiateRequest(DavixError** err){ const int auth_retry_limit = 5; int code, status, end_status = NE_RETRY; _last_read = -1; _total_read_size = 0; DAVIX_SCOPE_TRACE(DAVIX_LOG_HTTP, negoreq); // check timeout if(checkTimeout(err) == true) return -1; if(req_started){ DavixError::setupError(err, davix_scope_http_request(), StatusCode::AlreadyRunning, "Http request already started, Error"); return -1; } req_started = req_running = true; while(end_status == NE_RETRY && _number_try < auth_retry_limit){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "NEON start internal request"); if( (status = ne_begin_request(_req)) != NE_OK && status != NE_REDIRECT){ _last_read = -1; if( status == NE_ERROR && requestCleanup() && ( strstr(ne_get_error(_neon_sess->get_ne_sess()), "Could not") != NULL || strstr(ne_get_error(_neon_sess->get_ne_sess()), "Connection reset by peer") != NULL || strstr(ne_get_error(_neon_sess->get_ne_sess()), "Broken pipe") != NULL )){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_HTTP, "Connection problem, retry"); _number_try++; return startRequest(err); } if( status == NE_CONNECT && requestCleanup() ){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_HTTP, "Impossible to connect to {}, retry from origin {}", _current->getString(), _orig->getString()); _number_try++; return startRequest(err); } req_started= req_running == false; createError(status, err); cancelSessionReuse(); ContextExplorer::SessionFactoryFromContext(_c).redirectionClean(_request_type, *_orig); return -1; } _last_read =1; code = getRequestCode(); switch(code){ case 301: case 302: case 303: case 307: if( (end_status = processRedirection(status, err)) <0){ return -1; } break; case 401: // authentification requested, do retry ne_discard_response(_req); end_status = ne_end_request(_req); _last_read = -1; if( end_status != NE_RETRY){ req_started= req_running = false; clearAnswerContent(); _number_try++; if (requestCleanup()){ DavixError::clearError(err); endRequest(NULL); return startRequest(err); } if(end_status == NE_OK){ DavixError::setupError(err,davix_scope_http_request(), StatusCode::AuthentificationError, "401 Unauthorized"); return -1; } createError(end_status, err); return -1; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "(NEON) {} code -> request again ", code); break; case 403: case 501: // cleanup redirection _number_try++; if( requestCleanup()){ // recursive call, restart request endRequest(NULL); return startRequest(err); } end_status = 0; break; default: end_status = 0; break; } _number_try++; } if(_number_try >= auth_retry_limit){ if(_neon_sess.get() != NULL && _neon_sess->getLastError(err)){ DavixError::setupError(err,davix_scope_http_request(), StatusCode::AuthenticationError, "Authentication Error, reach maximum number of attempts"); } return -2; } return 0; } // mark the session as dirty for destruction, clean any cached redirection due to error // detect if the request comes from a cached session or have been redirected // if it is the case, return true // bool NEONRequest::requestCleanup(){ // cleanup redirection ContextExplorer::SessionFactoryFromContext(_c).redirectionClean(_request_type, *_orig); // disable recycling // server supporting broken pipelining will trigger if reused _neon_sess->disable_session_reuse(); // check if we had a redirection // if it's the case redirection can be expired, then if(_current != _orig || _neon_sess->isRecycledSession()){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, " -> Error when using reycling of session/redirect : cancel and try again"); // disable session reuse for this request, avoid picking up a session already expired params.setKeepAlive(false); _current = _orig; return true; } return false; } int NEONRequest::redirectRequest(DavixError **err){ boost::shared_ptr old_uri; const ne_uri * new_uri = ne_redirect_location(_neon_sess->get_ne_sess()); if(!new_uri){ DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, "Impossible to get the new redirected destination"); return -1; } char* dst_uri = ne_uri_unparse(new_uri); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "redirection from {} to {}", _current->getString(), dst_uri); // setup new path & session target old_uri = _current; _current= boost::shared_ptr(new Uri(dst_uri)); ne_free(dst_uri); ContextExplorer::SessionFactoryFromContext(_c).addRedirection(_request_type, *old_uri, _current); // recycle old request and session freeRequest(); _neon_sess.reset(NULL); // renew request req_started = false; // create a new couple of session + request if( createRequest(err) <0){ return -1; } req_started= true; return 0; } int NEONRequest::executeRequest(DavixError** err){ dav_ssize_t read_status=1, total_read=0; _last_request_flag =0; _vec.clear(); DAVIX_SCOPE_TRACE(DAVIX_LOG_HTTP, execReq); if( startRequest(err) < 0){ return -1; } if(getAnswerSize() > 0) _vec.reserve(std::min(getAnswerSize(), 4194304)); while(read_status > 0){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "NEON Read data flow"); size_t s = _vec.size(); _vec.resize(s + NEON_BUFFER_SIZE); read_status= readBlock(&(_vec[s]), NEON_BUFFER_SIZE, err); if( read_status >= 0){ if(read_status != NEON_BUFFER_SIZE){ _vec.resize(s + read_status); } total_read += read_status; } } if(read_status < 0){ if(err && *err == NULL){ createError(read_status, err); } return -1; } _vec.push_back('\0'); if(_ans_size < 0){ _ans_size = total_read; } if( endRequest(err) < 0){ return -1; } _last_request_flag =1; // 1 -> syn request return 0; } int NEONRequest::beginRequest(DavixError** err){ int ret = -1; _last_request_flag = 0; _vec.clear(); if( (ret= startRequest(err)) < 0) return -1; _last_request_flag = 2; // 2 -> sequential req return ret; } dav_ssize_t NEONRequest::readBlock(char* buffer, dav_size_t max_size, DavixError** err){ dav_ssize_t read_status=-1; if(_req == NULL){ DavixError::setupError(err, davix_scope_http_request(), StatusCode::AlreadyRunning, "No request started"); return -1; } if(max_size ==0) return 0; // check timeout if(checkTimeout(err) == true) return -1; // take from line buffer if(_vec_line.size() > 0){ if( _vec_line.size() >= max_size){ std::copy(_vec_line.begin(), _vec_line.begin() + max_size, buffer); _vec_line.erase(_vec_line.begin(), _vec_line.begin() + max_size); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "NEONRequest::readBlock read {} bytes (from buffer)", max_size); return max_size; }else{ const dav_ssize_t n_bytes = _vec_line.size(); std::copy(_vec_line.begin(), _vec_line.end(), buffer); _vec_line.clear(); read_status = readBlock(buffer + n_bytes, max_size -n_bytes, err); const dav_ssize_t ret_value = (read_status >= 0)?(read_status+n_bytes):(-1); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "NEONRequest::readBlock read {} bytes(from partially)", ret_value); return ret_value; } } if(_last_read ==0){ return 0; } _last_read= read_status= ne_read_response_block(_req, buffer, max_size ); if(read_status <0){ DavixError::setupError(err, davix_scope_http_request(), StatusCode::ConnectionProblem, "Invalid Read in request"); cancelSessionReuse(); req_running = false; return -1; } DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "NEONRequest::readBlock read {} bytes", read_status); _total_read_size += read_status; if(params.getTransferMonitorCb()){ dav_ssize_t final_size = getAnswerSize(); params.getTransferMonitorCb()(*_current, Transfer::Read, _total_read_size, ((final_size> 0)?(final_size):(0))); } return read_status; } dav_ssize_t NEONRequest::readToFd(int fd, dav_size_t read_size, DavixError** err){ dav_ssize_t ret=1, total=0; dav_size_t chunk_size = DAVIX_BLOCK_SIZE; read_size = (read_size==0)?(std::numeric_limits::max()):read_size; std::vector buffer(chunk_size); while( (ret = readBlock(&buffer[0], std::min(chunk_size,read_size), err)) >0 && ( read_size >0 )){ if(((dav_size_t)ret) == chunk_size && chunk_size < DAVIX_MAX_BLOCK_SIZE){ // increase buffer size chunk_size = std::min(chunk_size << 1, DAVIX_MAX_BLOCK_SIZE); buffer.resize(chunk_size); } dav_ssize_t write_len = ret; read_size -= ret; total += ret; do{ ret = write(fd, &buffer[0], write_len); if (ret == -1 && errno == EINTR) { continue; } else if (ret < 0) { DavixError::setupError(err, davix_scope_http_request(), StatusCode::SystemError, std::string("Impossible to write to fd").append(strerror(errno))); return -1; } else { write_len -= ret; } }while(write_len >0); } return (ret>= 0)?total:ret; } dav_ssize_t NEONRequest::readLine(char* buffer, dav_size_t max_size, DavixError** err){ dav_ssize_t ret=-1; if( _vec_line.size() > 0){ std::vector::iterator it; it = std::find(_vec_line.begin(), _vec_line.end(), '\n'); if( it != _vec_line.end()){ it ++; const dav_ssize_t read_size = it - _vec_line.begin(); std::copy(_vec_line.begin(), it, buffer); _vec_line.erase(_vec_line.begin(), it); return read_size; } std::copy(_vec_line.begin(), _vec_line.end(), buffer); const dav_ssize_t n_bytes = _vec_line.size(); _vec_line.clear(); ret = readLine(buffer + n_bytes, max_size - n_bytes, err); return (ret >= 0)?(ret + n_bytes):-1; } if( ( ret = readSegment(buffer, max_size, err)) >= 0){ // search for crlf char* p_endline; p_endline = std::find(buffer, buffer+ret, '\n'); if( p_endline < buffer+ret) p_endline++; _vec_line.reserve(ret - ( p_endline - buffer )); std::copy(p_endline, buffer + ret, std::back_inserter(_vec_line)); *p_endline = '\0'; return p_endline - buffer; } return -1; } dav_ssize_t NEONRequest::readSegment(char* p_buff, dav_size_t size_read, DavixError**err){ DavixError* tmp_err=NULL; dav_ssize_t ret, tmp_ret; dav_size_t s_read= size_read; ret = tmp_ret = 0; DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "Davix::Request::readSegment: want to read {} bytes ", size_read); do{ tmp_ret= readBlock(p_buff, s_read, &tmp_err); if(tmp_ret > 0){ // tmp_ret bytes readed ret += tmp_ret; } if(ret > 0 && ret < (dav_ssize_t) size_read){ p_buff+= tmp_ret; s_read -= tmp_ret; } }while( tmp_ret > 0 && ret < (dav_ssize_t) size_read); if(tmp_err){ DavixError::propagateError(err, tmp_err); return -1; } return ret; } int NEONRequest::endRequest(DavixError** err){ int status; (void) err; if(_req && req_running == true){ if(_last_read != 0){ // if read content, discard it DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "(EndRequest)(Libneon) Operation incomplete, kill the connection"); ne_abort_request(_req); cancelSessionReuse(); _last_read = -1; } status = ne_end_request(_req); if(status != NE_OK && status != NE_REDIRECT) { DavixError* tmp_err=NULL; createError(status, err); if(tmp_err){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "(EndRequest)(Libneon) Suppress broken connection {} -> {} ", tmp_err->getStatus(), tmp_err->getErrMsg()); cancelSessionReuse(); } DavixError::clearError(&tmp_err); } } req_started = req_running = false; return 0; } void NEONRequest::clearAnswerContent(){ _vec.clear(); } int NEONRequest::getRequestCode(){ return ne_get_status(_req)->code; } const char* NEONRequest::getAnswerContent(){ if(_last_request_flag == 1) return (const char*) &(_vec.at(0)); return NULL; } std::vector & NEONRequest::getAnswerContentVec(){ return _vec; } dav_ssize_t NEONRequest::getAnswerSizeFromHeaders() const{ std::string str_file_size=""; long size=-1; if( getAnswerHeader(ans_header_content_length, str_file_size)){ StrUtil::trim(str_file_size); try{ size = toType()(str_file_size); }catch(...){ size = -1; } } if( size == -1){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "Bad server answer: {} Invalid, impossible to determine answer size", ans_header_content_length); } return static_cast(size); } dav_ssize_t NEONRequest::getAnswerSize() const{ if(_ans_size < 0) _ans_size = getAnswerSizeFromHeaders(); return _ans_size; } time_t NEONRequest::getLastModified() const{ time_t t=0; std::string str_lastmodified; if( getAnswerHeader("Last-Modified", str_lastmodified)){ StrUtil::trim(str_lastmodified); try{ t = S3::s3TimeConverter(str_lastmodified); }catch(...){ str_lastmodified.clear(); } } if( str_lastmodified.empty()){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "Bad server answer: {} Invalid, impossible to determine last modified time"); } return t; } bool NEONRequest::getAnswerHeader(const std::string &header_name, std::string &value) const{ if(_req){ const char* answer_content = ne_get_response_header(_req, header_name.c_str()); if(answer_content){ value = answer_content; return true; } } return false; } size_t NEONRequest::getAnswerHeaders( HeaderVec & vec_headers) const{ if(_req){ void * handle = NULL; const char* name=NULL, *value=NULL; while( (handle = ne_response_header_iterate(_req, handle, &name, &value)) != NULL){ vec_headers.push_back(std::pair(name, value)); } } return vec_headers.size(); } void NEONRequest::setRequestBody(const std::string & body){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "NEONRequest : add request content of size {} ", body.size()); _content_body = std::string(body); _content_ptr = (char*) _content_body.c_str(); _content_len = strlen(_content_ptr); _fd_content = -1; } void NEONRequest::setRequestBody(const void *buffer, dav_size_t len){ _content_ptr = (char*) buffer; _content_len = len; _fd_content = -1; } void NEONRequest::setRequestBody(int fd, dav_off_t offset, dav_size_t len){ _fd_content = fd; _content_ptr = NULL; _content_len = len; _content_offset = offset; } void NEONRequest::setRequestBody(HttpBodyProvider provider, dav_size_t len, void* udata){ _content_len = len; _content_provider.callback = provider; _content_provider.udata = udata; } void NEONRequest::freeRequest(){ if(_req != NULL){ ne_request_destroy(_req); _req=NULL; } } void NEONRequest::createError(int ne_status, DavixError **err){ StatusCode::Code code; std::string str; switch(ne_status){ case NE_ERROR: { const char * neon_error = ne_get_error(_neon_sess->get_ne_sess()); str = std::string("(Neon): ").append((neon_error)?(neon_error):""); if (str.find("SSL handshake failed") == std::string::npos) code = StatusCode::ConnectionProblem; else code = StatusCode::SSLError; } break; case NE_TIMEOUT: { // check if redirection occured, if redirection occured // report TimeoutRedirectionError, to allow error recovery if(_current != _orig){ code = StatusCode::TimeoutRedirectionError; str= "Connection Timeout during redirection on "; str+= _current->getString(); break; } neon_generic_error_mapper(ne_status, code, str); } break; default: neon_generic_error_mapper(ne_status, code, str); break; } DavixError::setupError(err, davix_scope_http_request(), code, str); } void NEONRequest::neon_hook_pre_send(ne_request *r, void *userdata, ne_buffer *header){ (void) r; NEONRequest* req = (NEONRequest*) userdata; RequestPreSendHook hook = req->_c.getHook(); if(hook){ std::string header_line(header->data, (header->used)-1); hook(req->_h, header_line); } } void NEONRequest::neon_hook_pre_rec(ne_request *r, void *userdata, const ne_status *status){ (void) r; NEONRequest* req = (NEONRequest*) userdata; RequestPreReceHook hook = req->_c.getHook(); if(hook){ std::ostringstream header_line; HeaderVec headers; req->getAnswerHeaders(headers); header_line << "HTTP/"<< status->major_version << '.' << status->minor_version << ' ' << status->code << ' ' << status->reason_phrase << '\n'; hook(req->_h, header_line.str(), headers, status->code); } } } // namespace Davix davix-R_0_5_0/src/neon/neonrequest.hpp000066400000000000000000000161751257152637300201060ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_NEONREQUEST_H #define DAVIX_NEONREQUEST_H #include #include #include #include #include #include #include #include #include #include namespace Davix { #define NEON_BUFFER_SIZE 65000 class NEONSessionFactory; class NEONSession; class HttpRequest; class NEONSessionExtended; struct ContentProviderContext { ContentProviderContext(): callback(NULL), udata(NULL) {} HttpBodyProvider callback; void *udata; }; class NEONRequest : protected NonCopyable { public: int _req_flag; public: NEONRequest(HttpRequest &h, Context& f, const Uri & uri_req); virtual ~NEONRequest(); /** add a personalized header to the header request replace an existing one if already exist remove one if empty @param field : add a header field to the current http request or replace a existing one @param value : value of the field to set */ void addHeaderField(const std::string & field, const std::string & value){ _headers_field.push_back(std::pair (field, value)); } /** * set the request command to execute ( GET, POST, PUT, PROPFIND ) */ void setRequestMethod(const std::string & request_str){ _request_type = request_str; } void setParameters(const RequestParams &p ){ params = p; } // Execute the given request and return result to the buffer result // @return 0 on success int executeRequest(DavixError** err) ; void setRequestBody(const std::string & body); void setRequestBody(const void * buffer, dav_size_t len); void setRequestBody(int fd, dav_off_t offset, dav_size_t len); void setRequestBody(HttpBodyProvider provider, dav_size_t len, void* udata); int beginRequest(DavixError** err); /** read a block of a maximum size bytes in the request @param buffer : buffer to fill @param max_size : maximum number of bytes to set */ dav_ssize_t readBlock(char* buffer, dav_size_t max_size,DavixError** err); dav_ssize_t readSegment(char* buffer, dav_size_t size_read, DavixError**err); dav_ssize_t readLine(char* buffer, dav_size_t max_size, DavixError** err); dav_ssize_t readToFd(int fd, dav_size_t read_size, DavixError** err); /** finish an already started request */ int endRequest(DavixError** err); /** get a reference to the current result for synchronous full request */ const char* getAnswerContent(); std::vector & getAnswerContentVec(); /** * get content length **/ dav_ssize_t getAnswerSize() const; /** * get last modified **/ time_t getLastModified() const; /** clear the current result */ void clearAnswerContent(); int getRequestCode(); bool getAnswerHeader(const std::string &header_name, std::string &value) const; size_t getAnswerHeaders( std::vector > & vec_headers) const; // auth method support int do_pkcs12_cert_authentification(const char * filename_pkcs12, const char* passwd, DavixError** err); int do_login_passwd_authentification(const char *login, const char *passwd, DavixError** err); private: // request parameters RequestParams params; // neon internal field Ptr::Scoped _neon_sess; // request options flag ne_request * _req; boost::shared_ptr _current, _orig; // req info int _number_try; // read info dav_ssize_t _total_read_size, _last_read; std::vector _vec; std::vector _vec_line; // request content; char* _content_ptr; dav_size_t _content_len; dav_off_t _content_offset; std::string _content_body; int _fd_content; ContentProviderContext _content_provider; // answer length mutable dav_ssize_t _ans_size; // timeout management Chrono::TimePoint _expiration_time; // Request string std::string _request_type; HttpRequest & _h; Context& _c; bool req_started, req_running; int _last_request_flag; std::vector< std::pair > _headers_field; //////////////////////////////////////////// // Private Members dav_ssize_t getAnswerSizeFromHeaders() const; int startRequest(DavixError** err); int processRedirection(int neonCode, DavixError** err); // analyze and process redirection if needed void resetRequest(); int instanceSession(DavixError** err); bool checkTimeout(DavixError** err); void configureRequest(); void configureS3params(); void cancelSessionReuse(); // create initial neon request object int createRequest(DavixError** err); // negociate the request : authentification, redirection, name resolution int negotiateRequest(DavixError** err); // redirection logic int redirectRequest(DavixError** err); // redirecttion caching cleaning function bool requestCleanup(); void freeRequest(); void createError(int ne_status, DavixError** err); /** internal, try to authentification with pkcs12 credential */ int try_pkcs12_authentification(ne_session *sess, const ne_ssl_dname *const *dnames, DavixError** err); NEONRequest(const NEONRequest & req); NEONRequest & operator=(const NEONRequest & req); static ssize_t neon_body_content_provider(void* userdata, char* buffer, size_t buflen); static void neon_hook_pre_send(ne_request *req, void *userdata, ne_buffer *header); static void neon_hook_pre_rec(ne_request *req, void *userdata, const ne_status *status); friend class HttpRequest; friend class NEONSessionExtended; }; // // translate a neon error code to a davix one // void neon_to_davix_code(int ne_status,ne_session* sess, const std::string & scope, DavixError** err); void neon_simple_req_code_to_davix_code(int ne_status, ne_session* sess, const std::string & scope, DavixError** err); void configureRequestParamsProto(const Uri &uri, RequestParams ¶ms); } // namespace Davix #endif // DAVIX_NEONREQUEST_H davix-R_0_5_0/src/neon/neonsession.cpp000066400000000000000000000221441257152637300200650ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "neonsession.hpp" #include #include #include #include const char* davix_neon_key="davix_key"; using namespace StrUtil; namespace Davix{ static std::pair userInfo_to_auth(const std::string & userInfo){ std::pair id; std::string::const_iterator it = std::find(userInfo.begin(), userInfo.end(), ':'); id.first = std::string(userInfo.begin(), it); it = ((it != userInfo.end())?(it+1):(it)); id.second = std::string(it, userInfo.end()); return id; } static int validate_all_certificate(void *userdata, int failures, const ne_ssl_certificate *cert){ (void) userdata; (void) failures; (void) cert; return 0; } const int n_max_auth = 20; void NEONSession::authNeonCliCertMapper(void *userdata, ne_session *sess, const ne_ssl_dname *const *dnames, int dncount){ (void) dncount; (void) sess; (void) dnames; NEONSession* req = static_cast(userdata); X509Credential cert; const RequestParams* params = &req->_params; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "clicert callback "); DavixError::clearError(&(req->_last_error)); if(params->getClientCertFunctionX509()){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "call client cert callback "); SessionInfo infos; TRY_DAVIX{ params->getClientCertFunctionX509()(infos, cert); if(cert.hasCert() == false){ throw DavixException(davix_scope_x509cred(), StatusCode::AuthentificationError, "No valid credential given "); } ne_ssl_set_clicert(req->_sess, X509CredentialExtra::extract_ne_ssl_clicert(cert)); }CATCH_DAVIX(&(req->_last_error)); } return; } int NEONSession::provide_login_passwd_fn(void *userdata, const char *realm, int attempt, char *username, char *password){ (void) realm; NEONSession * req = static_cast(userdata); DavixError * tmp_err=NULL; int ret =-1; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Try to get auth/password authentification from client"); if(attempt > n_max_auth ){ DavixError::setupError(&(req->_last_error), davix_scope_http_request(), StatusCode::LoginPasswordError, "Overpass allowed number of authentication attempt"); } const std::pair retcallback(req->_params.getClientLoginPasswordCallback()); std::pair id; if(req->_u.getUserInfo().size() > 0){ id = userInfo_to_auth(req->_u.getUserInfo()); }else{ id = req->_params.getClientLoginPassword(); } if(id.first.empty() == false){ copy_std_string_to_buff(username, NE_ABUFSIZ, id.first.c_str()); copy_std_string_to_buff(password, NE_ABUFSIZ, id.second.c_str()); }else if(retcallback.first != NULL){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Try callback for login/passwd for {} time", attempt+1); SessionInfo infos; std::string tmp_login, tmp_password; DavixError::clearError(&(req->_last_error)); if( (ret = retcallback.first(retcallback.second, infos, tmp_login, tmp_password, attempt, &tmp_err) ) <0){ if(!tmp_err) DavixError::setupError(&tmp_err, davix_scope_http_request(), StatusCode::LoginPasswordError, "No valid login/passwd"); DavixError::propagateError(&(req->_last_error), tmp_err); return -1; } copy_std_string_to_buff(username, NE_ABUFSIZ, tmp_login.c_str()); copy_std_string_to_buff(password, NE_ABUFSIZ, tmp_password.c_str()); } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "get login/password with success...try server submission "); return 0; } NEONSession::NEONSession(Context & c, const Uri & uri, const RequestParams & p, DavixError** err) : _f(ContextExplorer::SessionFactoryFromContext(c)), _sess(NULL), _params(p), _last_error(NULL), _session_recycling(_f.getSessionCaching() && p.getKeepAlive()), reused(false), _u(uri) { _f.createNeonSession(p, uri, &_sess, err); if(_sess) configureSession(_sess, _u, p, &NEONSession::provide_login_passwd_fn, this, &NEONSession::authNeonCliCertMapper, this, reused); } NEONSession::~NEONSession(){ # ifndef _DISABLE_SESSION_REUSE if(_sess){ if(_session_recycling) _f.storeNeonSession(_sess); else ne_session_destroy(_sess); } # endif DavixError::clearError(&_last_error); } void configureSession(ne_session *_sess, const Uri & _u, const RequestParams ¶ms, ne_auth_creds lp_callback, void* lp_userdata, ne_ssl_provide_fn cred_callback, void* cred_userdata, bool & reused){ void* state = ne_get_session_private(_sess,davix_neon_key); if(state != NULL){ reused = true; } if(state == NULL || state != params.getParmState()){ // no configuration done, need to configure DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "configure session..."); if(strcmp(ne_get_scheme(_sess), "https") ==0) // fix a libneon bug with non ssl connexion ne_ssl_trust_default_ca(_sess); // register redirection management ne_redirect_register(_sess); // define user agent ne_set_useragent(_sess, params.getUserAgent().c_str()); if(params.getSSLCACheck() == false){ // configure ssl check DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "disable ssl verification"); ne_ssl_set_verify(_sess, validate_all_certificate, NULL); } if(timespec_isset(params.getConnectionTimeout())){ const int timeout = static_cast(params.getConnectionTimeout()->tv_sec); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "define connection timeout to {}" , timeout); ne_set_connect_timeout(_sess, timeout); } if(timespec_isset(params.getOperationTimeout())){ const int timeout = static_cast(params.getOperationTimeout()->tv_sec); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "define operation timeout to {}" , timeout); ne_set_read_timeout(_sess, timeout); } for(std::vector::const_iterator it = params.listCertificateAuthorityPath().begin(); it < params.listCertificateAuthorityPath().end(); it++){ struct stat st; if ( stat(it->c_str(), &st) < 0 || S_ISDIR(st.st_mode) == false){ DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_HTTP, "CA Path invalid : {}, {} ", *it, ((errno != 0)?strerror(errno):strerror(ENOTDIR))); errno = 0; }else{ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, "add CA PATH {}", *it); ne_ssl_truse_add_ca_path(_sess, it->c_str()); } } ne_set_session_flag(_sess, NE_SESSFLAG_PERSIST, params.getKeepAlive()); // setup sess key ne_set_session_private(_sess, davix_neon_key, params.getParmState()); } // configure callback for new request if( params.getClientLoginPassword().first.empty() == false || _u.getUserInfo().size() > 0 || params.getClientLoginPasswordCallback().first != NULL){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "enable login/password authentication"); ne_set_server_auth(_sess, lp_callback, lp_userdata); }else{ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "disable login/password authentication"); } // if authentification for cli cert by callback if( params.getClientCertFunctionX509()){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "enable client cert authentication by callback "); ne_ssl_provide_clicert(_sess, cred_callback, cred_userdata); }else{ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "disable client cert authentication"); } } } davix-R_0_5_0/src/neon/neonsession.hpp000066400000000000000000000053341257152637300200740ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef NEONSESSION_HPP #define NEONSESSION_HPP #include #include #include #include #include namespace Davix{ class NEONSessionFactory; class NEONSession { public: NEONSession(Context & c, const Uri & uri, const RequestParams & p, DavixError** err); virtual ~NEONSession(); inline ne_session* get_ne_sess(){ return _sess; } inline bool getLastError(DavixError** err){ if(_last_error){ DavixError::propagateError(err, _last_error); _last_error = NULL; return true; } return false; } inline bool isRecycledSession(){ return reused; } inline void disable_session_reuse(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_SSL, "Disable Session recycling"); _session_recycling = false; } private: NEONSessionFactory & _f; ne_session* _sess; const RequestParams & _params; DavixError* _last_error; bool _session_recycling; bool reused; Uri _u; NEONSession(const NEONSession &); NEONSession& operator=(const NEONSession &); // auth callback mapper // static void authNeonCliCertMapper(void *userdata, ne_session *sess, const ne_ssl_dname *const *dnames, int dncount); static int provide_login_passwd_fn(void *userdata, const char *realm, int attempt, char *username, char *password); }; void configureSession(ne_session *_sess, const Uri & uri, const RequestParams ¶ms, ne_auth_creds lp_callbac, void* lp_userdata, ne_ssl_provide_fn cred_callback, void* cred_userdata, bool & reused); } #endif // NEONSESSION_HPP davix-R_0_5_0/src/neon/neonsessionfactory.cpp000066400000000000000000000212541257152637300214560ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "neonsessionfactory.hpp" #include namespace Davix { static boost::once_flag neon_once = BOOST_ONCE_INIT; static void init_neon(){ ne_sock_init(); } static bool sessionCachingDisabled(){ return ( getenv("DAVIX_DISABLE_SESSION_CACHING") != NULL); } static bool redirCachingDisabled(){ return ( getenv("DAVIX_DISABLE_REDIRECT_CACHING") != NULL); } NEONSessionFactory::NEONSessionFactory() : _sess_map(), _sess_mut(), _session_caching(!sessionCachingDisabled()), _redir_caching(!redirCachingDisabled()), _redirCache(256) { boost::call_once(&init_neon, neon_once); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "HTTP/SSL Session caching {}", (_session_caching?"ENABLED":"DISABLED")); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "Redirection Session caching {}", (_redir_caching?"ENABLED":"DISABLED")); } NEONSessionFactory::~NEONSessionFactory(){ boost::lock_guard lock(_sess_mut); for(std::multimap::iterator it = _sess_map.begin(); it != _sess_map.end(); ++it){ ne_session_destroy(it->second); } } inline std::string davix_session_uri_rewrite(const Uri & u){ std::string proto = u.getProtocol(); if(proto.compare(0,4, "http") ==0 || proto.compare(0,2, "s3") == 0 || proto.compare(0,3, "dav") == 0){ proto.assign("http"); if(*(u.getProtocol().rbegin()) == 's') proto.append("s"); return proto; } return std::string(); } int NEONSessionFactory::createNeonSession(const RequestParams & params, const Uri & uri, ne_session** sess, DavixError **err){ if(uri.getStatus() == StatusCode::OK){ if(sess != NULL){ std::string scheme = davix_session_uri_rewrite(uri); if(scheme.size() > 0){ *sess = create_recycled_session(params, scheme, uri.getHost(), httpUriGetPort(uri)); return 0; } } } DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format("impossible to parse {}, not a valid HTTP, S3 or Webdav URL", uri.getString())); return -1; } int NEONSessionFactory::storeNeonSession(ne_session* sess){ internal_release_session_handle(sess); return 0; } ne_session* NEONSessionFactory::create_session(const RequestParams & params, const std::string & protocol, const std::string &host, unsigned int port){ ne_session *se; se = ne_session_create(protocol.c_str(), host.c_str(), (int) port); const Uri* proxy = params.getProxyServer(); if(se != NULL && proxy != NULL){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_HTTP, " configure mandatory proxy to {}", proxy->getString().c_str()); const enum ne_sock_sversion version = ((proxy->getProtocol().compare("socks5") ==0)?NE_SOCK_SOCKSV5:NE_SOCK_SOCKSV4); const int port_proxy = ((proxy->getPort() ==0)?1080:(proxy->getPort())); const std::string & userinfo = proxy->getUserInfo(); std::string user, password; std::string::const_iterator delimiter = std::find(userinfo.begin(), userinfo.end(), ':'); if(delimiter != userinfo.end()){ user.assign(std::string(userinfo.begin(), delimiter)); password.assign((delimiter+1), userinfo.end()); ne_session_socks_proxy(se, version, proxy->getHost().c_str(), port_proxy, user.c_str(), password.c_str()); }else{ ne_session_socks_proxy(se, version, proxy->getHost().c_str(), port_proxy, NULL, NULL); } } //ne_ssl_trust_default_ca(se); not stable in neon on epel 5 return se; } ne_session* NEONSessionFactory::create_recycled_session(const RequestParams & params, const std::string &protocol, const std::string &host, unsigned int port){ if(params.getKeepAlive()){ ne_session* se= NULL; boost::lock_guard lock(_sess_mut); std::multimap::iterator it; if( (it = _sess_map.find(create_map_keys_from_URL(protocol, host, port))) != _sess_map.end()){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "cached ne_session found ! taken from cache "); se = it->second; _sess_map.erase(it); return se; } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "no cached ne_session, create a new one "); return create_session(params, protocol, host, port); } void NEONSessionFactory::setSessionCaching(bool caching){ _session_caching = caching && !sessionCachingDisabled(); } void NEONSessionFactory::internal_release_session_handle(ne_session* sess){ // clear sensitive data // none // boost::lock_guard lock(_sess_mut); std::multimap::iterator it; std::string sess_key; sess_key.append(ne_get_scheme(sess)).append(ne_get_server_hostport(sess)); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "add old session to cache {}", sess_key.c_str()); _sess_map.insert(std::pair(sess_key, sess)); } static const std::string redirectionCreateKey(const std::string & method, const Uri & origin){ const std::string head_method("HEAD"); std::string res; res.reserve(method.size() + origin.getString().size() +3); res.append( ((method.compare("GET") ==0)?(head_method):(method))); // cache HEAD and GET on same key res.append("_").append(origin.getString()); return res; } void NEONSessionFactory::addRedirection( const std::string & method, const Uri & origin, boost::shared_ptr dest){ if(_redir_caching){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Add cached redirection <{} {} {}>", method.c_str(), origin.getString().c_str(), dest->getString().c_str()); _redirCache.insert(redirectionCreateKey(method, origin), dest); } } boost::shared_ptr NEONSessionFactory::redirectionResolve(const std::string & method, const Uri & origin){ boost::shared_ptr res = redirectionResolveSingle(method, origin); if(res.get() != NULL){ boost::shared_ptr res_rec = redirectionResolve(method, *res); if(res_rec.get() != NULL) return res_rec; } return res; } boost::shared_ptr NEONSessionFactory::redirectionResolveSingleIntern(const std::string & method, const Uri & origin){ return _redirCache.find(redirectionCreateKey(method, origin)); } boost::shared_ptr NEONSessionFactory::redirectionResolveSingle(const std::string & method, const Uri & origin){ boost::shared_ptr res = redirectionResolveSingleIntern(method, origin); if(res.get() != NULL){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Found redirection <{} {} {}>", method.c_str(), origin.getString().c_str(), res->getString().c_str()); } return res; } void NEONSessionFactory::redirectionClean(const std::string & method, const Uri & origin){ boost::shared_ptr res = redirectionResolveSingleIntern(method, origin); if(res.get() != NULL){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Delete Cached redirection for <{} {} {}>", method.c_str(), origin.getString().c_str(), res->getString().c_str()); _redirCache.erase(redirectionCreateKey(method, origin)); redirectionClean(method, *res); } } std::string create_map_keys_from_URL(const std::string & protocol, const std::string &host, unsigned int port){ std::string host_port; if( (strcmp(protocol.c_str(), "http") ==0 && port == 80) || ( strcmp(protocol.c_str(), "https") ==0 && port == 443)){ host_port = fmt::format("{}{}", protocol, host); }else host_port = fmt::format("{}{}:{}", protocol, host, port); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, " creating session keys... {}", host_port); return host_port; } } // namespace Davix davix-R_0_5_0/src/neon/neonsessionfactory.hpp000066400000000000000000000064431257152637300214660ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_NEONSESSIONFACTORY_H #define DAVIX_NEONSESSIONFACTORY_H #include #include #include #include #include #include namespace Davix { class HttpRequest; class NEONSessionFactory { friend class NEONRequest; public: NEONSessionFactory(); virtual ~NEONSessionFactory(); /** Create a session object or create a recycled one ( session reuse ) */ int createNeonSession(const RequestParams & params, const Uri & uri, ne_session** sess, DavixError** err); /** store a Neon session object for session reuse purpose */ int storeNeonSession(ne_session *sess); // // Redirecton caching // void addRedirection( const std::string & method, const Uri & origin, boost::shared_ptr dest); // try to find cached redirection, resolve a full chain boost::shared_ptr redirectionResolve(const std::string & method, const Uri & origin); // try to find a cached redirection, resolve only one element boost::shared_ptr redirectionResolveSingle(const std::string & method, const Uri & origin); void redirectionClean(const std::string & method, const Uri & origin); // // opts // void setSessionCaching(bool caching); inline bool getSessionCaching() const { return _session_caching; } private: // session pool std::multimap _sess_map; boost::mutex _sess_mut; bool _session_caching, _redir_caching; // redirection pool Cache _redirCache; void internal_release_session_handle(ne_session* sess); ne_session* create_session(const RequestParams & params, const std::string & protocol, const std::string &host, unsigned int port); ne_session* create_recycled_session(const RequestParams & params, const std::string & protocol, const std::string &host, unsigned int port); boost::shared_ptr redirectionResolveSingleIntern(const std::string & method, const Uri & origin); }; void parse_http_neon_url(const std::string & url, std::string & protocol, std::string & host, std::string & path, unsigned long *port); std::string create_map_keys_from_URL(const std::string & protocol, const std::string &host, unsigned int port); } // namespace Davix #endif // DAVIX_NEONSESSIONFACTORY_H davix-R_0_5_0/src/params/000077500000000000000000000000001257152637300153375ustar00rootroot00000000000000davix-R_0_5_0/src/params/davixrequestparams.cpp000066400000000000000000000342371257152637300220040ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include namespace Davix { const char * default_agent = "libdavix/" DAVIX_VERSION; volatile int state_value =0; inline int get_requeste_uid(){ state_value +=1; return state_value; } #define SESSION_FLAG_KEEP_ALIVE 0x01 struct X509Data{ X509Data() : _pair(static_cast(NULL),static_cast(NULL)), _x509_fun(), _cred(){} std::pair _pair; authFunctionClientCertX509 _x509_fun; X509Credential _cred; static X509Data* instance(boost::shared_ptr & cred_ptr){ if(cred_ptr.get() == NULL){ cred_ptr.reset(new X509Data()); } return cred_ptr.get(); } static X509Data* reset(boost::shared_ptr & cred_ptr){ cred_ptr.reset(new X509Data()); return cred_ptr.get(); } int cred_callback(const SessionInfo & info, X509Credential& cert){ (void) info; cert = _cred; return 0; } int c_callback(const SessionInfo & info, X509Credential& cert){ DavixError* tmp_err=NULL; int ret = -1; if(_pair.first){ ret = _pair.first(_pair.second, info, &cert, &tmp_err); } Davix::checkDavixError(&tmp_err); return ret; } }; struct RequestParamsInternal{ RequestParamsInternal() : _ssl_check(true), _redirection(true), _recursive_mode(false), _s3_listing_mode(S3ListingMode::Hierarchical), _s3_max_key_entries(10000), _ca_path(), _x509_data(), _idlogpass(), _call_loginpswwd(NULL), _call_loginpswwd_userdata(NULL), _aws_cred(), ops_timeout(), connexion_timeout(), agent_string(default_agent), _proto(RequestProtocol::Auto), _metalink_mode(MetalinkMode::Auto), _customhdr(), _proxy_server(), _session_flag(SESSION_FLAG_KEEP_ALIVE), _state_uid(get_requeste_uid()), _transferCb(), retry_number(default_retry_number), retry_delay(), _copy_mode(CopyMode::Push) { timespec_clear(&connexion_timeout); timespec_clear(&ops_timeout); connexion_timeout.tv_sec = DAVIX_DEFAULT_CONN_TIMEOUT; ops_timeout.tv_sec = DAVIX_DEFAULT_OPS_TIMEOUT; } virtual ~RequestParamsInternal(){ if(_idlogpass.second.empty() == false){ // eradicate password from memory for(std::string::iterator it = _idlogpass.second.begin(); it < _idlogpass.second.end(); ++it) *it = 'a'; } } RequestParamsInternal(const RequestParamsInternal & param_private): _ssl_check(param_private._ssl_check), _redirection(param_private._redirection), _recursive_mode(param_private._recursive_mode), _s3_listing_mode(param_private._s3_listing_mode), _s3_max_key_entries(param_private._s3_max_key_entries), _ca_path(param_private._ca_path), _x509_data(param_private._x509_data), _idlogpass(param_private._idlogpass), _call_loginpswwd(param_private._call_loginpswwd), _call_loginpswwd_userdata(param_private._call_loginpswwd_userdata), _aws_cred(param_private._aws_cred), ops_timeout(), connexion_timeout(), agent_string(param_private.agent_string), _proto(param_private._proto), _metalink_mode(param_private._metalink_mode), _customhdr(param_private._customhdr), _proxy_server(param_private._proxy_server), _session_flag(param_private._session_flag), _state_uid(param_private._state_uid), _transferCb(param_private._transferCb), retry_number(param_private.retry_number), retry_delay(param_private.retry_delay), _copy_mode(param_private._copy_mode){ timespec_copy(&(connexion_timeout), &(param_private.connexion_timeout)); timespec_copy(&(ops_timeout), &(param_private.ops_timeout)); } bool _ssl_check; // ssl CA check bool _redirection; // redirection support bool _recursive_mode; // recursive mode for get/put collections // s3 bucket listing mode S3ListingMode::S3ListingMode _s3_listing_mode; // Max number of keys returned by a S3 list bucket request unsigned long _s3_max_key_entries; // CA management std::vector _ca_path; // auth info boost::shared_ptr _x509_data; std::pair _idlogpass; authCallbackLoginPasswordBasic _call_loginpswwd; void* _call_loginpswwd_userdata; std::pair _aws_cred; // timeout management struct timespec ops_timeout; struct timespec connexion_timeout; // user agent std::string agent_string; // proto RequestProtocol::Protocol _proto; MetalinkMode::MetalinkMode _metalink_mode; // additional custom header lines HeaderVec _customhdr; // Proxy server URI boost::shared_ptr _proxy_server; // session flag int _session_flag; // ssl state value, a state uid is used to check if two copy of a requestParam struct are equal int _state_uid; // transfer cb TransferMonitorCB _transferCb; // retry attempts int retry_number; // delay in seconds between retry attempts int retry_delay; // 3rd party copy mode CopyMode::CopyMode _copy_mode; // method inline void regenerateStateUid(){ _state_uid = get_requeste_uid(); } private: RequestParamsInternal & operator=(const RequestParamsInternal & params); }; RequestParams::RequestParams() : d_ptr(new RequestParamsInternal()) { } RequestParams::RequestParams(const RequestParams& params) : d_ptr(new RequestParamsInternal(*(params.d_ptr))){ } RequestParams::~RequestParams(){ delete d_ptr; } RequestParams::RequestParams(const RequestParams* params) : d_ptr( ((params)?(new RequestParamsInternal(*(params->d_ptr))):(new RequestParamsInternal())) ){ } RequestParams & RequestParams::operator=(const RequestParams & orig){ if(d_ptr != orig.d_ptr) delete d_ptr; d_ptr = new RequestParamsInternal(*(orig.d_ptr)); return *this; } bool RequestParams::getSSLCACheck() const{ return d_ptr->_ssl_check; } void RequestParams::setSSLCAcheck(bool chk){ d_ptr->regenerateStateUid(); d_ptr->_ssl_check = chk; } void RequestParams::setClientCertX509(const X509Credential & cli_cert){ using namespace std; d_ptr->regenerateStateUid(); X509Data* x509 = X509Data::reset(d_ptr->_x509_data); x509->_cred = cli_cert; x509->_x509_fun = bind(&X509Data::cred_callback, x509, _1, _2); } void RequestParams::setClientLoginPassword(const std::string & login, const std::string & password){ d_ptr->regenerateStateUid(); d_ptr->_idlogpass = std::make_pair(login, password); } const std::pair & RequestParams::getClientLoginPassword() const{ return d_ptr->_idlogpass; } const X509Credential & RequestParams::getClientCertX509() const{ X509Data* x509 = X509Data::instance(d_ptr->_x509_data); return x509->_cred; } /// set a callback for X509 client side dynamic authentication /// this function overwrite \ref setClientCertX509 void RequestParams::setClientCertCallbackX509(authCallbackClientCertX509 callback, void* userdata){ using namespace std; d_ptr->regenerateStateUid(); X509Data* x509 = X509Data::reset(d_ptr->_x509_data); x509->_pair = std::make_pair(callback, userdata); x509->_x509_fun = bind(&X509Data::c_callback, x509, _1, _2); } void RequestParams::setClientCertFunctionX509(const authFunctionClientCertX509 &callback){ d_ptr->regenerateStateUid(); X509Data* x509 = X509Data::reset(d_ptr->_x509_data); x509->_x509_fun= callback; } const authFunctionClientCertX509 & RequestParams::getClientCertFunctionX509() const{ X509Data* x509 = X509Data::instance(d_ptr->_x509_data); return x509->_x509_fun; } /// return the current client side callback for authentification with the current user data std::pair RequestParams::getClientCertCallbackX509() const{ X509Data* x509 = X509Data::instance(d_ptr->_x509_data); return x509->_pair; } /// set a callback for X509 client side dynamic authentication /// this function overwrite \ref setClientCertX509 void RequestParams::setClientLoginPasswordCallback(authCallbackLoginPasswordBasic callback, void* userdata){ d_ptr->regenerateStateUid(); d_ptr->_call_loginpswwd = callback; d_ptr->_call_loginpswwd_userdata = userdata; } /// return the current client side callback for authentification with the current user data std::pair RequestParams::getClientLoginPasswordCallback() const{ return std::pair(d_ptr->_call_loginpswwd, d_ptr->_call_loginpswwd_userdata); } void RequestParams::setAwsAuthorizationKeys(const std::string &secret_key, const std::string &access_key){ d_ptr->_aws_cred = std::pair(secret_key,access_key); } const std::pair & RequestParams::getAwsAutorizationKeys() const{ return d_ptr->_aws_cred; } void RequestParams::setS3ListingMode(const S3ListingMode::S3ListingMode s3_listing_mode){ d_ptr->_s3_listing_mode = s3_listing_mode; } S3ListingMode::S3ListingMode RequestParams::getS3ListingMode() const{ return d_ptr->_s3_listing_mode; } void RequestParams::setS3MaxKey(const unsigned long s3_max_key_entries){ d_ptr->_s3_max_key_entries = s3_max_key_entries; } unsigned long RequestParams::getS3MaxKey() const{ return d_ptr->_s3_max_key_entries; } void RequestParams::addCertificateAuthorityPath(const std::string &path){ d_ptr->regenerateStateUid(); d_ptr->_ca_path.push_back(path); } const std::vector & RequestParams::listCertificateAuthorityPath() const{ return d_ptr->_ca_path; } void RequestParams::setConnectionTimeout(struct timespec *conn_timeout1){ timespec_copy(&(d_ptr->connexion_timeout),conn_timeout1); } void RequestParams::setOperationTimeout(struct timespec *ops_timeout1){ timespec_copy(&(d_ptr->ops_timeout), ops_timeout1); } const struct timespec* RequestParams::getConnectionTimeout() const { return &d_ptr->connexion_timeout; } const struct timespec* RequestParams::getOperationTimeout() const { return &d_ptr->ops_timeout; } void RequestParams::setTransparentRedirectionSupport(bool redirection){ d_ptr->regenerateStateUid(); d_ptr->_redirection = redirection; } bool RequestParams::getTransparentRedirectionSupport() const{ return d_ptr->_redirection; } void RequestParams::setOperationRetry(int number_retry){ d_ptr->retry_number = number_retry; } int RequestParams::getOperationRetry() const{ return d_ptr->retry_number; } void RequestParams::setOperationRetryDelay(int delay_retry){ d_ptr->retry_delay = delay_retry; } int RequestParams::getOperationRetryDelay() const{ return d_ptr->retry_delay; } void RequestParams::setTransfertMonitorCb(const TransferMonitorCB &cb){ d_ptr->_transferCb = cb; } const TransferMonitorCB & RequestParams::getTransferMonitorCb() const{ return d_ptr->_transferCb; } const std::string & RequestParams::getUserAgent() const{ return d_ptr->agent_string; } void RequestParams::setUserAgent(const std::string &user_agent){ d_ptr->regenerateStateUid(); d_ptr->agent_string = user_agent; } RequestProtocol::Protocol RequestParams::getProtocol() const { return d_ptr->_proto; } void RequestParams::setProtocol(const RequestProtocol::Protocol proto){ d_ptr->_proto = proto; } MetalinkMode::MetalinkMode RequestParams::getMetalinkMode() const{ return d_ptr->_metalink_mode; } void RequestParams::setMetalinkMode(const MetalinkMode::MetalinkMode mode){ d_ptr->_metalink_mode = mode; } void RequestParams::setKeepAlive(const bool keep_alive_flag){ d_ptr->regenerateStateUid(); if(keep_alive_flag) d_ptr->_session_flag |= SESSION_FLAG_KEEP_ALIVE; else d_ptr->_session_flag &= ~(SESSION_FLAG_KEEP_ALIVE); } bool RequestParams::getKeepAlive() const{ return d_ptr->_session_flag & SESSION_FLAG_KEEP_ALIVE; } void RequestParams::addHeader(const std::string &key, const std::string &val) { d_ptr->_customhdr.push_back( std::pair(key, val) ); } const HeaderVec & RequestParams::getHeaders() const{ return d_ptr->_customhdr; } void RequestParams::setProxyServer(const Uri &proxy_url){ d_ptr->_proxy_server.reset(new Uri(proxy_url)); } const Uri* RequestParams::getProxyServer() const{ return d_ptr->_proxy_server.get(); } void RequestParams::setCopyMode(const CopyMode::CopyMode copy_mode){ d_ptr->_copy_mode = copy_mode; } CopyMode::CopyMode RequestParams::getCopyMode() const{ return d_ptr->_copy_mode; } void RequestParams::setRecursiveMode(const bool recursive_mode){ d_ptr->_recursive_mode = recursive_mode; } bool RequestParams::getRecursiveMode() const{ return d_ptr->_recursive_mode; } // suppress useless warning #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" void* RequestParams::getParmState() const{ return (void*) (d_ptr->_state_uid); } void RequestParams::swap(RequestParams & p){ std::swap(d_ptr, p.d_ptr); } } // namespace Davix davix-R_0_5_0/src/request/000077500000000000000000000000001257152637300155445ustar00rootroot00000000000000davix-R_0_5_0/src/request/httprequest.cpp000066400000000000000000000336661257152637300206560ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include namespace Davix { ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// HttpRequest::HttpRequest(NEONRequest* req) : d_ptr(req) { } HttpRequest::HttpRequest(Context & context, const Uri & uri, DavixError** err) : d_ptr(new NEONRequest(*this, context,uri)){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_HTTP, "Creat HttpRequest for {}", uri.getString()); if(uri.getStatus() != StatusCode::OK){ DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format(" {} is not not a valid HTTP or Webdav URL", uri)); } } HttpRequest::HttpRequest(Context & context, const std::string & url, DavixError** err) : d_ptr(NULL){ Uri uri(url); d_ptr= new NEONRequest(*this, context, uri); if(uri.getStatus() != StatusCode::OK){ DavixError::setupError(err, davix_scope_http_request(), StatusCode::UriParsingError, fmt::format(" {} is not not a valid HTTP or Webdav URL", uri)); } } HttpRequest::~HttpRequest() { DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Destroy HttpRequest"); delete d_ptr; } void HttpRequest::setRequestMethod(const std::string &request_str){ d_ptr->setRequestMethod(request_str); } void HttpRequest::addHeaderField(const std::string &field, const std::string &value){ d_ptr->addHeaderField(field, value); } void HttpRequest::setParameters(const RequestParams &p){ d_ptr->setParameters(p); } void HttpRequest::setRequestBody(const std::string &body){ d_ptr->setRequestBody(body); } void HttpRequest::setRequestBody(const void *buffer, dav_size_t len_buff){ d_ptr->setRequestBody(buffer, len_buff); } void HttpRequest::setRequestBody(int fd, dav_off_t offset, dav_size_t len){ d_ptr->setRequestBody(fd, offset, len); } void HttpRequest::setRequestBody(HttpBodyProvider provider, dav_size_t len, void* udata){ d_ptr->setRequestBody(provider, len, udata); } int HttpRequest::getRequestCode(){ return d_ptr->getRequestCode(); } int HttpRequest::executeRequest(DavixError **err){ TRY_DAVIX{ runPreRunHook(); return d_ptr->executeRequest(err); }CATCH_DAVIX(err) return -1; } int HttpRequest::beginRequest(DavixError **err){ TRY_DAVIX{ // triggers Hooks runPreRunHook(); return d_ptr->beginRequest(err); }CATCH_DAVIX(err) return -1; } dav_ssize_t HttpRequest::readBlock(char *buffer, dav_size_t max_size, DavixError **err){ TRY_DAVIX{ return d_ptr->readBlock(buffer, max_size, err); }CATCH_DAVIX(err) return -1; } dav_ssize_t HttpRequest::readBlock(std::vector & buffer, dav_size_t max_size, DavixError **err){ dav_ssize_t ret=-1, v_size = (dav_ssize_t) buffer.size(); TRY_DAVIX{ buffer.resize(v_size + max_size); ret = readBlock(((char*) &buffer[0])+ v_size, max_size, err); buffer.resize(v_size + ( (ret > 0)?ret:0)); }CATCH_DAVIX(err) return ret; } dav_ssize_t HttpRequest::readSegment(char* buffer, dav_size_t max_size, DavixError** err){ return d_ptr->readSegment(buffer, max_size, err); } dav_ssize_t HttpRequest::readLine(char *buffer, dav_size_t max_size, DavixError **err){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Davix::Request::readLine want to read a line of max {} chars", max_size); dav_ssize_t ret= -1; TRY_DAVIX{ if( (ret = d_ptr->readLine(buffer, max_size, err)) >= 0){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Davix::Request::readLine got {} chars", ret); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_CORE, "Davix::Request::readLine content\n[[{}]]\n", std::string(buffer, ret)); } }CATCH_DAVIX(err) return ret; } void HttpRequest::discardBody(DavixError** err){ char buffer[1024]; dav_ssize_t read; TRY_DAVIX{ do { read = d_ptr->readSegment(buffer, sizeof(buffer), err); } while (read > 0 && *err == NULL); }CATCH_DAVIX(err) } dav_ssize_t HttpRequest::readToFd(int fd, DavixError** err){ TRY_DAVIX{ return d_ptr->readToFd(fd, 0, err); }CATCH_DAVIX(err) return -1; } dav_ssize_t HttpRequest::readToFd(int fd, dav_size_t read_size, DavixError** err){ TRY_DAVIX{ return d_ptr->readToFd(fd, read_size, err); }CATCH_DAVIX(err) return -1; } int HttpRequest::endRequest(DavixError **err){ TRY_DAVIX{ return d_ptr->endRequest(err); }CATCH_DAVIX(err) return -1; } void HttpRequest::clearAnswerContent(){ d_ptr->clearAnswerContent(); } bool HttpRequest::getAnswerHeader(const std::string &header_name, std::string &value) const{ return d_ptr->getAnswerHeader(header_name, value); } size_t HttpRequest::getAnswerHeaders( HeaderVec & vec_headers) const{ return d_ptr->getAnswerHeaders(vec_headers); } const char* HttpRequest::getAnswerContent(){ return d_ptr->getAnswerContent(); } std::vector & HttpRequest::getAnswerContentVec(){ return d_ptr->getAnswerContentVec(); } /// get content length dav_ssize_t HttpRequest::getAnswerSize() const{ return d_ptr->getAnswerSize(); } time_t HttpRequest::getLastModified() const{ return d_ptr->getLastModified(); } HttpCacheToken* HttpRequest::extractCacheToken()const{ return NULL; } void HttpRequest::useCacheToken(const HttpCacheToken *token){ (void) token; } /// set a HttpRequest flag void HttpRequest::setFlag(const RequestFlag::RequestFlag flag, bool value){ if(value) d_ptr->_req_flag |= flag; else d_ptr->_req_flag &= ~(flag); } /// get a HttpRequest flag value bool HttpRequest::getFlag(const RequestFlag::RequestFlag flag){ return d_ptr->_req_flag & ((int) flag); } void HttpRequest::runPreRunHook(){ // triggers Hooks RequestPreRunHook hook = d_ptr->_c.getHook(); if(hook){ hook(d_ptr->params, *this, *(d_ptr->_orig)); } } /////////////////////////////////////////////////// ///// Simplified request GET //////////////////////////////////////////////////// GetRequest::GetRequest(Context & context, const Uri & uri, DavixError** err) : HttpRequest(context, uri, err) { } /////////////////////////////////////////////////// ///// Simplified request PUT //////////////////////////////////////////////////// PutRequest::PutRequest(Context & context, const Uri & uri, DavixError** err) : HttpRequest(context, uri, err) { setRequestMethod("PUT"); setFlag(RequestFlag::SupportContinue100, true); setFlag(RequestFlag::IdempotentRequest, false); } /////////////////////////////////////////////////// ///// Simplified request POST //////////////////////////////////////////////////// PostRequest::PostRequest(Context & context, const Uri & uri, DavixError** err) : HttpRequest(context, uri, err) { setRequestMethod("POST"); //setFlag(RequestFlag::SupportContinue100, true); setFlag(RequestFlag::IdempotentRequest, false); } /////////////////////////////////////////////////// ///// Simplified request HEAD //////////////////////////////////////////////////// HeadRequest::HeadRequest(Context & context, const Uri & uri, DavixError** err) : HttpRequest(context, uri, err) { setRequestMethod("HEAD"); } /////////////////////////////////////////////////// ///// Simplified request DELETE //////////////////////////////////////////////////// DeleteRequest::DeleteRequest(Context & context, const Uri & uri, DavixError** err) : HttpRequest(context, uri, err) { setFlag(RequestFlag::IdempotentRequest, false); setRequestMethod("DELETE"); } /////////////////////////////////////////////////// ///// Simplified request PROPFIND //////////////////////////////////////////////////// PropfindRequest::PropfindRequest(Context & context, const Uri & uri, DavixError** err) : HttpRequest(context, uri, err) { setRequestMethod("PROPFIND"); } void httpcodeToDavixError(int code, const std::string &scope, const std::string & end_message, StatusCode::Code & dav_code, std::string & err_msg){ char const* str_msg = "Status Ok"; switch (code) { case 200: /* OK */ case 201: /* Created */ case 202: /* Accepted */ case 203: /* Non-Authoritative Information */ case 204: /* No Content */ case 206: /* partial content*/ case 205: /* Reset Content */ case 207: /* Multi-Status */ case 304: /* Not Modified */ dav_code = StatusCode::OK; str_msg = "Success"; break; case 401: /* Unauthorized */ case 402: /* Payment Required */ case 407: /* Proxy Authentication Required */ dav_code = StatusCode::AuthentificationError; str_msg = "Authentification Error"; break; case 303: /* See Other */ case 404: /* Not Found */ case 410: /* Gone */ dav_code = StatusCode::FileNotFound; str_msg = "File not found"; break; case 408: /* Request Timeout */ case 504: /* Gateway Timeout */ dav_code = StatusCode::OperationTimeout; str_msg = "Operation timeout"; break; case 409: if (scope == davix_scope_mkdir_str()){ dav_code = StatusCode::FileNotFound; str_msg = "Conflict, File not Found"; } else{ dav_code = StatusCode::FileExist; str_msg = "Conflict, File Exist"; } break; case 423: /* Locked */ case 403: /* Forbidden */ dav_code = StatusCode::PermissionRefused; str_msg = "Permission refused"; break; break; case 405: /* Method Not Allowed */ if (scope == davix_scope_mkdir_str()){ dav_code = StatusCode::FileExist; str_msg = "Method Not Allowed, File Exist"; } else{ dav_code = StatusCode::PermissionRefused; // Technically is a EPERM str_msg = "Method Not Allowed, Permission refused"; } break; case 400: /* Bad Request */ case 411: /* Length Required */ case 412: /* Precondition Failed */ case 414: /* Request-URI Too Long */ case 415: /* Unsupported Media Type */ case 424: /* Failed Dependency */ case 501: /* Not Implemented */ case 413: /* Request Entity Too Large */ case 507: /* Insufficient Storage */ dav_code = StatusCode::ConnectionProblem; str_msg = "Server Error"; break; case 301: /* Moved Permanently */ case 300: /* Multiple Choices */ case 302: /* Found */ dav_code = StatusCode::RedirectionNeeded; str_msg = "Redirection requested, transparent redirection disabled"; break; case 305: /* Use Proxy */ case 306: /* (Unused) */ case 307: /* Temporary Redirect */ case 406: /* Not Acceptable */ case 416: /* Requested Range Not Satisfiable */ case 417: /* Expectation Failed */ case 422: /* Unprocessable Entity */ case 500: /* Internal Server Error */ case 502: /* Bad Gateway */ case 503: /* Service Unavailable */ case 505: /* HTTP Version Not Supported */ default: dav_code = StatusCode::UnknowError; str_msg = "Unexcepted Server Error"; break; } err_msg.assign(fmt::format("HTTP {} : {} {}", code, str_msg, end_message)); } void httpcodeToDavixError(int code, const std::string & scope, const std::string & end_message, DavixError** err){ StatusCode::Code davix_code; std::string err_msg; httpcodeToDavixError(code, scope, end_message, davix_code, err_msg); DavixError::setupError(err, scope, davix_code, err_msg); } void httpcodeToDavixException(int code, const std::string & scope, const std::string & end_message){ StatusCode::Code davix_code; std::string err_msg; httpcodeToDavixError(code, scope, end_message, davix_code, err_msg); throw DavixException(scope, davix_code, err_msg); } bool httpcodeIsValid(int code) { switch (code) { case 200: /* OK */ case 201: /* Created */ case 202: /* Accepted */ case 203: /* Non-Authoritative Information */ case 204: /* No Content */ case 206: /* partial content */ case 205: /* Reset Content */ case 207: /* Multi-Status */ case 304: /* Not Modified */ return true; default: return false; } } } // namespace Davix davix-R_0_5_0/src/status/000077500000000000000000000000001257152637300153775ustar00rootroot00000000000000davix-R_0_5_0/src/status/davixstatusrequest.cpp000066400000000000000000000163251257152637300221020ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include namespace Davix { struct DavixErrorInternal{ DavixErrorInternal(const std::string &scope, StatusCode::Code errCode, const std::string &errMsg) : _scope(scope), _code(errCode), _errMsg(errMsg){ } DavixErrorInternal(const DavixErrorInternal & e) : _scope(e._scope), _code(e._code), _errMsg(e._errMsg){ } std::string _scope; StatusCode::Code _code; std::string _errMsg; }; DavixError::DavixError(const std::string &scope, StatusCode::Code errCode, const std::string &errMsg) : d_ptr(new DavixErrorInternal(scope, errCode, errMsg)){ } DavixError::DavixError(const DavixError & e) : d_ptr(new DavixErrorInternal(*(e.d_ptr))){ } DavixError & DavixError::operator =(const DavixError & e){ DavixError tmp(e); this->swap(tmp); return *this; } DavixError::~DavixError(){ delete d_ptr; } DavixError* DavixError::clone(){ return new DavixError(*this); } const std::string & DavixError::getErrMsg() const{ return d_ptr->_errMsg; } void DavixError::setErrMsg(const std::string &msg){ d_ptr->_errMsg = msg; } void DavixError::setStatus(const StatusCode::Code c){ d_ptr->_code = c; } StatusCode::Code DavixError::getStatus() const{ return d_ptr->_code; } const std::string & DavixError::getErrScope() const{ return d_ptr->_scope; } void DavixError::setErrScope(const std::string &scope){ d_ptr->_scope = scope; } void DavixError::setupError(DavixError **err, const std::string &scope, StatusCode::Code errCode, const std::string &errMsg){ if(err){ if(*err){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Error Override of previous DavixError, BUG !"); // error msg } *err = new DavixError(scope, errCode, errMsg); } } void DavixError::propagateError(DavixError **newErr, DavixError *oldErr){ propagatePrefixedError(newErr, oldErr, ""); } void DavixError::propagatePrefixedError(DavixError **newErr, DavixError *oldErr, const std::string &prefix){ if(oldErr== NULL) return; if(newErr){ if(*newErr != NULL){ std::cerr << "***ERROR*** in propagateError, *newErr is not NULL impossible to overwrite ... " " old error was" << oldErr->getErrMsg()<< std::endl; }else{ *newErr = oldErr; if(*newErr && prefix.empty() == false){ std::string new_mess(prefix); new_mess.append(" "); (*newErr)->d_ptr->_errMsg = new_mess.append((*newErr)->d_ptr->_errMsg); } } } } void DavixError::swap(DavixError &err){ std::swap(d_ptr, err.d_ptr); } void DavixError::clearError(DavixError **err){ if(err && *err){ delete *err; *err = NULL; } } void errno_to_davix_exception(int errno_code, const std::string &scope, const std::string &msg){ DavixError* tmp_err=NULL; davix_errno_to_davix_error(errno_code, scope, msg, &tmp_err); checkDavixError(&tmp_err); } void davix_errno_to_davix_error(int errcode, const std::string & scope, const std::string & msg, DavixError** newErr){ StatusCode::Code c; std::string msg_final; switch(errcode){ case 0: return; case ENOENT: c = StatusCode::FileNotFound; msg_final = "File not found " + msg; break; case EPERM: case EACCES: c = StatusCode::PermissionRefused; msg_final = "Permission refused " + msg; break; case EISDIR: c = StatusCode::IsADirectory; msg_final = "is a directory " + msg; break; case EINVAL: c = StatusCode::InvalidArgument; msg_final = "invalid argument " + msg; break; case EIO: c = StatusCode::InvalidArgument; msg_final = "Input/output error" + msg; break; case ENOTDIR: c = StatusCode::IsNotADirectory; msg_final = "is not a directory" + msg; break; default: c = StatusCode::SystemError; msg_final = std::string(strerror(errcode)) + " " + msg; } DavixError::setupError(newErr, scope, c, msg_final); } // extension struct DavixException::DavixExceptionIntern{ }; DavixException::DavixException(const std::string &scope, StatusCode::Code c, const std::string &msg) throw() : std::exception(), e(scope, c, msg), d_ptr(NULL){ } DavixException::DavixException(const DavixException &orig) throw() : e(orig.e), d_ptr(orig.d_ptr) { } DavixException::DavixException(DavixError **err) : std::exception(), e( "Davix::Error", StatusCode::UnknowError, "Error, no valid DavixError triggered"), d_ptr(NULL){ if(err != NULL && *err != NULL){ e.swap(**err); DavixError::clearError(err); } } void checkDavixError(DavixError **err){ if(err && *err){ throw DavixException(err); } } DavixException::~DavixException() throw(){ delete d_ptr; } const char* DavixException::what() const throw() { return e.getErrMsg().c_str(); } StatusCode::Code DavixException::code() const throw(){ return e.getStatus(); } const char* DavixException::scope() const throw(){ return e.getErrScope().c_str(); } void DavixException::toDavixError(DavixError **err){ DavixError::propagateError(err, new DavixError(this->e)); } std::string davix_scope_stat_str(){ return "Davix::stat"; } std::string davix_scope_mkdir_str(){ return "Davix::mkdir"; } std::string davix_scope_rm_str(){ return "Davix::rm"; } std::string davix_scope_mv_str(){ return "Davix::mv"; } std::string davix_scope_directory_listing_str(){ return "Davix::Posix::listdir"; } std::string davix_scope_http_request(){ return "Davix::HttpRequest"; } std::string davix_scope_meta(){ return "Davix::MetaDataOps"; } std::string davix_scope_xml_parser(){ return "Davix::XMLParser"; } std::string davix_scope_uri_parser(){ return "Davix::Uri::Parser"; } std::string davix_scope_davOps_str(){ return "Davix::Dav::Ops"; } std::string davix_scope_io_buff(){ return "Davix::IO:Buff"; } std::string davix_scope_x509cred(){ return "Davix::X509cred"; } } // namespace Davix davix-R_0_5_0/src/tools/000077500000000000000000000000001257152637300152145ustar00rootroot00000000000000davix-R_0_5_0/src/tools/CMakeLists.txt000066400000000000000000000076541257152637300177700ustar00rootroot00000000000000# main file for command line tools # LIST(APPEND davix_main_src "davix_tool_main.cpp") LIST(APPEND davix_ls_main_src "davix_tool_ls_main.cpp") LIST(APPEND davix_get_main_src "davix_tool_get_main.cpp") LIST(APPEND davix_put_main_src "davix_tool_put_main.cpp") LIST(APPEND davix_rm_main_src "davix_tool_rm_main.cpp") LIST(APPEND davix_mkcol_main_src "davix_tool_mkcol_main.cpp") LIST(APPEND davix_mv_main_src "davix_tool_mv_main.cpp") LIST(APPEND davix_copy_main_src "davix_tool_copy_main.cpp") LIST(APPEND davix_tool_common_src "${CMAKE_CURRENT_SOURCE_DIR}/davix_tool_params.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/davix_tool_util.cpp" "${SRC_SIMPLE_GET_PASS}" "${CMAKE_CURRENT_SOURCE_DIR}/davix_op.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/davix_taskqueue.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/davix_thread.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/davix_thread_pool.cpp") SET(davix_tool_common_src_up "${davix_tool_common_src}" PARENT_SCOPE) link_directories(${PROJECT_BINARY_DIR}/src/) add_definitions(-DNO_BOOST_INCLUDE) ## rt link set(RT_LIBRARIES "") if(HAVE_CLOCK_GETTIME) set(RT_LIBRARIES "rt") endif(HAVE_CLOCK_GETTIME) ## davix tool lib add_library(davix_tool_lib STATIC ${davix_tool_common_src}) ## davix cmd line add_executable(davix_tool ${davix_main_src}) target_link_libraries(davix_tool davix_tool_lib davix ${RT_LIBRARIES}) set_target_properties(davix_tool PROPERTIES OUTPUT_NAME "davix-http") add_dependencies(davix_tool libdavix) ## davix ls cmd line add_executable(davix_ls_tool ${davix_ls_main_src}) target_link_libraries(davix_ls_tool davix_tool_lib davix ${CMAKE_THREAD_LIBS_INIT} ${RT_LIBRARIES}) set_target_properties(davix_ls_tool PROPERTIES OUTPUT_NAME "davix-ls") add_dependencies(davix_ls_tool libdavix) ## davix get cmd line add_executable(davix_get_tool ${davix_get_main_src}) target_link_libraries(davix_get_tool davix_tool_lib davix pthread ${CMAKE_THREAD_LIBS_INIT} ${RT_LIBRARIES}) set_target_properties(davix_get_tool PROPERTIES OUTPUT_NAME "davix-get") add_dependencies(davix_get_tool libdavix) ## davix put cmd line add_executable(davix_put_tool ${davix_put_main_src}) target_link_libraries(davix_put_tool davix_tool_lib davix pthread ${CMAKE_THREAD_LIBS_INIT} ${RT_LIBRARIES}) set_target_properties(davix_put_tool PROPERTIES OUTPUT_NAME "davix-put") add_dependencies(davix_put_tool libdavix) ## davix del cmd line add_executable(davix_mkdir_tool ${davix_mkcol_main_src}) target_link_libraries(davix_mkdir_tool davix_tool_lib davix ${RT_LIBRARIES}) set_target_properties(davix_mkdir_tool PROPERTIES OUTPUT_NAME "davix-mkdir") add_dependencies(davix_mkdir_tool libdavix) ## davix rm cmd line add_executable(davix_rm_tool ${davix_rm_main_src}) target_link_libraries(davix_rm_tool davix_tool_lib davix ${CMAKE_THREAD_LIBS_INIT} ${RT_LIBRARIES}) set_target_properties(davix_rm_tool PROPERTIES OUTPUT_NAME "davix-rm") add_dependencies(davix_rm_tool libdavix) ## davix mv cmd line add_executable(davix_mv_tool ${davix_mv_main_src}) target_link_libraries(davix_mv_tool davix_tool_lib davix ${RT_LIBRARIES}) set_target_properties(davix_mv_tool PROPERTIES OUTPUT_NAME "davix-mv") add_dependencies(davix_mv_tool libdavix) install(TARGETS davix_tool davix_ls_tool davix_get_tool davix_put_tool davix_mkdir_tool davix_rm_tool davix_mv_tool DESTINATION ${BIN_INSTALL_DIR}/) ## davix cp cmd line if (ENABLE_THIRD_PARTY_COPY) add_executable(davix_cp_tool ${davix_copy_main_src}) target_link_libraries(davix_cp_tool davix_copy davix_tool_lib ${RT_LIBRARIES}) set_target_properties(davix_cp_tool PROPERTIES OUTPUT_NAME "davix-cp") add_dependencies(davix_cp_tool davix_copy) install(TARGETS davix_cp_tool DESTINATION ${BIN_INSTALL_DIR}/) endif (ENABLE_THIRD_PARTY_COPY) davix-R_0_5_0/src/tools/davix_mutex.hpp000066400000000000000000000027551257152637300202730ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_MUTEX_HPP #define DAVIX_MUTEX_HPP #include // Simple wrapper for scoped mutex namespace Davix{ class DavixMutex{ public: DavixMutex(pthread_mutex_t& mutex) : _mutex(mutex) { pthread_mutex_lock(&_mutex); } ~DavixMutex() { pthread_mutex_unlock(&_mutex); } void lock() { pthread_mutex_lock(&_mutex); } void unlock() { pthread_mutex_unlock(&_mutex); } pthread_mutex_t* getMutex() { return &_mutex; } private: pthread_mutex_t& _mutex; }; } #endif // DAVIX_MUTEX_HPP davix-R_0_5_0/src/tools/davix_op.cpp000066400000000000000000000435621257152637300175430ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "davix_op.hpp" #include "davix_taskqueue.hpp" #include #include #include #include namespace Davix{ //------------------------------------------------- //----------------------DavixOp-------------------- //------------------------------------------------- DavixOp::DavixOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, Context& c) : _target_url(target_url), _destination_url(destination_url), _opts(opts), _c(c), _scope() { } DavixOp::~DavixOp(){} std::string DavixOp::getTargetUrl(){ return _target_url; } std::string DavixOp::getDestinationUrl(){ return _destination_url; } std::string DavixOp::getOpType(){ return opType; } //------------------------------------------------- //----------------------GetOp---------------------- //------------------------------------------------- GetOp::GetOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, Context& c) : DavixOp(opts, target_url, destination_url, c) { opType = "GET"; _scope = "Davix::DavixOp::GetOp"; } GetOp::~GetOp(){} int GetOp::executeOp(){ int ret = -1; int fd = -1; DavixError* tmp_err=NULL; DavFile f(_c, _target_url); if((fd = getOutFd())> 0){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "{} executing op on ", _scope, _target_url); ret = f.getToFd(&_opts.params, fd, &tmp_err); //if getToFd failed, remove the just created blank local file if(tmp_err){ std::cerr << std::endl << _scope << " Failed to GET " << _target_url << std::endl; Tool::errorPrint(&tmp_err); remove(_destination_url.c_str()); } close(fd); } return ret; } int GetOp::getOutFd(){ DavixError* tmp_err=NULL; int fd = -1; if(_destination_url.empty() == false){ // for S3 we have to split the key into tokens and create a dir for each token if (_opts.params.getProtocol() == RequestProtocol::AwsS3){ if((Tool::mkdirP(_destination_url, true)) < 0 ){ std::cerr << std::endl << _scope << " Failed to create local directory for " << _destination_url << std::endl; return -1; } } if((fd = open(_destination_url.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0777)) <0 ){ davix_errno_to_davix_error(errno, _scope, std::string("while opening/creating ").append(_destination_url), &tmp_err); if(tmp_err){ Tool::errorPrint(&tmp_err); } return -1; } }else{ fd = dup(STDOUT_FILENO); } return fd; } //------------------------------------------------- //----------------------PutOp---------------------- //------------------------------------------------- PutOp::PutOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, dav_size_t file_size, Context& c) : DavixOp(opts, target_url, destination_url, c) { opType = "PUT"; _scope = "Davix::DavixOp::PutOp"; _file_size = file_size; } PutOp::~PutOp(){} int PutOp::executeOp(){ DavixError* tmp_err=NULL; int fd = -1; if( (fd = getInFd(&tmp_err)) < 0){ if(tmp_err) Tool::errorPrint(&tmp_err); return -1; } TRY_DAVIX{ DavFile f(_c, _destination_url); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "{} executing op on ", _scope, _destination_url); f.put(&_opts.params, fd, _file_size); close(fd); return 0; }CATCH_DAVIX(&tmp_err); if(fd != -1) close(fd); if(tmp_err->getStatus() == StatusCode::FileExist){ std::cerr << std::endl << _scope << " " << _destination_url << " already exists, continuing..." << std::endl; } else std::cerr << std::endl << _scope << " Failed to PUT " << _target_url << std::endl; Tool::errorPrint(&tmp_err); return -1; } int PutOp::getInFd(DavixError** err){ int fd = -1; if(_target_url.empty() == false){ if((fd = open(_target_url.c_str(), O_RDONLY)) <0 ){ davix_errno_to_davix_error(errno, _scope, std::string("for source file ").append(_target_url), err); return -1; } }else{ fd = dup(STDOUT_FILENO); } return fd; } //------------------------------------------------- //--------------------DeleteOp--------------------- //------------------------------------------------- DeleteOp::DeleteOp(const Tool::OptParams& opts, std::string destination_url, Context& c, std::string buf) : DavixOp(opts, "", destination_url, c) { opType = "DELETE"; _scope = "Davix::DavixOp::DeleteOp"; _buf = buf; } DeleteOp::~DeleteOp(){} int DeleteOp::executeOp(){ DavixError* tmp_err=NULL; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "{} executing op on ", _scope, _destination_url); if(_opts.params.getProtocol() == RequestProtocol::AwsS3){ _destination_url += "/?delete"; PostRequest req(_c, _destination_url, &tmp_err); if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } req.setParameters(_opts.params); std::ostringstream ss; ss << _buf.size(); // calculate md5 of body and set header fields, these are required for S3 multi-objects delete std::string md5; S3::calculateMD5(_buf, md5); req.addHeaderField("Content-MD5", md5); req.addHeaderField("Content-Length", ss.str()); req.setRequestBody(_buf); req.executeRequest(&tmp_err); if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } // check response code int code = req.getRequestCode(); if(!httpcodeIsValid(code)){ httpcodeToDavixError(req.getRequestCode(), davix_scope_http_request(), "during S3 multi-objects delete operation", &tmp_err); if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } } std::vector body = req.getAnswerContentVec(); TRY_DAVIX{ parse_deletion_result(code, Uri(_destination_url), _scope, body); }CATCH_DAVIX(&tmp_err); if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } } else{ // cases other than s3, not implenmented for now. WebDAV delete collection already works without the -r switch return -1; } return 0; } void DeleteOp::parse_deletion_result(int code, const Uri & u, const std::string & scope, const std::vector & body){ switch(code){ case 200:{ // if s3 && scope was davix_scope_rm_str() && batch delete, parse body S3DeleteParser parser; parser.parseChunk(&(body[0]), body.size()); // check if any of the delete request entry is flagged as error, if so, just print them for now if( parser.getDeleteStatus().size() > 0){ for(unsigned int i=0; i < parser.getDeleteStatus().size(); ++i){ if(parser.getDeleteStatus().at(i).error){ std::ostringstream ss; ss << "Error: " << parser.getDeleteStatus().at(i).error_code << " -> " << parser.getDeleteStatus().at(i).message << " encountered while atempting to delete " << parser.getDeleteStatus().at(i).filename; std::cerr << std::endl << ss.str() << std::endl; } return; } // if no properties, status were filtered because invalid httpcodeToDavixException(404, scope); return; } } case 201: case 202: case 204:{ return; } case 207:{ // parse webdav DavDeleteXMLParser parser; parser.parseChunk(&(body[0]), body.size()); if( parser.getProperties().size() > 0){ for(unsigned int i=0; i < parser.getProperties().size(); ++i){ const int sub_code = parser.getProperties().at(i).req_status; std::ostringstream ss; ss << "occurred during deletion request for " << parser.getProperties().at(i).filename; if(httpcodeIsValid(sub_code) == false){ httpcodeToDavixException(sub_code, scope, ss.str()); } } return; } // if no properties, properties were filtered because invalid httpcodeToDavixException(404, scope); break; } } std::ostringstream ss; ss << " with url " << u.getString(); httpcodeToDavixException(code, scope, ss.str()); } //------------------------------------------------- //---------------------ListOp---------------------- //------------------------------------------------- ListOp::ListOp(const Tool::OptParams& opts, std::string target_url, Context& c, DavixTaskQueue* listing_tq, FILE* filestream, pthread_mutex_t& output_mutex) : DavixOp(opts, target_url, "NULL", c), _listing_tq(listing_tq), _filestream(filestream), _output_mutex(output_mutex) { opType = "LIST"; _scope = "Davix::DavixOp::ListOp"; } ListOp::~ListOp(){} void ListOp::display_file_entry(const std::string & filename, const Tool::OptParams & opts, FILE* filestream){ (void) opts; fputs(filename.c_str(), filestream); fputs("\n",filestream); } void ListOp::display_long_file_entry(const std::string & filename, struct stat* st, const Tool::OptParams & opts, FILE* filestream){ (void) opts; std::ostringstream ss; ss << Tool::string_from_mode(st->st_mode) << " "; ss << Tool::string_from_size_t(static_cast(st->st_nlink),4) << " "; ss << Tool::string_from_size_t(st->st_size, 9) << " "; ss << Tool::string_from_ptime(st->st_mtime) << " "; ss << filename << "\n"; fputs(ss.str().c_str(), filestream); } int ListOp::executeOp(){ DAVIX_DIR* fd = NULL; DavPosix pos(&_c); DavixError* tmp_err=NULL; std::string outputPath; struct stat st; struct dirent* d; unsigned long entry_counter = 0; std::string last_success_entry; std::deque > dirQueue; std::deque fileQueue; // set up first entry if(!_target_url.empty()){ dirQueue.push_back(std::make_pair(_target_url, _destination_url)); } else DavixError::setupError(&tmp_err, "Davix::ListOp", StatusCode::InvalidArgument, " target URL is empty."); if( (fd = pos.opendirpp(&_opts.params, dirQueue.front().first, &tmp_err)) == NULL){ Tool::errorPrint(&tmp_err); return -1; } Uri tmp(_target_url); std::string fullpath = tmp.getPath(); if(fullpath[0] == '/') fullpath.erase(0,1); while( ((d = pos.readdirpp(fd, &st, &tmp_err)) != NULL)){ // if one entry inside a directory fails, the loop exits, the other entires are not processed last_success_entry = dirQueue.front().first+d->d_name; // for each entry, see if it's a directory, if yes, push to dirQueue for further processing if(st.st_mode & S_IFDIR){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Directory entry found, pushing {}/ to dirQueue", dirQueue.front().first+d->d_name); dirQueue.push_back(std::make_pair(dirQueue.front().first+d->d_name+"/", fullpath+d->d_name)); } else{ fileQueue.push_back(fullpath+d->d_name); } } // while readdirpp if(tmp_err){ Tool::errorPrint(&tmp_err); std::cerr << std::endl << "Error occured during listing " << dirQueue.front().first << " Number of entries processed in current directory: " << entry_counter << ". Continuing..."<< std::endl; std::cerr << std::endl << "Last succesful entry is " << last_success_entry << std::endl; } entry_counter = 0; pos.closedirpp(fd, NULL); dirQueue.pop_front(); // discard parent entry { // lock this part so the output is sync'ed // this should also ensure all the child ops are ordered in the taskqueue DavixMutex mutex(_output_mutex); for(unsigned int i=0; i < dirQueue.size(); ++i){ //push listing op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to (listing) work queue, target is {}.", dirQueue[i].first); ListOp* l_op = new ListOp(_opts, dirQueue[i].first, _c, _listing_tq, _filestream, _output_mutex); _listing_tq->pushOp(l_op); if(_opts.pres_flag & LONG_LISTING_FLAG){ display_long_file_entry(dirQueue[i].second, &st, _opts, _filestream); }else{ display_file_entry(dirQueue[i].second, _opts, _filestream); } } for(unsigned int i=0; i < fileQueue.size(); ++i){ if(_opts.pres_flag & LONG_LISTING_FLAG){ display_long_file_entry(fileQueue[i], &st, _opts, _filestream); }else{ display_file_entry(fileQueue[i], _opts, _filestream); } } } if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } return 0; } //------------------------------------------------- //---------------------ListppOp---------------------- //------------------------------------------------- ListppOp::ListppOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, Context& c, DavixTaskQueue* tq, DavixTaskQueue* listing_tq) : DavixOp(opts, target_url, destination_url, c) { opType = "LISTPP"; _scope = "Davix::DavixOp::ListppOp"; _tq = tq; _listing_tq = listing_tq; } ListppOp::~ListppOp(){} int ListppOp::executeOp(){ DAVIX_DIR* fd = NULL; DavPosix pos(&_c); DavixError* tmp_err=NULL; std::string outputPath; struct stat st; struct dirent* d; unsigned long entry_counter=0; std::string last_success_entry; std::deque > dirQueue; std::deque > opQueue; // set up first entry if(!_target_url.empty() && !_destination_url.empty()){ dirQueue.push_back(std::make_pair(_target_url, _destination_url)); } else DavixError::setupError(&tmp_err, "Davix::ListppOp", StatusCode::InvalidArgument, " target or destination URL is empty."); if( (fd = pos.opendirpp(&_opts.params, dirQueue.front().first, &tmp_err)) == NULL){ Tool::errorPrint(&tmp_err); return -1; } // dir opened successfully, create local dir Tool::mkdirP(dirQueue.front().second, false); while( ((d = pos.readdirpp(fd, &st, &tmp_err)) != NULL)){ // if one entry inside a directory fails, the loop exits, the other entires are not processed last_success_entry = dirQueue.front().first+d->d_name; // for each entry, see if it's a directory, if yes, push to dirQueue for further processing if(st.st_mode & S_IFDIR){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Directory entry found, pushing {}/ to dirQueue", dirQueue.front().first+d->d_name); dirQueue.push_back(std::make_pair(dirQueue.front().first+d->d_name+"/",dirQueue.front().second+"/"+d->d_name)); } else if(!(st.st_mode & S_IFDIR)){ //if we spend too long in here, server will likely close the connection mid-readdirpp, need to get all the entries quickly before processing them opQueue.push_back(std::make_pair(dirQueue.front().first+d->d_name, dirQueue.front().second+"/"+d->d_name)); entry_counter++; } } // while readdirpp if(tmp_err){ Tool::errorPrint(&tmp_err); std::cerr << std::endl << "Error occured during listing " << dirQueue.front().first << " Number of entries processed in current directory: " << entry_counter << ". Continuing..."<< std::endl; std::cerr << std::endl << "Last succesful entry is " << last_success_entry << std::endl; } pos.closedirpp(fd, NULL); dirQueue.pop_front(); for(unsigned int i=0; i < dirQueue.size(); ++i){ //push listing op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to (listing) work queue, target is {} and destination is {}.", dirQueue[i].first, dirQueue[i].second); ListppOp* l_op = new ListppOp(_opts, (dirQueue[i].first), (dirQueue[i].second), _c, _tq, _listing_tq); _listing_tq->pushOp(l_op); } for(unsigned int i=0; i < opQueue.size(); ++i){ //push op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to (get) work queue, target is {} and destination is {}.", opQueue[i].first, opQueue[i].second); GetOp* op = new GetOp(_opts, (opQueue[i].first), (opQueue[i].second), _c); _tq->pushOp(op); } if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } return 0; } } // namespace Davix davix-R_0_5_0/src/tools/davix_op.hpp000066400000000000000000000076241257152637300175470ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_OP_HPP #define DAVIX_OP_HPP #include #include #include #include namespace Davix{ class DavixOp{ protected: std::string _target_url; std::string _destination_url; std::string opType; Tool::OptParams _opts; Context& _c; std::string _scope; DavixOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, Context& c); //virtual ~DavixOp(); public: virtual int executeOp()=0; virtual ~DavixOp(); std::string getTargetUrl(); std::string getDestinationUrl(); std::string getOpType(); private: }; class GetOp : public DavixOp{ public: GetOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, Context& c); virtual ~GetOp(); virtual int executeOp(); int getOutFd(); private: }; class PutOp : public DavixOp{ public: PutOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, dav_size_t file_size, Context& c); virtual ~PutOp(); virtual int executeOp(); int getInFd(DavixError** err); private: dav_size_t _file_size; }; class DeleteOp : public DavixOp{ public: // for s3 batch delete, need post request and body DeleteOp(const Tool::OptParams& opts, std::string destination_url, Context& c, std::string buf); // for anything else DeleteOp(const Tool::OptParams& opts, std::string destination_url, Context& c); virtual ~DeleteOp(); virtual int executeOp(); std::string calculateMD5(std::string content, DavixError** err); void parse_deletion_result(int code, const Uri & u, const std::string & scope, const std::vector & body); private: std::string _buf; }; // forward declaration class DavixTaskQueue; // ListOp, used in davix-ls for recursively crawling the namespace class ListOp : public DavixOp{ public: ListOp(const Tool::OptParams& opts, std::string target_url, Context& c, DavixTaskQueue* listing_tq, FILE* filestream, pthread_mutex_t& output_mutex); virtual ~ListOp(); virtual int executeOp(); private: DavixTaskQueue* _listing_tq; FILE* _filestream; pthread_mutex_t& _output_mutex; static void display_file_entry(const std::string & filename, const Tool::OptParams & opts, FILE* filestream); static void display_long_file_entry(const std::string & filename, struct stat* st, const Tool::OptParams & opts, FILE* filestream); }; // ListppOp, used in davix-get for recursively crawling namespace and getting files // different than ListOp, doesn't print out info of entries, instead, it populates another taskqueue with GetOps class ListppOp : public DavixOp{ public: ListppOp(const Tool::OptParams& opts, std::string target_url, std::string destination_url, Context& c, DavixTaskQueue* tq, DavixTaskQueue* listing_tq); virtual ~ListppOp(); virtual int executeOp(); private: DavixTaskQueue* _tq; DavixTaskQueue* _listing_tq; }; } #endif // DAVIX_OP_HPP davix-R_0_5_0/src/tools/davix_taskqueue.cpp000066400000000000000000000117131257152637300211250ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "davix_taskqueue.hpp" #include #include namespace Davix{ DavixTaskQueue::DavixTaskQueue(){ pthread_mutex_init(&tq_mutex, NULL); pthread_cond_init(&popOpConvar, NULL); pthread_cond_init(&pushOpConvar, NULL); _shutdown = false; _no_cap = false; _queueType = QueueType::FIFO; } DavixTaskQueue::DavixTaskQueue(const Tool::OptParams& opts, QueueType::QueueType queueType){ pthread_mutex_init(&tq_mutex, NULL); pthread_cond_init(&popOpConvar, NULL); pthread_cond_init(&pushOpConvar, NULL); _shutdown = false; _no_cap = opts.no_cap; _queueType = queueType; } int DavixTaskQueue::pushOp(DavixOp* op){ { DavixMutex mutex(tq_mutex); // for recursive namespace crawling, we set a hard limit to the number of listing ops are allowed to prevent overflow // not the ideal solution, perhaps disk-backing the queue after a certain threshold would be better if((op->getOpType() == "LIST") || op->getOpType() == "LISTPP"){ if(!_no_cap && (taskQueue.size() > MAX_NUM_OF_LISTING_OPS)){ // queue size balloning out of control, warn and exit std::cerr << std::endl << "***Task queue's size has exceeded the maximum allowed, exiting programme!***" << std::endl; exit(-1); } } else{ while(taskQueue.size() >= DAVIX_DEFAULT_TASKQUEUE_SIZE) pthread_cond_wait(&pushOpConvar, mutex.getMutex()); } taskQueue.push_back(op); } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixTaskQueue) {} Op pushed to taskQueue, target is {}, queue size is now: {}", op->getOpType(), op->getTargetUrl(), taskQueue.size()); pthread_cond_signal(&popOpConvar); return 0; } DavixOp* DavixTaskQueue::popOp(){ bool dosig = false; DavixOp* op = NULL; //struct timespec to; { DavixMutex mutex(tq_mutex); while(taskQueue.empty() && !_shutdown){ /* * to.tv_sec = time(NULL) + DEFAULT_WAIT_TIME; * to.tv_nsec = 0; * int rc = pthread_cond_timedwait(&popOpConvar, mutex.getMutex(), &to); * * if(rc == ETIMEDOUT) * { * std::cerr << std::endl << "(DavixTaskQueue) PopOp() timed out." << std::endl; * return NULL; } } */ pthread_cond_wait(&popOpConvar, mutex.getMutex()); if(_shutdown){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixTaskQueue) Shutting down task queue, queue size is: {}", taskQueue.size()); return NULL; } } if(taskQueue.size() > 0){ switch(_queueType){ case QueueType::FIFO: { op = taskQueue.front(); taskQueue.pop_front(); break; } case QueueType::LIFO: { op = taskQueue.back(); taskQueue.pop_back(); break; } } // end switch dosig = true; } } // end mutex scope if (dosig) { DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixTaskQueue) {} Op popped from taskQueue, queue size is now: {}", op->getOpType(), taskQueue.size()); pthread_cond_signal(&pushOpConvar); return op; } return NULL; } int DavixTaskQueue::getSize(){ DavixMutex mutex(tq_mutex); return taskQueue.size(); } bool DavixTaskQueue::isEmpty(){ DavixMutex mutex(tq_mutex); return taskQueue.empty(); } void DavixTaskQueue::shutdown(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixTaskQueue) Commencing shutdown..."); _shutdown = true; pthread_cond_broadcast(&pushOpConvar); pthread_cond_broadcast(&popOpConvar); } bool DavixTaskQueue::isStopped(){ return _shutdown; } } davix-R_0_5_0/src/tools/davix_taskqueue.hpp000066400000000000000000000034771257152637300211420ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_TASKQUEUE_HPP #define DAVIX_TASKQUEUE_HPP #include #include #include #include #include #define DEFAULT_WAIT_TIME 30 #define MAX_NUM_OF_LISTING_OPS 2000000 namespace Davix{ namespace QueueType{ enum QueueType{ // first in first out FIFO, // last in first out LIFO }; } class DavixTaskQueue{ public: DavixTaskQueue(); DavixTaskQueue(const Tool::OptParams& opts, QueueType::QueueType queueType); int pushOp(DavixOp* op); DavixOp* popOp(); int getSize(); bool isEmpty(); void shutdown(); bool isStopped(); private: std::deque taskQueue; pthread_mutex_t tq_mutex; pthread_cond_t popOpConvar; pthread_cond_t pushOpConvar; bool _shutdown; bool _no_cap; QueueType::QueueType _queueType; }; } #endif // DAVIX_TASKQUEUE_HPP davix-R_0_5_0/src/tools/davix_thread.cpp000066400000000000000000000061521257152637300203660ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "davix_thread.hpp" #include namespace Davix{ DavixThread::DavixThread(DavixTaskQueue* tq, int id) : threadId(id), _tq(tq), worker(), state(WorkerState::IDLE), event(WorkerEvent::WORK) { } DavixThread::~DavixThread(){} int DavixThread::createWorkerThread(){ if(pthread_create(&worker, NULL, startThread, (void*)this) != 0){ return -1; } return 0; } void* DavixThread::startThread(void* args){ DavixThread* worker = (DavixThread*)args; worker->run(); return 0; } int DavixThread::run(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixThread) Worker thread: {} started", threadId); while(true){ switch(event){ case WorkerEvent::WORK: { DavixOp* op = NULL; op = _tq->popOp(); if(op != NULL){ state = WorkerState::BUSY; int ret = op->executeOp(); if(ret < 0){ if(op->getOpType() == "DELETE") DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixThread) Worker thread: {} failed to execute op on {}.", threadId, op->getDestinationUrl()); else DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixThread) Worker thread: {} failed to execute op on {}.", threadId, op->getTargetUrl()); } delete op; state = WorkerState::IDLE; } break; } case WorkerEvent::STOP: { return 0; break; } } // if task queue is not running, nothing to do, exit if(_tq->isStopped()) return 0; } return 0; } pthread_t& DavixThread::getWorkerHandle(){ return worker; } int DavixThread::getThreadId(){ return threadId; } void DavixThread::shutdown(){ state = WorkerState::STOPPING; event = WorkerEvent::STOP; } WorkerState::WorkerState DavixThread::getWorkerState(){ return state; } } // namespace Davix davix-R_0_5_0/src/tools/davix_thread.hpp000066400000000000000000000036371257152637300204000ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_THREAD_HPP #define DAVIX_THREAD_HPP #include #include #include namespace Davix{ namespace WorkerState{ enum WorkerState { IDLE, BUSY, STOPPING }; } namespace WorkerEvent{ enum WorkerEvent { WORK, STOP }; } class DavixThread{ private: int threadId; bool _isFree; DavixTaskQueue* _tq; pthread_t worker; pthread_cond_t eventConvar; public: /* enum WorkerState { IDLE, BUSY, STOPPING }state; enum WorkerEvent { WORK, STOP }event; */ WorkerState::WorkerState state; WorkerEvent::WorkerEvent event; DavixThread(DavixTaskQueue* tq, int id); ~DavixThread(); int createWorkerThread(); static void* startThread(void* args); int run(); pthread_t& getWorkerHandle(); void shutdown(); int getThreadId(); WorkerState::WorkerState getWorkerState(); }; } #endif // DAVIX_THREAD_HPP davix-R_0_5_0/src/tools/davix_thread_pool.cpp000066400000000000000000000055741257152637300214260ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include namespace Davix{ DavixThreadPool::DavixThreadPool(DavixTaskQueue* tq, const int pool_size) : _tq(tq), threadCount(0), _pool_size(pool_size) { init(); } DavixThreadPool::~DavixThreadPool(){ for(int i=0; i<_pool_size; ++i){ if(tp[i]) delete tp[i]; } if(tp) delete tp; } void DavixThreadPool::init(){ tp = new DavixThread*[_pool_size]; if(tp){ for(int i=0; i<_pool_size; ++i){ tp[i] = NULL; tp[i] = new DavixThread(_tq, i); if(tp[i] != NULL){ tp[i]->createWorkerThread(); threadCount++; } else std::cerr << std::endl << "Failed to create worker thread: " << i << std::endl; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixThreadPool) Threadpool initiated. Number of worker threads is: {}", threadCount); } else std::cerr << std::endl << "Failed to init threadpool!" << std::endl; } void DavixThreadPool::shutdown(){ int count = 0; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixThreadPool) Shutting down threadpool. Number of threads to join: {}", threadCount); _tq->shutdown(); for(int i=0; i<_pool_size; ++i){ if(tp[i] != NULL){ tp[i]->shutdown(); if(pthread_join(tp[i]->getWorkerHandle(), NULL) != 0){ std::cerr << std::endl << "Failed to join worker thread: " << i << std::endl; continue; } count++; } } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "(DavixThreadPool) Threadpool stopped. Number of threads joined: {}/{}", count, threadCount); } int DavixThreadPool::getThreadCount(){ return threadCount; } bool DavixThreadPool::allThreadsIdle(){ for(int i = 0; i < threadCount; ++i){ if(tp[i]->getWorkerState() == WorkerState::BUSY) return false; } return true; } } davix-R_0_5_0/src/tools/davix_thread_pool.hpp000066400000000000000000000026601257152637300214240ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_THREAD_POOL_HPP #define DAVIX_THREAD_POOL_HPP #include #include #include #include namespace Davix{ class DavixThreadPool{ public: DavixThreadPool(DavixTaskQueue* tq, const int pool_size); ~DavixThreadPool(); void init(); void shutdown(); int getThreadCount(); bool allThreadsIdle(); private: DavixTaskQueue* _tq; int threadCount; int _pool_size; DavixThread** tp; }; } #endif // DAVIX_THREAD_POOL_HPP davix-R_0_5_0/src/tools/davix_tool_copy_main.cpp000066400000000000000000000045711257152637300221350ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include using namespace Davix; using namespace std; const std::string scope_main = "Davix::Tools::davix"; std::string get_base_copy_options(){ return " Copy Options:\n" "\t--copy-mode: 3rd party copy mode - push(default) or pull\n"; } static void performanceCallback(const PerformanceData& perfData, void *udata) { (void) udata; std::cout << perfData.totalTransferred() << " (" << perfData.avgTransfer() << " bytes/sec)" << std::endl; } static std::string help_msg(const std::string & cmd_path){ std::string help_str = fmt::format("Usage : {} ", cmd_path); help_str += Tool::get_copy_description_options(); help_str += get_base_copy_options(); help_str += Tool::get_common_options(); return help_str; } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); if( (retcode= Tool::parse_davix_copy_options(argc, argv, opts, &tmp_err)) ==0){ Context c; if( (retcode = Tool::configureAuth(opts)) == 0){ configureContext(c, opts); DavixCopy copy(c, &opts.params); copy.setPerformanceCallback(performanceCallback, NULL); copy.copy(opts.vec_arg[0], opts.vec_arg[1], 1, &tmp_err); } } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_get_main.cpp000066400000000000000000000245651257152637300217470ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 // @author : Devresse Adrien // main file for davix-get operation using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_get = "Davix::Tools::davix-get"; std::string get_base_get_options(){ return " Get Options:\n" "\t-r NUMBER_OF_THREADS: Get directories and their contents recursively.\n"; } static std::string help_msg(const std::string &cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_get_description_options(); help_msg += Tool::get_common_options(); help_msg += get_base_get_options(); return help_msg; } int get_output_get_fstream(const Tool::OptParams & opts, const std::string & scope, std::string uri, DavixError** err){ int fd = -1; if(uri.empty() == false){ if((fd = open(uri.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0777)) <0 ){ davix_errno_to_davix_error(errno, scope, std::string("for destination file ").append(opts.output_file_path), err); return -1; } }else{ fd = dup(STDOUT_FILENO); } return fd; } static int excute_get(Context& c, const Tool::OptParams & opts, int out_fd, std::string uri, DavixError** err){ int ret; DavFile f(c, uri); ret = f.getToFd(&opts.params, out_fd, err); return (ret >= 0)?0:-1; } static int populateTaskQueue(Context& c, const Tool::OptParams & opts, std::string uri, DavixTaskQueue* tq, DavixTaskQueue* listing_tq, DavixError** err ){ DAVIX_DIR* fd = NULL; DavPosix pos(&c); DavixError* tmp_err=NULL; std::string outputPath; struct stat st; struct dirent* d; int entry_counter=0; std::string last_success_entry; std::deque > dirQueue; std::deque > opQueue; outputPath = opts.output_file_path; // set up first entry if(!uri.empty()){ // if output path is not specified, default to current directory if(outputPath.empty()){ std::deque dirVec; std::string tmp = Uri(uri).getPath(); if(tmp == "/"){ // no output path and no token in url to use as default, fallback to ./temp outputPath = "./temp"; } else{ Tool::tokeniseUrl(Uri(uri).getPath(), dirVec); outputPath = "./"+dirVec.back(); } } dirQueue.push_back(std::make_pair(uri, outputPath)); } else DavixError::setupError(&tmp_err, "Davix::Tool::Get", StatusCode::InvalidArgument, " target URL is empty."); if( (fd = pos.opendirpp(&opts.params, dirQueue.front().first, &tmp_err)) == NULL){ Tool::errorPrint(&tmp_err); // if the "root" level cannot be found, there is nothing we can do, just quit return -1; } // dir opened successfully, create local dir Tool::mkdirP(dirQueue.front().second, false); //if S3, remove last token of url to accommodate duplicate token in d_name if (opts.params.getProtocol() == RequestProtocol::AwsS3){ dirQueue.front().first = "s3://"+(Uri(dirQueue.front().first).getHost())+"/"; } while( ((d = pos.readdirpp(fd, &st, &tmp_err)) != NULL)){ // if one entry inside a directory fails, the loop exits, the other entires are not processed last_success_entry = dirQueue.front().first+d->d_name; // for each entry, do a stat to see if it's a directory, if yes, push to dirQueue for further processing if(st.st_mode & S_IFDIR){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Directory entry found, pushing {}/ to dirQueue", dirQueue.front().first+d->d_name); dirQueue.push_back(std::make_pair(dirQueue.front().first+d->d_name+"/",dirQueue.front().second+"/"+d->d_name)); } else if(!(st.st_mode & S_IFDIR)){ //if we spend too long in here, server will likely close the connection mid-readdirpp, need to get all the entries quickly before processing them opQueue.push_back(std::make_pair(dirQueue.front().first+d->d_name, dirQueue.front().second+"/"+d->d_name)); } entry_counter++; if(!opts.debug) Tool::batchTransferMonitor(dirQueue.front().first, "Crawling", entry_counter, 0); } // while readdirpp if(tmp_err){ Tool::errorPrint(&tmp_err); cerr << endl << "Error occured during listing " << dirQueue.front().first << " Number of entries processed in current directory: " << entry_counter << ". Continuing..."<< endl; cerr << endl << "Last succesful entry is " << last_success_entry << endl; } entry_counter = 0; pos.closedirpp(fd, NULL); dirQueue.pop_front(); int num_of_ops = opQueue.size(); int num_listing_ops = dirQueue.size(); // if endpoint is S3 then there is no need to crawl namespace recursively, since it's flat if (opts.params.getProtocol() != RequestProtocol::AwsS3){ for(unsigned int i=0; i < dirQueue.size(); ++i){ //push listing op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to (listing) work queue, target is {} and destination is {}.", dirQueue[i].first, dirQueue[i].second); entry_counter++; if(!opts.debug) Tool::batchTransferMonitor(dirQueue[i].first, "Populating (listing) task queue for", entry_counter, num_listing_ops); ListppOp* l_op = new ListppOp(opts, (dirQueue[i].first), (dirQueue[i].second), c, tq, listing_tq); listing_tq->pushOp(l_op); } entry_counter = 0; } for(unsigned int i=0; i < opQueue.size(); ++i){ //push op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to (get) work queue, target is {} and destination is {}.", opQueue[i].first, opQueue[i].second); entry_counter++; if(!opts.debug) Tool::batchTransferMonitor(opQueue[i].first, "Populating (get) task queue for", entry_counter, num_of_ops); GetOp* op = new GetOp(opts, (opQueue[i].first), (opQueue[i].second), c); tq->pushOp(op); } if(tmp_err){ DavixError::propagateError(err, tmp_err); return -1; } return 0; } static int preGetCheck(Tool::OptParams & opts, DavixError** err ) { Context c; configureContext(c, opts); File f(c, opts.vec_arg[0]); struct stat st; DavixError* tmp_err=NULL; // Try to understand what to do // If the URL is for plain HTTP then we don't want to stat bool justgetfile = true; if ( opts.vec_arg[0].compare(0, 4, "http") != 0 ) { int r = f.stat(&opts.params, &st, &tmp_err); if (r && tmp_err) { DavixError::propagateError(err, tmp_err); return -1; } if ( !r && (st.st_mode & S_IFDIR) && opts.params.getRecursiveMode()) justgetfile = false; } if (justgetfile) { // target resource is a file or request protocol is http, just get it normally int out_fd= -1; if( ( (out_fd = get_output_get_fstream(opts, scope_get, opts.output_file_path, &tmp_err)) > 0) && (Tool::configureMonitorCB(opts, Transfer::Read)) == 0) { excute_get(c, opts, out_fd, opts.vec_arg[0], &tmp_err); Tool::flushFinalLineShell(out_fd); close(out_fd); } } else { std::string url(opts.vec_arg[0]); if (url[url.size()-1] != '/') url += '/'; // if protocol is S3, set listing mode to SemiHierarchical, we want to get every object under the same prefix in one go if (opts.params.getProtocol() == RequestProtocol::AwsS3){ opts.params.setS3ListingMode(S3ListingMode::SemiHierarchical); // unfortunately s3 defaults max-keys to 1000 and doesn't provide a way to disable the cap, set to large number opts.params.setS3MaxKey(999999999); } DavixTaskQueue tq; // for get ops DavixTaskQueue listing_tq; // for listing ops // create threadpool instance DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Creating threadpool"); DavixThreadPool tp(&tq, opts.threadpool_size); DavixThreadPool listing_tp(&listing_tq, opts.threadpool_size); populateTaskQueue(c, opts, url, &tq, &listing_tq, &tmp_err); // if both task queues are empty, then all work is done, stop workers. Otherwise wait. do{ sleep(2); }while(!tq.isEmpty() || !listing_tq.isEmpty() || !tp.allThreadsIdle() || !listing_tp.allThreadsIdle()); listing_tp.shutdown(); tp.shutdown(); Tool::flushFinalLineShell(STDOUT_FILENO); } if(tmp_err){ DavixError::propagateError(err, tmp_err); return -1; } return 0; } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); if( (retcode= Tool::parse_davix_get_options(argc, argv, opts, &tmp_err)) ==0 && (retcode = Tool::configureAuth(opts)) == 0){ retcode = preGetCheck(opts, &tmp_err); } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_ls_main.cpp000066400000000000000000000224021257152637300215720ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 // @author : Devresse Adrien // main file for davix ls tool using namespace Davix; using namespace std; std::string get_base_listing_options(){ return " Listing Options:\n" "\t--long-list, -l: long Listing mode\n" "\t-r NUMBER_OF_THREADS List directories's content recursively using multiple threads\n" "\t--no-cap: Disable size cap on task queue for pending listing operations\n" "\t--s3-listing: S3 bucket listing mode - flat, semi or hierarchical(default)\n" "\t--s3-maxkeys: Maximum number of entries returns by S3 list bucket request. default: 10000\n"; } static std::string help_msg(const std::string & cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_base_description_options(); help_msg += Tool::get_common_options(); help_msg += get_base_listing_options(); return help_msg; } static void display_file_entry(const std::string & filename, const Tool::OptParams & opts, FILE* filestream){ (void) opts; fputs(filename.c_str(), filestream); fputs("\n",filestream); } static void display_long_file_entry(const std::string & filename, struct stat* st, const Tool::OptParams & opts, FILE* filestream){ (void) opts; std::ostringstream ss; ss << Tool::string_from_mode(st->st_mode) << " "; ss << Tool::string_from_size_t(static_cast(st->st_nlink),4) << " "; ss << Tool::string_from_size_t(st->st_size, 9) << " "; ss << Tool::string_from_ptime(st->st_mtime) << " "; ss << filename << "\n"; fputs(ss.str().c_str(), filestream); } static int listing(const Tool::OptParams & opts, FILE* filestream, DavixError** err ){ DAVIX_DIR* fd = NULL; Context c; configureContext(c, opts); DavPosix pos(&c); struct stat st; struct dirent* d; if( (fd = pos.opendirpp(&opts.params, opts.vec_arg[0], err)) == NULL) return -1; while( (d = pos.readdirpp(fd, &st, err)) != NULL ){ if(opts.pres_flag & LONG_LISTING_FLAG){ display_long_file_entry(d->d_name, &st, opts, filestream); }else{ display_file_entry(d->d_name, opts, filestream); } } pos.closedirpp(fd, NULL); return (err && *err)?(-1):0; } static int get_info(const Tool::OptParams & opts, FILE* filestream, DavixError** err ){ Context c; configureContext(c, opts); File f(c, opts.vec_arg[0]); struct stat st; if( f.stat(&opts.params, &st, err) == 0){ if(opts.pres_flag & LONG_LISTING_FLAG){ if( opts.params.getProtocol() == RequestProtocol::AwsS3){ std::string tmp(opts.vec_arg[0]); display_long_file_entry(tmp.substr(tmp.rfind('/')+1), &st, opts, filestream); } else{ display_long_file_entry(opts.vec_arg[0], &st, opts, filestream); } }else{ display_file_entry(opts.vec_arg[0], opts, filestream); } return 0; } return -1; } static int populateTaskQueue(Context& c, const Tool::OptParams & opts, std::string uri, DavixTaskQueue* listing_tq, DavixError** err, FILE* filestream, pthread_mutex_t& output_mutex){ DAVIX_DIR* fd = NULL; DavPosix pos(&c); DavixError* tmp_err=NULL; std::string outputPath; struct stat st; struct dirent* d; unsigned long entry_counter = 0; std::string last_success_entry; std::deque dirQueue; // set up first entry if(!uri.empty()){ dirQueue.push_back(uri); } else DavixError::setupError(&tmp_err, "Davix::ListOp", StatusCode::InvalidArgument, " target URL is empty."); if( (fd = pos.opendirpp(&opts.params, dirQueue.front(), &tmp_err)) == NULL){ Tool::errorPrint(&tmp_err); return -1; } Uri tmp(uri); std::string fullpath = tmp.getPath(); if(fullpath[0] == '/') fullpath.erase(0,1); while( ((d = pos.readdirpp(fd, &st, &tmp_err)) != NULL)){ // if one entry inside a directory fails, the loop exits, the other entires are not processed last_success_entry = dirQueue.front()+d->d_name; // for each entry, do a stat to see if it's a directory, if yes, push to dirQueue for further processing if(st.st_mode & S_IFDIR){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Directory entry found, pushing {}/ to dirQueue", dirQueue.front()+d->d_name); dirQueue.push_back(dirQueue.front()+d->d_name+"/"); } if(opts.pres_flag & LONG_LISTING_FLAG){ display_long_file_entry(fullpath+d->d_name, &st, opts, filestream); }else{ display_file_entry(fullpath+d->d_name, opts, filestream); } } // while readdirpp if(tmp_err){ Tool::errorPrint(&tmp_err); std::cerr << std::endl << "Error occured during listing " << dirQueue.front() << " Number of entries processed in current directory: " << entry_counter << ". Continuing..."<< std::endl; std::cerr << std::endl << "Last succesful entry is " << last_success_entry << std::endl; } pos.closedirpp(fd, NULL); dirQueue.pop_front(); for(unsigned int i=0; i < dirQueue.size(); ++i){ //push listing op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to (listing) work queue, target is {}.", dirQueue[i]); ListOp* l_op = new ListOp(opts, dirQueue[i], c, listing_tq, filestream, output_mutex); listing_tq->pushOp(l_op); } if(tmp_err){ Tool::errorPrint(&tmp_err); return -1; } return 0; } static int recursiveListing(const Tool::OptParams & opts, FILE* filestream, DavixError** err ){ Context c; configureContext(c, opts); File f(c, opts.vec_arg[0]); DavixError* tmp_err=NULL; std::string url(opts.vec_arg[0]); if (url[url.size()-1] != '/') url += '/'; DavixTaskQueue listing_tq(opts, QueueType::LIFO); // for listing ops // init output mutex for child listOps, only one listOp can output to a stream at a given time pthread_mutex_t output_mutex; pthread_mutex_init(&output_mutex, NULL); // create threadpool instance DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Creating threadpool"); DavixThreadPool listing_tp(&listing_tq, opts.threadpool_size); populateTaskQueue(c, opts, url, &listing_tq, &tmp_err, filestream, output_mutex); do{ sleep(2); }while((!listing_tq.isEmpty()) || !(listing_tp.allThreadsIdle())); listing_tp.shutdown(); Tool::flushFinalLineShell(STDOUT_FILENO); if(tmp_err){ DavixError::propagateError(err, tmp_err); return -1; } return 0; } int main(int argc, char** argv){ int retcode; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); FILE* fstream = stdout; if( (retcode= Tool::parse_davix_ls_options(argc, argv, opts, &tmp_err)) ==0){ if( (retcode = Tool::configureAuth(opts)) == 0){ // if recursive and S3 if(opts.params.getRecursiveMode() && (opts.vec_arg[0].compare(0,2,"s3") ==0)){ // don't need to use -r switch for S3, just set listing mode to SemiHierarchical and do a normal listing opts.params.setS3ListingMode(S3ListingMode::SemiHierarchical); // unfortunately s3 defaults max-keys to 1000 and doesn't provide a way to disable the cap, set to large number opts.params.setS3MaxKey(999999999); retcode = listing(opts, fstream, &tmp_err); } else if(opts.params.getRecursiveMode()){ // dav recursive listing retcode = recursiveListing(opts, fstream, &tmp_err); } else{ // normal listing retcode = listing(opts, fstream, &tmp_err); } // just a single file if(retcode < 0 && tmp_err->getStatus() == StatusCode::IsNotADirectory){ DavixError::clearError(&tmp_err); retcode = get_info(opts, fstream, &tmp_err); } } } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_main.cpp000066400000000000000000000060371257152637300211020ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include // @author : Devresse Adrien // main file for davix low level cmd line tool using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_main = "Davix::Tools::davix"; static void configureRequest(HttpRequest& req, Tool::OptParams & opts){ req.setParameters(opts.params); if(opts.req_type.empty() == false) req.setRequestMethod(opts.req_type); req.setRequestBody(opts.req_content); } static std::string get_request_options(){ return " Request Options: \n" "\t--data Content of the request\n" "\t--request, -X: Request operation to use (ex : GET, PUT, PROPFIND, etc..)\n" "\n" ; } static std::string help_msg(const std::string & cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_base_description_options(); help_msg += Tool::get_common_options(); help_msg += get_request_options(); return help_msg; } static int read_stream(HttpRequest* req, int fd_out, DavixError** err){ if(req->beginRequest(err) <0 || req->readToFd(fd_out, err) < 0) return -1; return req->endRequest(err); } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); int out_fd; if( (retcode= Tool::parse_davix_options(argc, argv, opts, &tmp_err)) ==0){ Context c; configureContext(c, opts); if( (out_fd= Tool::getOutFd(opts, scope_main, &tmp_err)) > 0 && (retcode = Tool::configureAuth(opts)) == 0){ HttpRequest req(c, opts.vec_arg[0], &tmp_err); if( tmp_err == NULL){ configureRequest(req, opts); retcode= read_stream(&req, out_fd, &tmp_err); Tool::flushFinalLineShell(out_fd); close(out_fd); }else{ retcode =-1; } } } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_mkcol_main.cpp000066400000000000000000000037721257152637300222720ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include // @author : Devresse Adrien // main file for davix make collection cmd line tool using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_main = "Davix::Tools::davix-mkcol"; static std::string help_msg(const std::string & cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_base_description_options(); help_msg += Tool::get_common_options(); return help_msg; } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); if( (retcode= Tool::parse_davix_options(argc, argv, opts, &tmp_err)) ==0){ Context c; if( (retcode = Tool::configureAuth(opts)) == 0){ configureContext(c, opts); DavFile f(c,opts.vec_arg[0]); f.makeCollection(&opts.params, &tmp_err); } } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_mkdir_main.cpp000066400000000000000000000035561257152637300222730ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include // @author : Devresse Adrien // main file for davix mkdir cmd line tool using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_main = "Davix::Tools::davix"; static std::string help_msg(const std::string & cmd_path){ return Tool::get_base_description_options() + Tool::get_common_options(); } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); if( (retcode= Tool::parse_davix_options(argc, argv, opts, &tmp_err)) ==0){ Context c; if( (retcode = Tool::configureAuth(opts, &tmp_err)) == 0){ DavFile f(c,opts.vec_arg[0]); f.makeCollection(&opts.params, &tmp_err); } } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_mv_main.cpp000066400000000000000000000040731257152637300216020ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Kwong Tat Cheung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_main = "Davix::Tools::davix-mv"; static std::string help_msg(const std::string & cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_base_description_options(); help_msg += Tool::get_common_options(); return help_msg; } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); TRY_DAVIX{ if( (retcode= Tool::parse_davix_options(argc, argv, opts, &tmp_err)) ==0){ Context c; if( (retcode = Tool::configureAuth(opts)) == 0){ configureContext(c, opts); File source(c, opts.vec_arg[0]), dest(c, opts.vec_arg[1]); source.move(&opts.params, dest); retcode =0; } } }CATCH_DAVIX(&tmp_err){ retcode = -1; } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_params.cpp000066400000000000000000000424411257152637300214400ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "davix_tool_params.hpp" #include "davix_tool_util.hpp" #include #include #include namespace Davix{ namespace Tool{ const std::string scope_params = "Davix::Tools::Params"; #define CAPATH_OPT 1000 #define DEBUG_OPT 1001 #define USER_LOGIN 1002 #define USER_PASSWORD 1003 #define DATA_CONTENT 1004 #define S3_SECRET_KEY 1005 #define S3_ACCESS_KEY 1006 #define X509_PRIVATE_KEY 1007 #define TRACE_OPTIONS 1008 #define REDIRECTION_OPT 1009 #define METALINK_OPT 1010 #define CONN_TIMEOUT 1011 #define TIMEOUT_OPS 1012 #define RETRY_OPT 1013 #define S3_LISTING_MODE 1014 #define S3_MAX_KEYS 1015 #define RETRY_DELAY_OPT 1016 #define HAS_INPUT_FILE 1017 #define THIRD_PT_COPY_MODE 1018 #define DISABLE_LISTING_CAP 1019 // LONG OPTS #define COMMON_LONG_OPTIONS \ {"debug", no_argument, 0, DEBUG_OPT }, \ {"header", required_argument, 0, 'H' }, \ {"help", no_argument, 0,'?'}, \ {"metalink", required_argument, 0, METALINK_OPT }, \ {"module", required_argument, 0, 'P'}, \ {"proxy", required_argument, 0, 'x'}, \ {"redirection", required_argument, 0, REDIRECTION_OPT }, \ {"conn-timeout", required_argument, 0, CONN_TIMEOUT }, \ {"retry", required_argument, 0, RETRY_OPT }, \ {"retry-delay", required_argument, 0, RETRY_DELAY_OPT }, \ {"timeout", required_argument, 0, TIMEOUT_OPS }, \ {"trace", required_argument, 0, TRACE_OPTIONS }, \ {"infile", required_argument, 0, HAS_INPUT_FILE }, \ {"version", no_argument, 0, 'V'} #define SECURITY_LONG_OPTIONS \ {"cert", required_argument, 0, 'E' }, \ {"capath", required_argument, 0, CAPATH_OPT }, \ {"key", required_argument, 0, X509_PRIVATE_KEY}, \ {"userlogin", required_argument, 0, USER_LOGIN}, \ {"userpass", required_argument, 0, USER_PASSWORD}, \ {"s3secretkey", required_argument, 0, S3_SECRET_KEY}, \ {"s3accesskey", required_argument, 0, S3_ACCESS_KEY}, \ {"insecure", no_argument, 0, 'k' } #define REQUEST_LONG_OPTIONS \ {"request", required_argument, 0, 'X' }, \ {"data", required_argument, 0, DATA_CONTENT}, \ {"verbose", no_argument, 0, 0 } #define LISTING_LONG_OPTIONS \ {"s3-listing", required_argument, 0, S3_LISTING_MODE }, \ {"s3-maxkeys", required_argument, 0, S3_MAX_KEYS }, \ {"no-cap", required_argument, 0, DISABLE_LISTING_CAP}, \ {"long-list", no_argument, 0, 'l' } #define COPY_LONG_OPTIONS \ {"copy-mode", required_argument, 0, THIRD_PT_COPY_MODE } OptParams::OptParams() : params(), vec_arg(), debug(false), s3_delete_per_request(20), threadpool_size(10), req_type(), help_msg(), cred_path(), priv_key(), output_file_path(), input_file_path(), userlogpasswd(), req_content(), aws_auth(), pres_flag(0), shell_flag(0), has_input_file(false), no_cap(false) { } static void option_abort(char** argv){ std::cerr << argv[0] <<", Error: Wrong argument format\n"; std::cerr << "Try '" << argv[0] <<" --help' for more informations" << std::endl; exit(-1); } static void display_version(){ std::cout << "Version: " << version() << std::endl; exit(0); } template Y match_option(T begin, T end, Y begin_res, Y end_res, Z val, char** argv){ Y res = match_array(begin, end, begin_res, end_res, val); if(res == end_res){ option_abort(argv); } return res; } static int set_header_field(const std::string & arg, OptParams & p, DavixError** err){ dav_size_t pos; if( (pos = arg.find(':') ) == std::string::npos){ DavixError::setupError(err, scope_params, StatusCode::InvalidArgument, " Invalid header field argument"); return -1; } p.params.addHeader(arg.substr(0,pos), arg.substr(pos+1)); return 0; } static void set_metalink_opt(RequestParams & params, const std::string & metalink_opt, char** argv){ const std::string str_opt[] = { "no" , "disable", "auto", "failover" }; const Davix::MetalinkMode::MetalinkMode mode_opt[] = { MetalinkMode::Disable, MetalinkMode::Disable, MetalinkMode::Auto, MetalinkMode::FailOver }; params.setMetalinkMode(*match_option(str_opt, str_opt+sizeof(str_opt)/sizeof(str_opt[0]), mode_opt, mode_opt + sizeof(mode_opt)/sizeof(mode_opt[0]), metalink_opt, argv)); } static void set_redirection_opt(RequestParams & params, const std::string & redir_opt, char** argv){ const std::string str_opt[] = { "no" , "yes", "auto"}; const bool mode_opt[] = { false, true, true }; params.setTransparentRedirectionSupport(*match_option(str_opt, str_opt+sizeof(str_opt)/sizeof(str_opt[0]), mode_opt, mode_opt + sizeof(mode_opt)/sizeof(mode_opt[0]), redir_opt, argv)); } static int parse_int(const std::string & opt, char** argv){ try{ return toType()(opt); }catch(...){ std::cerr << "Invalid option value " << opt << std::endl; option_abort(argv); } return 0; } static struct timespec parse_timeout(const std::string & opt, char** argv){ int t = parse_int(opt, argv); struct timespec timelapse; timelapse.tv_sec =t; timelapse.tv_nsec =0; return timelapse; } int parse_davix_options_generic(const std::string &opt_filter, const struct option* long_options, int argc, char** argv, OptParams & p, DavixError** err){ int ret =0; int option_index=0; while( (ret = getopt_long(argc, argv, opt_filter.c_str(), long_options, &option_index)) > 0){ switch(ret){ case DEBUG_OPT: p.debug = true; // max log level setLogLevel(DAVIX_LOG_TRACE); setLogScope(DAVIX_LOG_SCOPE_ALL ^ DAVIX_LOG_XML); break; case 'E': p.cred_path = SanitiseTildedPath(optarg); break; case 'k': p.params.setSSLCAcheck(false); break; case 'H': if( set_header_field(optarg, p, err) <0) return -1; break; case S3_LISTING_MODE: { if(std::string(optarg).compare("flat")==0) p.params.setS3ListingMode(S3ListingMode::Flat); else if(std::string(optarg).compare("hierarchical")==0) p.params.setS3ListingMode(S3ListingMode::Hierarchical); else if(std::string(optarg).compare("semi")==0) p.params.setS3ListingMode(S3ListingMode::SemiHierarchical); break; } case S3_MAX_KEYS: p.params.setS3MaxKey(atoi(optarg)); break; case CAPATH_OPT: p.params.addCertificateAuthorityPath(optarg); break; case USER_LOGIN: p.userlogpasswd.first = optarg; break; case X509_PRIVATE_KEY: p.priv_key = SanitiseTildedPath(optarg).c_str(); break; case USER_PASSWORD: p.userlogpasswd.second = optarg; break; case DATA_CONTENT: p.req_content = optarg; break; case RETRY_OPT: p.params.setOperationRetry( parse_int(optarg, argv)); break; case RETRY_DELAY_OPT: p.params.setOperationRetryDelay( parse_int(optarg, argv)); break; case S3_ACCESS_KEY: p.aws_auth.second = optarg; break; case S3_SECRET_KEY: p.aws_auth.first = optarg; break; case 'l': p.pres_flag |= LONG_LISTING_FLAG; break; case 'o': p.output_file_path = optarg; break; case 'P': p.modules_list = StrUtil::tokenSplit(std::string(optarg), ","); break; case 'V': display_version(); return 1; case TRACE_OPTIONS: { p.debug = true; setLogScope(0); setLogScope(std::string(optarg)); setLogLevel(DAVIX_LOG_TRACE); } break; case 'x': p.params.setProxyServer(std::string(optarg, 0, 2048)); break; case 'X': p.req_type = std::string(optarg, 0, 255); break; case METALINK_OPT: set_metalink_opt(p.params, std::string(optarg), argv); break; case REDIRECTION_OPT: set_redirection_opt(p.params, std::string(optarg), argv); break; case CONN_TIMEOUT:{ struct timespec s =parse_timeout(std::string(optarg), argv); p.params.setConnectionTimeout(&s); } break; case TIMEOUT_OPS:{ struct timespec s =parse_timeout(std::string(optarg), argv); p.params.setOperationTimeout(&s); break; } case HAS_INPUT_FILE:{ p.has_input_file = true; p.input_file_path = optarg; } break; case THIRD_PT_COPY_MODE:{ if(std::string(optarg).compare("pull")==0) p.params.setCopyMode(CopyMode::Pull); else if(std::string(optarg).compare("push")==0) p.params.setCopyMode(CopyMode::Push); break; } case DISABLE_LISTING_CAP:{ p.no_cap = true; break; } case 'r':{ p.params.setRecursiveMode(true); p.threadpool_size = atoi(optarg); break; } case 'n':{ p.s3_delete_per_request = (atoi(optarg)); break; } case '?': std::cout << p.help_msg; exit(1); break; default: option_abort(argv); } } ret =-1; for(int i = optind; i < argc; ++i){ p.vec_arg.push_back(argv[i]); ret =0; } if(ret != 0){ option_abort(argv); } return ret; } int parse_davix_options(int argc, char** argv, OptParams & p, DavixError** err){ const std::string arg_tool_main= "P:x:H:E:X:o:kVr:"; const struct option long_options[] = { COMMON_LONG_OPTIONS, SECURITY_LONG_OPTIONS, REQUEST_LONG_OPTIONS, {0, 0, 0, 0 } }; return parse_davix_options_generic(arg_tool_main, long_options, argc, argv, p, err); } int parse_davix_ls_options(int argc, char** argv, OptParams & p, DavixError** err){ const std::string arg_tool_main= "P:x:H:E:vkVlfr:"; const struct option long_options[] = { COMMON_LONG_OPTIONS, SECURITY_LONG_OPTIONS, LISTING_LONG_OPTIONS, {0, 0, 0, 0 } }; if( parse_davix_options_generic(arg_tool_main, long_options, argc, argv, p, err) <0 || p.vec_arg.size() != 1){ option_abort(argv); return -1; } return 0; } int parse_davix_get_options(int argc, char** argv, OptParams & p, DavixError** err){ const std::string arg_tool_main= "P:x:H:E:o:OvkVr:"; const struct option long_options[] = { COMMON_LONG_OPTIONS, SECURITY_LONG_OPTIONS, {0, 0, 0, 0 } }; if( parse_davix_options_generic(arg_tool_main, long_options, argc, argv, p, err) < 0 || p.vec_arg.size() > 2){ option_abort(argv); return -1; } if(p.vec_arg.size() == 2){ p.output_file_path = p.vec_arg[1]; } return 0; } int parse_davix_put_options(int argc, char** argv, OptParams & p, DavixError** err){ const std::string arg_tool_main= "P:x:H:E:o:vkVr:"; const struct option long_options[] = { COMMON_LONG_OPTIONS, SECURITY_LONG_OPTIONS, {0, 0, 0, 0 } }; if( parse_davix_options_generic(arg_tool_main, long_options, argc, argv, p, err) < 0 || p.vec_arg.size() != 2){ option_abort(argv); return -1; } p.input_file_path = p.vec_arg[0]; return 0; } int parse_davix_copy_options(int argc, char** argv, OptParams & p, DavixError** err){ const std::string arg_tool_main= "P:x:H:E:X:o:kV"; const struct option long_options[] = { COMMON_LONG_OPTIONS, SECURITY_LONG_OPTIONS, REQUEST_LONG_OPTIONS, COPY_LONG_OPTIONS, {0, 0, 0, 0 } }; return parse_davix_options_generic(arg_tool_main, long_options, argc, argv, p, err); } int parse_davix_rm_options(int argc, char** argv, OptParams & p, DavixError** err){ const std::string arg_tool_main= "P:x:H:E:X:o:kVr:n:"; const struct option long_options[] = { COMMON_LONG_OPTIONS, SECURITY_LONG_OPTIONS, REQUEST_LONG_OPTIONS, {0, 0, 0, 0 } }; return parse_davix_options_generic(arg_tool_main, long_options, argc, argv, p, err); } std::string get_common_options(){ return " Common Options:\n" "\t--conn-timeout TIME: Connection timeout in seconds. default: 30\n" "\t--retry NUMBER: Number of retry attempt in case of an operation failure. default: 10\n" "\t--retry-delay TIME: Number of seconds to wait between retry attempts. default: 0\n" "\t--debug: Debug mode\n" "\t--header, -H: Add a header field to the request\n" "\t--help, -h: Display this help message\n" "\t--metalink OPT: Metalink support. value=failover|no. default=failover) \n" "\t--module, -P NAME: Load a plugin or profile by name\n" "\t--proxy, -x URL: SOCKS5 proxy server URL. (Ex: socks5://login:pass@socks.example.org)\n" "\t--redirection OPT: Transparent redirection support. value=yes|no. default=yes)\n" "\t--timeout TIME: Global timeout for the operation in seconds. default: infinite\n" "\t--trace: Specify one or more scopes to trace. (Ex: --trace log level(optional),header,file)\n" "\t--version, -V: Display version\n" " Security Options:\n" "\t--capath CA_PATH: Add an additional certificate authority directory\n" "\t--cert, -E CRED_PATH: Client Certificate in PEM format\n" "\t--key KEY_PATH: Private key in PEM format\n" "\t--insecure, -k: Disable SSL credential checks\n" "\t--userlogin: User login for login/password authentication\n" "\t--userpass: User password for login/password authentication\n" "\t--s3secretkey SEC_KEY: S3 authentication: secret key\n" "\t--s3accesskey ACC_KEY: S3 authentication: access key\n" ; } std::string get_base_description_options(){ return "[OPTIONS ...] \n" ; } std::string get_get_description_options(){ return "[OPTIONS ...] [local_file]\n" ; } std::string get_put_description_options(){ return "[OPTIONS ...] \n" ; } std::string get_copy_description_options(){ return "[OPTIONS ...] \n" ; } } } davix-R_0_5_0/src/tools/davix_tool_params.hpp000066400000000000000000000057211257152637300214450ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_TOOL_PARAMS_HPP #define DAVIX_TOOL_PARAMS_HPP #include #include #include namespace Davix{ namespace Tool{ typedef std::pair HeaderParam; typedef std::pair LoginPasswd; typedef std::vector HeaderVec; // pres flag #define LONG_LISTING_FLAG 0x01 #define DISPLAY_HEADERS 0x02 struct OptParams{ OptParams(); RequestParams params; // vector of non-option arguments in order std::vector vec_arg; int verbose; int debug; int s3_delete_per_request; int threadpool_size; // request command std::string req_type; // help msg std::string help_msg; // credential path std::string cred_path; // priv key path std::string priv_key; // output file -o std::string output_file_path; // input file path std::string input_file_path; // user login/passwd LoginPasswd userlogpasswd; // request content std::string req_content; // s3 auth std::pair aws_auth; // presentation flag int pres_flag; // shell flags int shell_flag; // input file flag bool has_input_file; // disable cap on task queue's size bool no_cap; // modules list std::vector modules_list; }; int parse_davix_options(int argc, char** argv, OptParams & p, DavixError** err); int parse_davix_ls_options(int argc, char** argv, OptParams & p, DavixError** err); int parse_davix_get_options(int argc, char** argv, OptParams & p, DavixError** err); int parse_davix_put_options(int argc, char** argv, OptParams & p, DavixError** err); int parse_davix_copy_options(int argc, char** argv, OptParams & p, DavixError** err); int parse_davix_rm_options(int argc, char** argv, OptParams & p, DavixError** err); std::string get_common_options(); std::string get_base_description_options(); std::string get_get_description_options(); std::string get_put_description_options(); std::string get_copy_description_options(); } } #endif // DAVIX_TOOL_PARAMS_HPP davix-R_0_5_0/src/tools/davix_tool_put_main.cpp000066400000000000000000000167771257152637300220060ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 // @author : Devresse Adrien // main file for davix-put operation using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_put = "Davix::Tools::davix-put"; std::string get_base_put_options(){ return " Put Options:\n" "\t-r NUMBER_OF_THREADS: Upload directories and their contents recursively.\n"; } static std::string help_msg(const std::string & cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_put_description_options(); help_msg += Tool::get_common_options(); help_msg += get_base_put_options(); return help_msg; } static int execute_put(Context& c, const Tool::OptParams & opts, int fd, DavixError** err){ const std::string & src_file = opts.input_file_path; const std::string & dst_file = opts.vec_arg[1]; TRY_DAVIX{ DavFile f(c, dst_file); struct stat st; if( fstat(fd, &st) != 0){ errno_to_davix_exception(errno, scope_put, std::string("for source file ").append(src_file)); } if( S_ISREG(st.st_mode) && (st.st_size >= 0)){ f.put(&opts.params, fd, static_cast(st.st_size)); return 0; } throw DavixException(scope_put, StatusCode::SystemError, std::string(src_file).append("is not a valid regular file")); }CATCH_DAVIX(err); return -1; } static int tryMakeCollection(Context& c, const Tool::OptParams & opts, std::string dst_path){ DavixError* err=NULL; DavFile f(c,dst_path); f.makeCollection(&opts.params, &err); if(err){ if(err->getStatus() == StatusCode::FileExist){ std::cerr << std::endl << scope_put << " " << dst_path << " already exists, continuing..." << std::endl; DavixError::clearError(&err); } else{ Tool::errorPrint(&err); return -1; } } return 0; } static int populateTaskQueue(Context& c, const Tool::OptParams & opts, std::string src_path, std::string dst_path, DavixTaskQueue* tq, DavixError** err ){ struct stat st; DIR* dp; struct dirent *de; int ret = -1; int entry_counter = 0; if((dp = opendir(src_path.c_str()) ) == NULL){ DavixError* tmp_err=NULL; davix_errno_to_davix_error(errno, scope_put, std::string("for source file ").append(src_path), &tmp_err); Tool::errorPrint(&tmp_err); return -1; } // process entries recursively while ((de = readdir(dp)) != NULL) { if((strcmp(de->d_name, ".")) && (strcmp(de->d_name, ".."))){ // ignore "." and ".." entries if(stat(((src_path+de->d_name).c_str()), &st) == 0){ // check if entry is file or directory if(S_ISDIR(st.st_mode)){ // is directory if(opts.params.getProtocol() != RequestProtocol::AwsS3){ // if protocol is S3, don't need make collection (not heirarchical) ret = tryMakeCollection(c, opts, dst_path+"/"+de->d_name); if(ret <0) return ret; } ret = populateTaskQueue(c, opts, src_path+de->d_name+"/", dst_path+"/"+de->d_name, tq, err); } else if(S_ISREG(st.st_mode) && st.st_size > 0){ //push op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to work queue, source is {} and destination is {}.", src_path+de->d_name, dst_path+"/"+de->d_name); PutOp* op = new PutOp(opts, src_path+de->d_name, dst_path+"/"+de->d_name, static_cast(st.st_size), c); tq->pushOp(op); entry_counter++; } } else{ errno_to_davix_exception(errno, scope_put, std::string("for source file ").append(src_path)); return -1; } } if(!opts.debug) Tool::batchTransferMonitor(src_path, "Populating task queue for", entry_counter, 0); } closedir(dp); return (err)?(-1):0; } static int prePutCheck(Tool::OptParams & opts, DavixError** err){ struct stat st; int ret = -1; Context c; configureContext(c, opts); if((ret = stat(opts.input_file_path.c_str(), &st)) != 0){ DavixError* tmp_err=NULL; davix_errno_to_davix_error(errno, scope_put, std::string("for source file ").append(opts.input_file_path), &tmp_err); DavixError::propagateError(err, tmp_err); return -1; } if((st.st_mode & S_IFDIR) && opts.params.getRecursiveMode()){ std::string src_path(opts.input_file_path); if(src_path[src_path.size()] != '/') src_path += '/'; DavixTaskQueue tq; // create threadpool instance DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Creating threadpool"); DavixThreadPool tp(&tq, opts.threadpool_size); if(opts.params.getProtocol() != RequestProtocol::AwsS3){ // if protocol is S3, don't need make collection (not heirarchical) ret = tryMakeCollection(c, opts, opts.vec_arg[1]); if(ret <0) return ret; } std::string url(opts.vec_arg[1]); if (url[url.size()-1] == '/') url.erase(url.size() - 1); ret = populateTaskQueue(c, opts, src_path, url, &tq, err); // if task queue is empty, then all work is done, stop workers. Otherwise wait. while(!tq.isEmpty()){ sleep(2); } tp.shutdown(); Tool::flushFinalLineShell(STDOUT_FILENO); } else{ // single file to upload, process it normally int fd_in = -1; if(((fd_in = Tool::getInFd(opts, scope_put, err)) > 0) && (Tool::configureMonitorCB(opts, Transfer::Write)) == 0){ ret = execute_put(c, opts, fd_in, err); close(fd_in); } } return ret; } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); if(( (retcode = Tool::parse_davix_put_options(argc, argv, opts, &tmp_err)) == 0) && ((retcode = Tool::configureAuth(opts)) == 0)){ retcode = prePutCheck(opts, &tmp_err); } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_rm_main.cpp000066400000000000000000000170631257152637300216010ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 // @author : Devresse Adrien // main file for davix low level cmd line tool using namespace Davix; using namespace std; #define READ_BLOCK_SIZE 4096 const std::string scope_main = "Davix::Tools::davix-rm"; const std::string openTag_req = ""; const std::string closeTag_req = ""; const std::string openTags_entry = ""; const std::string closeTags_entry = ""; std::string get_base_rm_options(){ return " Delete Options:\n" "\t-r NUMBER_OF_THREADS: Remove contents recursively, also works on S3 objects for storage systems that supports multi-objects deletion.\n" "\t-n NUMBER_OF_KEYS: Number of object keys to include in each delete request, S3 supports up to 1000, but request will likely timeout. Default: 20\n"; } static std::string help_msg(const std::string & cmd_path){ std::string help_msg = fmt::format("Usage : {} ", cmd_path); help_msg += Tool::get_base_description_options(); help_msg += Tool::get_common_options(); help_msg += get_base_rm_options(); return help_msg; } static int populateTaskQueue(Context& c, const Tool::OptParams & opts, std::string uri, DavixTaskQueue* tq, DavixError** err ){ DAVIX_DIR* fd = NULL; DavPosix pos(&c); DavixError* tmp_err=NULL; struct stat st; struct dirent* d; int counter = 0; int entry_counter = 0; std::string protocol, host; std::string buffer(openTag_req); if( (fd = pos.opendirpp(&opts.params, opts.vec_arg[0], &tmp_err)) == NULL){ DavixError::propagateError(err, tmp_err); return -1; } if(opts.vec_arg[0].compare(2,1,"s") == 0){ protocol = "s3s://"; } else{ protocol = "s3://"; } host = protocol + Uri(uri).getHost(); while( (d = pos.readdirpp(fd, &st, &tmp_err)) != NULL ){ // for every entry //TODO: unless user has turned on rr mode, skip entries that end with a '/'? //that way we can provide a way to just delete files inside the directory and not the other directories // format to xml and push to buffer string, for every n entries, create a DeleteOp(PostRequest) std::string entry(d->d_name); // for each entry, entry buffer += openTags_entry + entry + closeTags_entry; counter++; entry_counter++; // although the S3 API supports up to 1000 keys per request, in practice this will most likely results in a 504 gateway timeout if(counter == opts.s3_delete_per_request){ // default is set to 20, just to be safe buffer += closeTag_req; // push op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to work queue, target is {}.", host); DeleteOp* op = new DeleteOp(opts, host, c, buffer); tq->pushOp(op); counter = 0; buffer.clear(); buffer = openTag_req; } if(!opts.debug) Tool::batchTransferMonitor(uri, "Multi-objects delete ", entry_counter, 0); } // check if there is still anything in buffer for remainder entries if(!buffer.empty()){ buffer += closeTag_req; // push op to task queue DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Adding item to work queue, target is {}.", host); DeleteOp* op = new DeleteOp(opts, host, c, buffer); tq->pushOp(op); } pos.closedirpp(fd, NULL); return 0; } static int preDeleteCheck(Tool::OptParams & opts, DavixError** err ) { Context c; configureContext(c, opts); DavPosix f(&c); struct stat st; DavixError* tmp_err=NULL; // see if the requested url actually points to a directory or not int r = f.stat(&opts.params, opts.vec_arg[0], &st, &tmp_err); if (tmp_err) { DavixError::propagateError(err, tmp_err); return -1; } if (r && !(st.st_mode & S_IFDIR)){ DavixError::setupError(&tmp_err, scope_main, StatusCode::IsNotADirectory, "Failed to delete, target is not a directory."); DavixError::propagateError(err, tmp_err); return -1; } DavixTaskQueue tq; // create threadpool instance DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "Creating threadpool"); DavixThreadPool tp(&tq, opts.threadpool_size); // TODO two modes, one to delete "recursively, one for depth of 1. can probbaly do it in readdirpp // set listing mode to SemiHierarchical, we want to get every object under the same prefix in one go opts.params.setS3ListingMode(S3ListingMode::SemiHierarchical); // unfortunately s3 defaults max-keys to 1000 and doesn't provide a way to disable the cap, set to large number opts.params.setS3MaxKey(999999999); std::string url(opts.vec_arg[0]); if (url[url.size()-1] != '/') url += '/'; populateTaskQueue(c, opts, url, &tq, &tmp_err); // if task queue is empty, then all work is done, stop workers. Otherwise wait. while(!tq.isEmpty()){ sleep(2); } tp.shutdown(); Tool::flushFinalLineShell(STDOUT_FILENO); if(tmp_err){ DavixError::propagateError(err, tmp_err); return -1; } return 0; } int main(int argc, char** argv){ int retcode=-1; Tool::OptParams opts; DavixError* tmp_err=NULL; opts.help_msg = help_msg(argv[0]); if( (retcode= Tool::parse_davix_rm_options(argc, argv, opts, &tmp_err)) ==0){ if( (retcode = Tool::configureAuth(opts)) == 0){ if (opts.vec_arg[0].compare(0,4,"http") ==0){ opts.params.setProtocol(RequestProtocol::Http); }else if( opts.vec_arg[0].compare(0,2,"s3") ==0){ opts.params.setProtocol(RequestProtocol::AwsS3); }else if ( opts.vec_arg[0].compare(0, 3,"dav") ==0){ opts.params.setProtocol(RequestProtocol::Webdav); } // only s3 needs special treatment, WebDAV delete on collection already works if((opts.params.getProtocol() == RequestProtocol::AwsS3) && (opts.params.getRecursiveMode())){ preDeleteCheck(opts, &tmp_err); } else{ Context c; configureContext(c, opts); DavFile f(c,opts.vec_arg[0]); f.deletion(&opts.params, &tmp_err); } } } Tool::errorPrint(&tmp_err); return retcode; } davix-R_0_5_0/src/tools/davix_tool_util.cpp000066400000000000000000000440241257152637300211310ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "davix_tool_util.hpp" #include #include #include #include #include namespace Davix{ namespace Tool{ using namespace StrUtil; using namespace std::placeholders; dav_ssize_t writeToFd(int fd, const void* buffer, dav_size_t s_buff){ while(1){ ssize_t ret; errno =0; if((ret= write(fd, buffer, static_cast(s_buff))) <0 && errno == EINTR){ continue; } return static_cast(ret); } } dav_ssize_t writeToFd(int fd, const std::string & str){ return writeToFd(fd, str.c_str(), str.size()); } std::string string_from_ptime(const time_t & t){ char b[255]; b[sizeof(b)-1]= '\0'; struct tm local_time; (void) localtime_r(&t, &local_time); strftime(b, 254, "%F %T", &local_time); return std::string(b); } dav_ssize_t ask_user_login(std::string & login){ char l[1024] ={0}; (std::cout << "Login: ").flush(); std::cin.getline(l, 1023); login.assign(l); std::fill(l, l+1024,'\0'); return login.size(); } dav_ssize_t ask_user_passwd(std::string & passwd){ char p[1024] ={0}; std::cout << "Password: "; std::cout.flush(); if(simple_get_pass(p, 1023) > 0){ passwd.assign(p); std::fill(p, p+1024,'\0'); return passwd.size(); } return 0; } void writeConsoleLine(int fd, char symbol, const std::string & msg){ std::ostringstream ss; ss << symbol << " " << msg << "\n"; writeToFd(fd, ss.str()); } int configureAuth(OptParams & opts){ // setup client side credential opts.params.setClientCertCallbackX509(&authCallbackCert, &opts); // setup client login / password opts.params.setClientLoginPasswordCallback(&authCallbackLoginPassword, &opts); //setup aws creds if(opts.aws_auth.first.empty() == false){ opts.params.setAwsAuthorizationKeys(opts.aws_auth.first, opts.aws_auth.second); opts.params.setProtocol(RequestProtocol::AwsS3); } return 0; } static void printHookHeaders(char symbol, const std::string & first_msg, const std::string & start_line){ std::string req_header(start_line); StrUtil::remove(req_header, '\r'); rtrim(req_header, StrUtil::isCrLf()); std::vector res; split(req_header, '\n', res); writeConsoleLine(STDOUT_FILENO, '*', first_msg); for(stringVec::iterator it =res.begin(); it != res.end(); ++it){ writeConsoleLine(STDOUT_FILENO, symbol, *it); } } static void printHookHeadersVec(char symbol, const std::string & first_msg, const std::string & init_line, const HeaderVec & headers){ std::string parsed_first_line(init_line); StrUtil::remove(parsed_first_line, '\r'); rtrim(parsed_first_line, StrUtil::isCrLf()); writeConsoleLine(STDOUT_FILENO, '*', first_msg); writeConsoleLine(STDOUT_FILENO, symbol, parsed_first_line); for(HeaderVec::const_iterator it =headers.begin(); it != headers.end(); ++it){ std::string header_line(it->first); header_line.append(": ").append(it->second); writeConsoleLine(STDOUT_FILENO, symbol, header_line); } } void hook_davix_tool_pre_send(HttpRequest& req, const std::string & start_line){ (void) req; printHookHeaders('>', "Send request", start_line); } void hook_davix_tool_pre_rec(HttpRequest& req, const std::string & init_line, const HeaderVec & headers, int status_code){ (void) req; (void) status_code; printHookHeadersVec('<', "Receive answer", init_line, headers); } void configureContext(Context &context, const OptParams & opts){ if(opts.pres_flag & DISPLAY_HEADERS){ RequestPreSendHook send_hook(hook_davix_tool_pre_send); RequestPreReceHook rece_hook(hook_davix_tool_pre_rec); context.setHook(send_hook); context.setHook(rece_hook); } for(std::vector::const_iterator it = opts.modules_list.begin(); it != opts.modules_list.end(); it++){ context.loadModule(*it); } } int getOutFd(const Tool::OptParams & opts, const std::string & scope, DavixError** err){ int fd = -1; if(opts.output_file_path.empty() == false){ if((fd = open(opts.output_file_path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0777)) <0 ){ davix_errno_to_davix_error(errno, scope, std::string("for destination file ").append(opts.output_file_path), err); return -1; } }else{ fd = dup(STDOUT_FILENO); } return fd; } int getInFd(const Tool::OptParams & opts, const std::string & scope, DavixError** err){ int fd = -1; if(opts.input_file_path.empty() == false){ if((fd = open(opts.input_file_path.c_str(), O_RDONLY)) <0 ){ davix_errno_to_davix_error(errno, scope, std::string("for source file ").append(opts.input_file_path), err); return -1; } }else{ fd = dup(STDOUT_FILENO); } return fd; } void errorPrint(DavixError ** err){ if(err && *err){ std::cerr << "("<< (*err)->getErrScope() <<") Error: "<< (*err)->getErrMsg() << std::endl; DavixError::clearError(err); } } std::string mode_to_stringmode(mode_t mode){ mode_t tmp_mode = mode; //static const char * strv= "xwrxwrxwr"; char res[11]; std::fill(res, res+10, '-'); res[10]='\0'; for(int i=0; i <9; i++){ res[9-i] = ( mode = (tmp_mode >> 1)) & 0x01; } res[0]= S_ISDIR(mode); return std::string(res); } int authCallbackLoginPassword(void* userdata, const SessionInfo & info, std::string & login, std::string & password, int count, DavixError** err){ (void) info; OptParams* opts = static_cast(userdata); int ret = -1; if(opts->userlogpasswd.first.empty() == false){ login = opts->userlogpasswd.first; password = opts->userlogpasswd.second; ret =0; }else { if(count > 0) std::cout << "Authentication Failure, try again:\n"; else std::cout << "Authentication needed:\n"; if( ask_user_login(login) > 0){ if(ask_user_passwd(password) > 0){ ret =0; } } } std::cout << std::endl; if(ret < 0) DavixError::setupError(err, "Davix::Tool::Auth", StatusCode::LoginPasswordError, "No valid login/password provided"); return ret; } int authCallbackCert(void* userdata, const SessionInfo & info, X509Credential* cert, DavixError** err){ (void) info; OptParams* opts = static_cast(userdata); const std::string key_path(opts->priv_key), cred_path(opts->cred_path); if(cred_path.empty() == false){ // try without password if( cert->loadFromFilePEM( ((key_path.empty()== false)?(key_path):(cred_path)), cred_path, "", err) <0){ if( (*err)->getStatus() != StatusCode::CredDecryptionError){ // credential specific error std::cerr << "("<< (*err)->getErrScope() <<") Error: "<< (*err)->getErrMsg() << std::endl; DavixError::clearError(err); return -1; } // retry with password std::cout << std::endl; DavixError::clearError(err); std::string password; if( ask_user_passwd(password) <0 || cert->loadFromFilePEM(key_path, cred_path, password, err) <0 ){ if(err && *err == NULL){ DavixError::setupError(err, "Davix::Tool::Auth", StatusCode::CredDecryptionError, "Impossible to use and decrypt client credential"); std::cerr << "("<< (*err)->getErrScope() <<") Error: "<< (*err)->getErrMsg() << std::endl; DavixError::clearError(err); } return -1; } } std::cout << std::endl; return 0; } if(err && *err == NULL){ DavixError::setupError(err, "Davix::Tool::Auth", StatusCode::LoginPasswordError, "No valid client credential provided"); } return -1; } std::string string_from_mode(mode_t mode){ const char* rmask ="xwr"; std::string str(10,'-'); str[0] = (S_ISDIR(mode))?'d':'-'; for(size_t i=0; i < 9; ++i){ str[9-i] = (( mode & (0x01 << i))?(rmask[i%3]):'-'); } return str; } std::string string_from_size_t(size_t number, size_t size_string){ unsigned int digit= static_cast(log10(static_cast(number))); std::ostringstream ss; ss << number; ss << std::string(((digit < size_string)?(size_string - digit):0), ' '); return ss.str(); } bool isShell(int fd){ if(isatty(fd) ==1) return true; errno =0; return false; } void flushFinalLineShell(int fd){ if(isShell(fd)){ writeToFd(fd, "\n", 1); } } std::string SanitiseTildedPath(const char * path){ if(path[0] == '~') { std::string newpath(path); newpath.erase(0, 1); const char * val = std::getenv("HOME"); if(val != NULL){ newpath.insert(0, val); } else{ newpath.insert(0, "/"); } return newpath; } return std::string(path); } bool is_number(const std::string& s) { std::string::const_iterator it = s.begin(); while (it != s.end() && std::isdigit(*it)) ++it; return !s.empty() && it == s.end(); } void TransferMonitor(const Uri & url, Transfer::Type op_type, dav_ssize_t bytes_transfered, dav_size_t total_size, Transfer::Type tool_type){ static bool print_header= false; static Chrono::TimePoint start_time, last_time; Chrono::TimePoint current_time; Chrono::Clock clk(Chrono::Clock::Monolitic, Chrono::Clock::Second); int out_fd = STDERR_FILENO; // output fd -> stderr if((op_type != tool_type)){ return; } int progress = 0; dav_size_t baudrate =0; current_time = clk.now(); if(print_header == false){ std::string type = ((op_type == Transfer::Read) ? "Read" : "Write"); last_time = start_time = clk.now(); std::cout << "Performing " << type << " operation on: " << url << std::endl; print_header = true; }else{ // tty display is slow // display progression only every second if(current_time < (last_time + Chrono::Duration(1)) && (static_cast(bytes_transfered) != total_size)) return; } last_time = clk.now(); Chrono::Duration diff_time = last_time - start_time; if( diff_time.toTimeValue() > 0){ baudrate = bytes_transfered/(diff_time.toTimeValue()); } if(total_size > 0){ progress = static_cast((static_cast(bytes_transfered) / static_cast(total_size)) * 100); } printProgressBar(out_fd, progress, bytes_transfered, total_size, baudrate); } std::string normalize_unit(dav_size_t bytes){ const char * tab_unit[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" }; size_t size_tab_unit= sizeof(tab_unit)/sizeof(const char*); const dav_size_t factor = 10*1024; size_t i; for(i =0; i < size_tab_unit; ++i){ if(bytes < factor){ break; } bytes /= 1024; } return fmt::format("{}{}", bytes, tab_unit[i]); } void printProgressBar(int out_fd, int percent, dav_ssize_t bytes_transfered, dav_size_t total_size, dav_size_t baudrate){ std::string bar; std::string unit; static bool printOnce = true; dav_size_t size = total_size; struct winsize win; ioctl(out_fd, TIOCGWINSZ, &win); // w = width of bar, r = 100/w double w = static_cast(win.ws_row)/1.5; double r = 100/w; for(double i = 0; i < w; ++i){ if(i < (static_cast(percent)/r) ){ bar.replace(i,1,"="); }else{ bar.replace(i,1," "); } } if((percent == 100) && !printOnce) return; std::cout << "\r" "[" << bar << "] "; std::cout.width(3); std::cout << percent << "% " << normalize_unit(bytes_transfered) << 'B' << "/" << normalize_unit(size) << 'B'; std::cout.width(10); std::cout << normalize_unit(baudrate) << "B/s" << " " << std::flush; if(static_cast(bytes_transfered) == size){ std::cout << std::endl; printOnce = false; } } int configureMonitorCB(OptParams & opts, Transfer::Type type){ using namespace std; // active monitoring callback only if output != stdout and stderr is a terminal if(opts.output_file_path.empty() == false && isatty(STDERR_FILENO) ==1 ){ TransferMonitorCB transMonCB; transMonCB = bind(&Tool::TransferMonitor, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, type); opts.params.setTransfertMonitorCb(transMonCB); } return 0; } void tokeniseUrl(std::string url, std::deque& dirVec){ if(url.empty()) return; std::string::iterator iter; for(iter = url.begin(); iter != url.end(); ){ std::string::iterator tmpIter = std::find(iter, url.end(), '/'); std::string tmp = std::string(iter, tmpIter); dirVec.push_back(tmp); iter = tmpIter; if(tmpIter != url.end()) ++iter; } } int mkdirP(std::string url, bool trim){ int ret = -1; std::deque dirVec; std::string::iterator iter; for(iter = url.begin(); iter != url.end(); ){ std::string::iterator tmpIter = std::find(iter, url.end(), '/'); std::string tmp = std::string(url.begin(), tmpIter); dirVec.push_back(tmp); iter = tmpIter; if(tmpIter != url.end()) ++iter; } ret = mkdirP(dirVec, trim); return ret; } int mkdirP(std::deque& dirVec, bool trim){ std::deque dirList; // ignore . entries, don't need to create if(dirVec[0] == "." || dirVec[0] == "./") dirVec.pop_front(); // discard first and last entry, for cases where first already exists and last is a file to be create/open if(trim){ dirVec.pop_front(); dirVec.pop_back(); } /* //TODO: optimise logic to skip tokens that have been created previously for(unsigned int i=0; i=0; --i){ ret = mkdir(dirVec[i].c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if((ret == 0) || (errno == EEXIST)){ break; } else{ std::string tmp = dirVec[i]; dirList.push_front(tmp); } } // at this point we only have to create the dir(s) they do not already exist for(unsigned int ii=0; ii * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_TOOL_UTIL_HPP #define DAVIX_TOOL_UTIL_HPP #include #include #include namespace Davix{ namespace Tool{ dav_ssize_t writeToFd(int fd, const void* buffer, dav_size_t s_buff); dav_ssize_t writeToFd(int fd, const std::string & str); int configureAuth(OptParams & opts); void configureContext(Context &context, const OptParams & opts); void errorPrint(DavixError ** err); void writeConsoleLine(int fd, char symbol, const std::string & msg); int authCallbackLoginPassword(void* userdata, const SessionInfo & info, std::string & login, std::string & password, int count, DavixError** err); int authCallbackCert(void* userdata, const SessionInfo & info, X509Credential* cert, DavixError** err); // return output file descriptor int getOutFd(const Tool::OptParams & opts, const std::string & scope, DavixError** err); // return output file descriptor int getInFd(const Tool::OptParams & opts, const std::string & scope, DavixError** err); // string utils std::string string_from_mode(mode_t mode); std::string string_from_ptime(const time_t &t); // print a string in a minimum of size_string char, fill it with white-space if inferior to this std::string string_from_size_t(size_t number, size_t size_string); std::string filename_from_uri(const std::string & current_dir, const Uri & uri); // shell related utils bool isShell(int fd); void flushFinalLineShell(int fd); // replace '~' at front of string with env HOME if found std::string SanitiseTildedPath(const char * path); bool is_number(const std::string& s); void TransferMonitor(const Uri & url, Transfer::Type op_type, dav_ssize_t bytes_transfered, dav_size_t total_size, Transfer::Type tool_type); void printProgressBar(int out_fd, int percent, dav_ssize_t bytes_transfered, dav_size_t total_size, dav_size_t baudrate); int configureMonitorCB(OptParams & opts, Transfer::Type type); void tokeniseUrl(std::string url, std::deque& dirVec); // mkdir -p, discard front and back entries if trim is true int mkdirP(std::string dirPath, bool trim); int mkdirP(std::deque& dirVec, bool trim); void batchTransferMonitor(std::string dirPath, std::string msg, int entryCount, int totalEntry); } } #endif // DAVIX_TOOL_UTIL_HPP davix-R_0_5_0/src/utils/000077500000000000000000000000001257152637300152145ustar00rootroot00000000000000davix-R_0_5_0/src/utils/davix_fileproperties.hpp000066400000000000000000000041141257152637300221540ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_FILEPROPERTIES_H #define DAVIX_FILEPROPERTIES_H #include #include #include #include #include namespace Davix { struct FileProperties { FileProperties() : filename(), req_status(0), info(){} std::string filename; unsigned int req_status; /* status code of the request associated ( ex: http 200) */ // stat() metadata StatInfo info; inline void clear(){ info = StatInfo(); filename.clear(); req_status = 0; } }; struct FileDeleteStatus { FileDeleteStatus() : filename(), message(), error_code(), req_status(0), error(false){} std::string filename; std::string message; std::string error_code; // for when server return a text code unsigned int req_status; /* status code of the request associated ( ex: http 200) */ bool error; inline void clear(){ filename.clear(); message.clear(); error_code.clear(); req_status = 0; error = false; } }; } // namespace Davix #endif // DAVIX_FILEPROPERTIES_H davix-R_0_5_0/src/utils/davix_logger.cpp000066400000000000000000000155711257152637300204030ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 const int BUFFER_SIZE =4096; const char* prefix = "DAVIX"; static int internal_log_level = 0; static int internal_log_scope = DAVIX_LOG_SCOPE_ALL; static void (*_fhandler)(void* userdata, int mgs_level, const char* msg) = NULL; static void* _log_handler_userdata = NULL; namespace Davix{ const char* SCOPE_FILE = "file"; const char* SCOPE_HTTP = "http"; const char* SCOPE_POSIX = "posix"; const char* SCOPE_XML = "xml"; const char* SCOPE_SSL = "ssl"; const char* SCOPE_HEADER = "header"; const char* SCOPE_BODY = "body"; const char* SCOPE_CHAIN = "chain"; const char* SCOPE_CORE = "core"; const char* SCOPE_GRID = "grid"; const char* SCOPE_SOCKET = "socket"; const char* SCOPE_LOCKS = "locks"; const char* SCOPE_ALL = "all"; const std::string davix_log_scope[] = { SCOPE_FILE, SCOPE_HTTP, SCOPE_POSIX, SCOPE_XML, SCOPE_SSL, SCOPE_HEADER, SCOPE_BODY, SCOPE_CHAIN, SCOPE_CORE, SCOPE_GRID, SCOPE_SOCKET, SCOPE_LOCKS, SCOPE_ALL }; const int num_of_scopes = sizeof(davix_log_scope)/sizeof(*davix_log_scope); int getLogLevel(){ return internal_log_level; } void setLogLevel(int logLevel){ internal_log_level = logLevel; } int getLogScope(){ return internal_log_scope; } void setLogScope(int log_scope){ internal_log_scope = log_scope; } void setLogScope(const std::string &scope){ int mask=0; std::vector vec_scopes; StrUtil::split( scope, ',', vec_scopes); for(std::vector::iterator it = vec_scopes.begin(); it < vec_scopes.end(); ++it){ for(int i = 0; i < num_of_scopes; ++i){ if(StrUtil::compare_ncase((*it), davix_log_scope[i]) == 0){ switch(i){ case 0: mask |= DAVIX_LOG_FILE; break; case 1: mask |= DAVIX_LOG_HTTP; break; case 2: mask |= DAVIX_LOG_POSIX; break; case 3: mask |= DAVIX_LOG_XML; break; case 4: mask |= DAVIX_LOG_SSL; break; case 5: mask |= DAVIX_LOG_HEADER; break; case 6: mask |= DAVIX_LOG_BODY; break; case 7: mask |= DAVIX_LOG_CHAIN; break; case 8: mask |= DAVIX_LOG_CORE; break; case 9: mask |= DAVIX_LOG_GRID; break; case 10: mask |= DAVIX_LOG_SOCKET; break; case 11: mask |= DAVIX_LOG_LOCKS; break; case 12: mask |= DAVIX_LOG_SCOPE_ALL; break; default: break; } } } } setLogScope(mask); } void logStr(int scope, int log_level, const std::string & str){ if(_fhandler){ _fhandler(_log_handler_userdata, log_level, str.c_str()); }else{ if(scope & DAVIX_LOG_HEADER){ // log header, we do not want headers to be prefixed fmt::print(stderr, "{}\n", str); }else{ // davix logs fmt::print(stderr,"{}({}): {}\n", prefix, getScopeName(scope), str); } } } std::string getScopeName(int scope_mask){ std::string scope_name; switch(scope_mask){ case DAVIX_LOG_FILE: scope_name = SCOPE_FILE; break; case DAVIX_LOG_HTTP: scope_name = SCOPE_HTTP; break; case DAVIX_LOG_POSIX: scope_name = SCOPE_POSIX; break; case DAVIX_LOG_XML: scope_name = SCOPE_XML; break; case DAVIX_LOG_SSL: scope_name = SCOPE_SSL; break; case DAVIX_LOG_HEADER: scope_name = SCOPE_HEADER; break; case DAVIX_LOG_BODY: scope_name = SCOPE_BODY; break; case DAVIX_LOG_CHAIN: scope_name = SCOPE_CHAIN; break; case DAVIX_LOG_CORE: scope_name = SCOPE_CORE; break; case DAVIX_LOG_GRID: scope_name = SCOPE_GRID; break; case DAVIX_LOG_SOCKET: scope_name = SCOPE_SOCKET; break; case DAVIX_LOG_LOCKS: scope_name = SCOPE_LOCKS; break; default: scope_name = "Unknown"; break; } return scope_name; } } // Davix // // Old legacy API // extern "C" void davix_set_log_level(int log_mask){ internal_log_level = log_mask; } extern "C" int davix_get_log_level(){ return internal_log_level; } extern "C" int davix_get_log_scope(){ return internal_log_scope; } extern "C" void davix_vlogger2(int log_mask, int log_level, const char* msg, va_list ap){ char buffer[BUFFER_SIZE]; vsnprintf(buffer, BUFFER_SIZE-1, msg, ap); buffer[BUFFER_SIZE-1] ='\0'; Davix::logStr(log_mask, log_level, buffer); } extern "C" void davix_vlogger(int log_mask, const char* msg, va_list va){ davix_vlogger2(log_mask, DAVIX_LOG_DEBUG, msg, va); } extern "C" void davix_logger(int log_mask, const char * msg, ...){ va_list va; va_start(va, msg); davix_vlogger(log_mask, msg, va); va_end(va); } extern "C" void davix_set_log_handler( void (*fhandler)(void* userdata, int mgs_level, const char* msg), void* userdata){ _fhandler = fhandler; _log_handler_userdata = userdata; } davix-R_0_5_0/src/utils/davix_logger_internal.hpp000066400000000000000000000041571257152637300223020ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_LOGGER_INTERNAL_HPP #define DAVIX_LOGGER_INTERNAL_HPP #include "davix_internal_config.hpp" #include "../libs/alibxx/str/format.hpp" #include namespace Davix{ // log a string message to the davix logger void logStr(int scope, int log_level, const std::string & str); // Simple logger to trace in / out of function scope // class ScopeLogger{ public: ScopeLogger(int scopep, const char* msgp) : scope(0), msg(NULL){ if( getLogLevel() >= DAVIX_LOG_TRACE && getLogScope() & scopep){ msg = msgp; scope = scopep; logStr(scope, davix_get_log_level(), ::Davix::fmt::format(" -> {}",msg)); } } ~ScopeLogger(){ if(msg){ logStr(scope, davix_get_log_level(), ::Davix::fmt::format(" <- {}",msg)); } } private: int scope; const char* msg; }; #define DAVIX_SLOG(lvl, scope, msg, ...) \ do{ \ if( (::Davix::getLogScope() & scope) && (::Davix::getLogLevel() >= lvl) ){ \ ::Davix::logStr(scope, lvl, ::Davix::fmt::format(msg, ##__VA_ARGS__)); } \ }while(0) #define DAVIX_SCOPE_TRACE(scope, id) \ ::Davix::ScopeLogger id(scope, __func__) } // Davix #endif // DAVIX_LOGGER_INTERNAL_HPP davix-R_0_5_0/src/utils/davix_s3_utils.cpp000066400000000000000000000224701257152637300206650ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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 namespace Davix{ const std::string prefix_s3_header("x-amz-"); const std::string prefix_s3_date("x-amz-date"); std::string getAwsReqToken(const std::string & stringToSign, const std::string & private_key){ std::ostringstream ss; const std::string hmac = hmac_sha1(private_key, stringToSign); ss << Base64::base64_encode((unsigned char*) hmac.c_str(), hmac.size()); return Uri::escapeString(ss.str()); } std::string getAwsAuthorizationField(const std::string & stringToSign, const std::string & private_key, const std::string & access_key){ std::ostringstream ss; const std::string hmac = hmac_sha1(private_key, stringToSign); ss << "AWS "<< access_key << ":" << Base64::base64_encode((unsigned char*) hmac.c_str(), hmac.size()); return ss.str(); } namespace S3{ static std::string extract_bucket(const Uri & uri){ const std::string & hostname = uri.getHost(); std::string::const_iterator it = std::find(hostname.begin(), hostname.end(),'.'); return std::string(hostname.begin(), it); } static std::string get_md5(HeaderVec & vec){ for(HeaderVec::iterator it = vec.begin(); it < vec.end(); it++){ if( StrUtil::compare_ncase(it->first, "Content-MD5") ==0){ return it->second; } } return ""; } static std::string get_type(HeaderVec & vec){ for(HeaderVec::iterator it = vec.begin(); it < vec.end(); it++){ if( StrUtil::compare_ncase(it->first, "Content-Type") ==0){ return it->second; } } return ""; } static std::string get_date(HeaderVec & vec){ for(HeaderVec::iterator it = vec.begin(); it < vec.end(); it++){ if( StrUtil::compare_ncase(it->first, "date") ==0){ return it->second; } } // create date struct tm utc_current; time_t t = time(NULL); char date[255]; date[254]= '\0'; #ifdef HAVE_GMTIME_R gmtime_r(&t, &utc_current); #else struct tm* p_utc = gmtime(&t); memcpy(&utc_current, p_utc, sizeof(struct tm)); #endif strftime(date, 254, "%a, %d %b %Y %H:%M:%S %z", &utc_current); // push date vec.push_back(std::pair("Date", date)); return std::string(date); } bool matchAmzheaders(const std::string & header_key){ return (StrUtil::compare_ncase(header_key, prefix_s3_header, prefix_s3_header.size()) == 0 && StrUtil::compare_ncase(header_key, prefix_s3_date) != 0); } std::string getAmzCanonHeaders(HeaderVec & headers){ std::string canon_amz_headers; for(HeaderVec::iterator it = headers.begin(); it < headers.end(); ++it){ std::string header_key = (*it).first, header_value = (*it).second; StrUtil::toLower(StrUtil::trim(header_key)); StrUtil::toLower(StrUtil::trim(header_value)); if( matchAmzheaders(header_key)){ canon_amz_headers.reserve(canon_amz_headers.size() + header_key.size() + header_value.size() +1); canon_amz_headers += header_key; canon_amz_headers += ":"; canon_amz_headers += header_value; canon_amz_headers += "\n"; } } return canon_amz_headers; } void signRequest(const RequestParams & params, const std::string & method, const Uri & url, HeaderVec & headers){ std::ostringstream ss; // construct Request token ss << method << "\n" << get_md5(headers) << "\n" << get_type(headers) << "\n" << get_date(headers) << "\n"; if((method == "POST") && (url.getQuery() == "delete")){ // work around for S3 batch delete request ss << getAmzCanonHeaders(headers) << '/' << extract_bucket(url) << url.getPath() << '?' << url.getQuery(); } else{ ss << getAmzCanonHeaders(headers) << '/' << extract_bucket(url) << url.getPath(); } headers.push_back(std::pair("Authorization", getAwsAuthorizationField(ss.str(), params.getAwsAutorizationKeys().first, params.getAwsAutorizationKeys().second))); } Uri tokenizeRequest(const RequestParams & params, const std::string & method, const Uri & url, HeaderVec & headers, time_t expirationTime){ std::ostringstream ss; // construct Request token ss << method << "\n" << get_md5(headers) << "\n" << get_type(headers) << "\n" << static_cast(expirationTime) << "\n"; if((method == "POST") && (url.getQuery() == "delete")){ // work around for S3 batch delete request ss << getAmzCanonHeaders(headers) << '/' << extract_bucket(url) << url.getPath() << '?' << url.getQuery(); } else{ ss << getAmzCanonHeaders(headers) << '/' << extract_bucket(url) << url.getPath(); } const std::string signature = getAwsReqToken(ss.str(), params.getAwsAutorizationKeys().first); ss.clear(); ss.str(""); ss << url.getString(); if(url.getQuery().size() ==0){ ss << "?"; }else{ ss << "&"; } ss << "AWSAccessKeyId=" << params.getAwsAutorizationKeys().second << "&"; ss << "Signature=" << signature << "&"; ss << "Expires=" << static_cast(expirationTime); // add amz headers as query parameters for(HeaderVec::iterator it = headers.begin(); it < headers.end(); ++it){ if(matchAmzheaders(it->first)){ std::string key= it->first, value = it->second; StrUtil::toLower(StrUtil::trim(key)); StrUtil::toLower(StrUtil::trim(value)); ss << "&"<< Uri::escapeString(key) << "=" << Uri::escapeString(value); } } return Uri(ss.str()); } Uri s3UriTransformer(const Uri & original_url, const RequestParams & params, const bool addDelimiter){ std::string delimiter = "&delimiter=/"; std::string prefix = "?prefix="; std::string maxKey = "&max-keys="; std::string protocol; if(original_url.getString().compare(2,1,"s") == 0){ protocol = "s3s://"; } else{ protocol = "s3://"; } std::ostringstream ss; ss << protocol << original_url.getHost() << "/"; if(!original_url.getPath().empty()){ // there is something after '/', grab it std::string tmp = original_url.getPath(); // if prefix doesn't end with '/', add one to handle query on folder if(tmp.compare(tmp.size()-1,1,"/") != 0) tmp += "/"; tmp.erase(0,1); prefix += tmp; } ss << prefix << maxKey << params.getS3MaxKey(); // skip delimiter if where we want to list everything after a certain prefix, // useful in cases like GET Collection if(addDelimiter) ss << delimiter; return Uri(ss.str()); } time_t s3TimeConverter(std::string &s3time){ struct tm t; memset(&t, 0, sizeof(struct tm)); size_t pos=0; std::string tmp; // check which datetime format is used if(strptime(s3time.c_str(), "%a, %d %b %Y %H:%M:%S %z", &t) == NULL){ if((pos = s3time.find("T")) != std::string::npos){ // iso 8601 tmp = s3time.substr(0,pos) + " " + s3time.substr(pos+1,s3time.find('.',pos)-1); strptime(tmp.c_str(), "%F %T", &t); } } time_t mtime = timegm(&t); return mtime; } // taken from dmlite std::string hexPrinter(const unsigned char* data, dav_size_t nbytes){ char buffer[nbytes * 2 + 1]; char *p; p = buffer; for(dav_size_t offset = 0; offset < nbytes; ++offset, p+=2) sprintf(p, "%02x", data[offset]); *p = '\0'; return std::string(buffer); } int calculateMD5(std::string &input, std::string &output){ if(input.empty()) return -1; unsigned char result_buf[MD5_DIGEST_LENGTH]; MD5((unsigned char*)input.c_str(), input.size(), result_buf); output = Base64::base64_encode(result_buf, MD5_DIGEST_LENGTH); return output.empty() ? -1 : 0; } int calculateMD5(int fd, std::string &output){ struct stat statbuf; if(fstat(fd, &statbuf) < 0) return -1; unsigned char result_buf[MD5_DIGEST_LENGTH]; void* file_buf = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); MD5((unsigned char*)file_buf, statbuf.st_size, result_buf); munmap(file_buf, statbuf.st_size); output = Base64::base64_encode(result_buf, MD5_DIGEST_LENGTH); return output.empty() ? -1 : 0; } } // S3 } // Davix davix-R_0_5_0/src/utils/davix_utils_internal.hpp000066400000000000000000000021071257152637300221540ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #pragma once #ifndef DAVIX_UTILS_INTERNAL_HPP #define DAVIX_UTILS_INTERNAL_HPP #include #include #endif // DAVIX_UTILS_INTERNAL_HPP davix-R_0_5_0/src/utils/davixuri.cpp000066400000000000000000000357011257152637300175610ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include namespace Davix { /** * @cond HIDDEN_SYMBOLS */ const std::string void_str(""); int davix_uri_parse(const std::string & uri_str, UriPrivate & res); int davix_uri_cmp(const UriPrivate &u1, const UriPrivate &u2); std::string davix_path_escape(const std::string & str); std::string davix_path_unescape(const std::string & str); struct UriPrivate{ UriPrivate() : code(StatusCode::UriParsingError), proto(), userinfo(), path(), host(), query(), port(0), _uri_string(), query_and_path(NULL){} UriPrivate(const UriPrivate & orig): code(orig.code), proto(orig.proto), userinfo(orig.userinfo), path(orig.path), host(orig.host), query(orig.query), port(orig.port), _uri_string(orig._uri_string), query_and_path(NULL){ } ~UriPrivate(){ } void parsing(const std::string & uri_string){ _uri_string = uri_string; if( davix_uri_parse(_uri_string, *this) == 0 && proto.size() != 0 && port != UINT_MAX){ code = StatusCode::OK; }else{ clear(); } } void clear(){ proto.clear(); userinfo.clear(); path.clear(); host.clear(); query.clear(); fragment.clear(); port = 0; } StatusCode::Code code; std::string proto, userinfo, path, host, query, fragment; unsigned int port; std::string _uri_string; Ptr::Scoped query_and_path; }; Uri::Uri() : d_ptr(new UriPrivate()){ } Uri::Uri(const std::string & uri) : d_ptr(new UriPrivate()){ d_ptr->parsing(uri); } Uri::Uri(const Uri & uri) : d_ptr(new UriPrivate(*(uri.d_ptr))){ } Uri::~Uri(){ delete d_ptr; } int Uri::getPort() const{ if(d_ptr->code != StatusCode::OK) return -1; return static_cast(d_ptr->port); } const std::string & Uri::getHost() const{ return d_ptr->host; } const std::string & Uri::getString() const{ return d_ptr->_uri_string; } const std::string & Uri::getProtocol() const { return d_ptr->proto; } const std::string & Uri::getUserInfo() const{ return d_ptr->userinfo; } const std::string & Uri::getPath() const { return d_ptr->path; } const std::string & Uri::getPathAndQuery() const { if(d_ptr->query_and_path.get() == NULL){ if(d_ptr->query.size() > 0){ d_ptr->query_and_path.reset(new std::string(d_ptr->path + "?" + d_ptr->query)); }else{ d_ptr->query_and_path.reset(new std::string(d_ptr->path)); } } return *(d_ptr->query_and_path); } const std::string & Uri::getQuery() const{ return d_ptr->query; } Uri & Uri::operator =(const Uri & orig){ if(this == &orig) return *this; if (d_ptr) delete d_ptr; d_ptr = new UriPrivate(*(orig.d_ptr)); return *this; } StatusCode::Code Uri::getStatus() const{ return d_ptr->code; } bool Uri::equal(const Uri &u2) const{ if(this->getStatus() != Davix::StatusCode::OK || u2.getStatus() != Davix::StatusCode::OK) return false; return davix_uri_cmp(*d_ptr, *(u2.d_ptr))==0; } bool Uri::operator ==(const Uri & u2) const{ return this->equal(u2); } std::string Uri::escapeString(const std::string & str){ return davix_path_escape(str); } std::string Uri::unescapeString(const std::string & str){ return davix_path_unescape(str); } // FIX IT : does not manage properly ../ Uri Uri::fromRelativePath(const Uri &uri, const std::string &relPath){ std::ostringstream ss; if(relPath.size() >= 2){ // test if not absolute std::string::const_iterator it; if( ( it = std::find(relPath.begin(), relPath.end(), '/')) != relPath.end() && it != relPath.begin() && *(it-1) == ':' && (it+1) != relPath.end() && *(it+1) == '/'){ return Uri(relPath); } // RFC 3986 network-path reference” if(relPath[0] == '/' && relPath[1] == '/'){ ss << uri.getProtocol() << ":" << relPath; return Uri(ss.str()); } // RFC 3986 relative ” if(relPath[0] == '.' && relPath[1] == '/'){ ss << uri.getString() << "/"; std::copy(relPath.begin()+2,relPath.end(), std::ostreambuf_iterator(ss)); return Uri(ss.str()); } } // RFC 3986 abs path ” if( relPath.size() >= 1){ if(relPath[0] == '/'){ ss << uri.getProtocol() << "://"; if(uri.getUserInfo().size() >0){ ss << uri.getUserInfo() << '@'; } ss << uri.getHost(); if(uri.getPort() != 0){ ss << ':' << uri.getPort(); } ss << relPath; return Uri(ss.str()); } } ss << uri.getString() <<'/'<< relPath; return Uri(ss.str()); } bool uriCheckError(const Uri &uri, DavixError **err){ if(uri.getStatus() == StatusCode::OK) return true; DavixError::setupError(err, davix_scope_uri_parser(), uri.getStatus(), std::string("Uri syntax Invalid : ").append(uri.getString())); return false; } unsigned int httpUriGetPort(const Uri & uri){ int port = uri.getPort(); if( port ==0){ const std::string & scheme = uri.getProtocol(); if(*scheme.rbegin() == 's') // davs, https or s3s port = 443; else port =80; } return port; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// part imported from neon parser ne_uri, converted C++ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* URI ABNF from RFC 3986: */ #define PS (0x0001) /* "+" */ #define PC (0x0002) /* "%" */ #define DS (0x0004) /* "-" */ #define DT (0x0008) /* "." */ #define US (0x0010) /* "_" */ #define TD (0x0020) /* "~" */ #define FS (0x0040) /* "/" */ #define CL (0x0080) /* ":" */ #define AT (0x0100) /* "@" */ #define QU (0x0200) /* "?" */ #define DG (0x0400) /* DIGIT */ #define AL (0x0800) /* ALPHA */ #define GD (0x1000) /* gen-delims = "#" / "[" / "]" * ... except ":", "/", "@", and "?" */ #define SD (0x2000) /* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" * / "*" / "+" / "," / ";" / "=" * ... except "+" which is PS */ #define OT (0x4000) /* others */ #define URI_ALPHA (AL) #define URI_DIGIT (DG) /* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" */ #define URI_UNRESERVED (AL | DG | DS | DT | US | TD) /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ #define URI_SCHEME (AL | DG | PS | DS | DT) /* real sub-delims definition, including "+" */ #define URI_SUBDELIM (PS | SD) /* real gen-delims definition, including ":", "/", "@" and "?" */ #define URI_GENDELIM (GD | CL | FS | AT | QU) /* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */ #define URI_USERINFO (URI_UNRESERVED | PC | URI_SUBDELIM | CL) /* pchar = unreserved / pct-encoded / sub-delims / ":" / "@" */ #define URI_PCHAR (URI_UNRESERVED | PC | URI_SUBDELIM | CL | AT) /* invented: segchar = pchar / "/" */ #define URI_SEGCHAR (URI_PCHAR | FS) /* query = *( pchar / "/" / "?" ) */ #define URI_QUERY (URI_PCHAR | FS | QU) /* fragment == query */ #define URI_FRAGMENT URI_QUERY /* any characters which should be path-escaped: */ #define URI_ESCAPE ((URI_GENDELIM & ~(FS)) | URI_SUBDELIM | OT | PC) static const unsigned int uri_chars[256] = { /* 0xXX x0 x2 x4 x6 x8 xA xC xE */ /* 0x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* 1x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* 2x */ OT, SD, OT, GD, SD, PC, SD, SD, SD, SD, SD, PS, SD, DS, DT, FS, /* 3x */ DG, DG, DG, DG, DG, DG, DG, DG, DG, DG, CL, SD, OT, SD, OT, QU, /* 4x */ AT, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, /* 5x */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, GD, OT, GD, OT, US, /* 6x */ OT, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, /* 7x */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, OT, OT, OT, TD, OT, /* 8x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* 9x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Ax */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Bx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Cx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Dx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Ex */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, /* Fx */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT }; #define uri_lookup(ch) (uri_chars[(unsigned char)ch]) int davix_uri_parse(const std::string & uri_str, UriPrivate & res) { const char *p, *s, *uri; p = s = uri = uri_str.c_str(); /* => s = p = URI-reference */ if (uri_lookup(*p) & URI_ALPHA) { while (uri_lookup(*p) & URI_SCHEME) p++; if (*p == ':') { res.proto.assign(uri, p -s); s = p + 1; } } /* => s = heir-part, or s = relative-part */ if (s[0] == '/' && s[1] == '/') { const char *pa; /* => s = "//" authority path-abempty (from expansion of * either heir-part of relative-part) */ /* authority = [ userinfo "@" ] host [ ":" port ] */ s = pa = s + 2; /* => s = authority */ while (*pa != '/' && *pa != '\0') pa++; /* => pa = path-abempty */ p = s; while (p < pa && uri_lookup(*p) & URI_USERINFO) p++; if (*p == '@') { res.userinfo.assign(s, p-s); s = p + 1; } /* => s = host */ if (s[0] == '[') { p = s + 1; while (*p != ']' && p < pa) p++; if (p == pa || (p + 1 != pa && p[1] != ':')) { /* Ill-formed IP-literal. */ return -1; } p++; /* => p = colon */ } else { /* Find the colon. */ p = pa; while (*p != ':' && p > s) p--; } if (p == s) { p = pa; /* No colon; => p = path-abempty */ } else if (p + 1 != pa) { /* => p = colon */ res.port = atoi(p + 1); if( res.port == 0) res.port = UINT_MAX; } res.host.assign(s, p - s); s = pa; if (*s == '\0') { s = "/"; /* FIXME: scheme-specific. */ } } /* => s = path-abempty / path-absolute / path-rootless * / path-empty / path-noscheme */ p = s; while (uri_lookup(*p) & URI_SEGCHAR) p++; /* => p = [ "?" query ] [ "#" fragment ] */ res.path.assign(s, p - s); if (*p != '\0') { s = p++; while (uri_lookup(*p) & URI_QUERY) p++; /* => p = [ "#" fragment ] */ /* => s = [ "?" query ] [ "#" fragment ] */ if (*s == '?') { res.query.assign(s + 1, p - s - 1); if (*p != '\0') { s = p++; while (uri_lookup(*p) & URI_FRAGMENT) p++; } } /* => p now points to the next character after the * URI-reference; which should be the NUL byte. */ if (*s == '#') { res.fragment.assign(s + 1, p - s - 1); } else if (*p || *s != '?') { return -1; } } return 0; } // As specified by RFC 2616, section 3.2.3. int davix_uri_cmp(const UriPrivate & u1, const UriPrivate & u2) { int diff; if( (diff= u1.path.compare(u2.path)) != 0) return diff; if( (diff= strcasecmp(u1.host.c_str(), u2.host.c_str())) != 0) return diff; if( (diff= strcasecmp(u1.proto.c_str(), u2.proto.c_str())) != 0) return diff; if( (diff= u1.query.compare(u2.query)) != 0) return diff; if( (diff= u1.fragment.compare(u2.fragment)) != 0) return diff; if( (diff= u1.userinfo.compare(u2.userinfo)) != 0) return diff; return u2.port - u1.port; } std::string davix_path_unescape(const std::string & str) { const char *pnt, *uri = (const char*)str.c_str(); char *retpos, buf[5] = { "0x00" }; char buffer[str.size() + 1]; retpos = buffer; for (pnt = uri; *pnt != '\0'; pnt++) { if (*pnt == '%') { if (!isxdigit((unsigned char) pnt[1]) || !isxdigit((unsigned char) pnt[2])) { /* Invalid URI */ return std::string(); } buf[2] = *++pnt; buf[3] = *++pnt; /* bit faster than memcpy */ *retpos++ = (char)strtol(buf, NULL, 16); } else { *retpos++ = *pnt; } } *retpos = '\0'; return std::string(buffer); } /* CH must be an unsigned char; evaluates to 1 if CH should be * percent-encoded. */ #define path_escape_ch(ch) (uri_lookup(ch) & URI_ESCAPE) std::string davix_path_escape(const std::string & str) { const unsigned char *pnt, *path= (const unsigned char*)(str.c_str()); char *p; size_t count = 0; for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { count += path_escape_ch(*pnt); } if (count == 0) { return std::string((const char*) path); } char buffer[str.size() + 2 * count + 1]; p = buffer; for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { if (path_escape_ch(*pnt)) { /* Escape it - % */ sprintf(p, "%%%02x", (unsigned char) *pnt); p += 3; } else { *p++ = *pnt; } } *p = '\0'; return std::string(buffer); } #undef path_escape_ch std::ostream& operator<< (std::ostream& stream, const Davix::Uri & _u){ stream << _u.getString(); return stream; } } // namespace Davix std::ostream& operator<< (std::ostream& stream, const Davix::Uri & _u){ stream << _u.getString(); return stream; } davix-R_0_5_0/src/xml/000077500000000000000000000000001257152637300146545ustar00rootroot00000000000000davix-R_0_5_0/src/xml/CMakeLists.txt000066400000000000000000000001561257152637300174160ustar00rootroot00000000000000# main file for src FILE(GLOB _src_xmlparser "*.cpp") SET(src_xmlparser ${_src_xmlparser} PARENT_SCOPE ) davix-R_0_5_0/src/xml/davdeletexmlparser.cpp000066400000000000000000000146201257152637300212560ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "davdeletexmlparser.hpp" #include #include #include #include using namespace StrUtil; namespace Davix { const Xml::XmlPTree prop_response(Xml::ElementStart, "response"); static Ptr::Scoped webDavTree; static boost::once_flag _l_init = BOOST_ONCE_INIT; struct DavDeleteXMLParser::DavxDeleteXmlIntern{ DavxDeleteXmlIntern() : _stack(), _props(), _current_props(), _last_response_status(500), _last_filename(){ _stack.reserve(10); char_buffer.reserve(1024); } // node stack std::vector _stack; // props std::deque _props; FileProperties _current_props; int _last_response_status; std::string _last_filename; // buffer std::string char_buffer; inline void appendChars(const char *buff, size_t len){ char_buffer.append(std::string(buff, len)); } inline void clear(){ char_buffer.clear(); } inline void add_new_elem(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " properties detected "); _current_props.clear(); _current_props.filename = _last_filename; // setup the current filename _current_props.req_status = _last_response_status; } inline void store_new_elem(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " end of properties... "); _props.push_back(_current_props); } inline void update_elem(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " updating propertie's info "); _current_props.filename = _last_filename; _current_props.req_status = _last_response_status; } }; typedef void (*properties_cb)(DavDeleteXMLParser::DavxDeleteXmlIntern & par, const std::string & name); static void check_href(DavDeleteXMLParser::DavxDeleteXmlIntern & par, const std::string & name){ std::string _href(name); rtrim(_href, isSlash()); // remove trailing slash std::string::reverse_iterator it = std::find(_href.rbegin(), _href.rend(), '/'); if( it == _href.rend()){ par._last_filename.assign(_href); }else{ par._last_filename.assign(it.base(), _href.end()); } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " href/filename parsed -> {} ", par._last_filename.c_str() ); } static void check_status(DavDeleteXMLParser::DavxDeleteXmlIntern & par, const std::string & name){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " status found -> parse it"); std::string str_status(name); ltrim(str_status, StrUtil::isSpace()); std::string::iterator it1, it2; it1 = std::find(str_status.begin(), str_status.end(), ' '); if( it1 != str_status.end()){ it2 = std::find(it1+1, str_status.end(), ' '); std::string str_status_parsed(it1+1, it2); unsigned long res = strtoul(str_status_parsed.c_str(), NULL, 10); if(res != ULONG_MAX){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " status value : {}", res); par._last_response_status = res; return; } } DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_XML, "Invalid dav status field value"); errno =0; } static void init_webdavTree(){ // Nodes list webDavTree.reset(new Xml::XmlPTree(Xml::ElementStart, "multistatus")); webDavTree->addChild(Xml::XmlPTree(Xml::ElementStart, "response")); Xml::XmlPTree::iterator it = webDavTree->beginChildren(); it->addChild(Xml::XmlPTree(Xml::ElementStart, "href", Xml::XmlPTree::ChildrenList(), (void*) &check_href)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "status", Xml::XmlPTree::ChildrenList(), (void*) &check_status)); } DavDeleteXMLParser::DavDeleteXMLParser() : d_ptr(new DavxDeleteXmlIntern()) { boost::call_once(init_webdavTree, _l_init); } DavDeleteXMLParser::~DavDeleteXMLParser(){ delete d_ptr; } std::deque & DavDeleteXMLParser::getProperties(){ return d_ptr->_props; } int DavDeleteXMLParser::parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts){ (void) parent; (void) name; (void) nspace; (void) atts; // add elem to stack Xml::XmlPTree node(Xml::ElementStart, name); d_ptr->_stack.push_back(node); // if beginning of prop, add new element if(node.compareNode(prop_response)){ d_ptr->add_new_elem(); } return 1; } int DavDeleteXMLParser::parserCdataCb(int state, const char *cdata, size_t len){ (void) state; d_ptr->appendChars(cdata, len); return 0; } int DavDeleteXMLParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; Xml::XmlPTree node(Xml::ElementStart, name); if(node.compareNode(prop_response)){ d_ptr->store_new_elem(); } // find potential interesting data std::vector chain; if(d_ptr->char_buffer.size() != 0){ chain = webDavTree->findChain(d_ptr->_stack); if(chain.size() > 0){ properties_cb cb = ((properties_cb) chain.at(chain.size()-1)->getMeta()); if(cb){ StrUtil::trim(d_ptr->char_buffer); cb(*d_ptr, d_ptr->char_buffer); } } d_ptr->update_elem(); } // cleaning work if(d_ptr->_stack.size() == 0) throw DavixException(davix_scope_xml_parser(),StatusCode::ParsingError, "Corrupted Parser Stack, Invalid XML"); d_ptr->_stack.pop_back(); d_ptr->clear(); return 0; } } // namespace Davix davix-R_0_5_0/src/xml/davdeletexmlparser.hpp000066400000000000000000000034301257152637300212600ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_DAVDELETEXMLPARSER_HPP #define DAVIX_DAVDELETEXMLPARSER_HPP #include #include #include namespace Davix { class DavDeleteXMLParser : public XMLPropParser { public: struct DavxDeleteXmlIntern; DavDeleteXMLParser(); virtual ~DavDeleteXMLParser(); virtual std::deque & getProperties(); protected: virtual int parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts); virtual int parserCdataCb(int state, const char *cdata, size_t len); virtual int parserEndElemCb(int state, const char *nspace, const char *name); private: DavxDeleteXmlIntern* d_ptr; }; /* inline bool match_element(const char* c_origin, const char* c_pattern){ // C style, critical function return strcmp(c_origin,c_pattern) ==0; } */ } // namespace Davix #endif // DAVIX_DAVDELETEXMLPARSER_HPP davix-R_0_5_0/src/xml/davix_ptree.cpp000066400000000000000000000017211257152637300176730ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "davix_ptree.hpp" namespace Davix { } // namespace Davix davix-R_0_5_0/src/xml/davix_ptree.hpp000066400000000000000000000122601257152637300177000ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_PTREE_HPP #define DAVIX_PTREE_HPP #include #include #include #include namespace Davix { template , class PredEqualData = std::equal_to > class BasicPtree{ public: typedef BasicPtree tree_type; typedef tree_type* ptr_type; typedef std::vector ChildrenList; typedef typename ChildrenList::const_iterator const_iterator; typedef typename ChildrenList::iterator iterator; BasicPtree() : _key(KeyType()), _data(DataType()), _children(ChildrenList()), _meta_data(NULL), _data_cmp(PredEqualData()), _key_cmp(PredEqualKey()) {} BasicPtree(const KeyType & key, const DataType & data, const ChildrenList & l = ChildrenList(), void* meta = NULL) : _key(key), _data(data), _children(l), _meta_data(meta){} BasicPtree(const BasicPtree & orig) : _key(orig._key), _data(orig._data), _children(orig._children), _meta_data(orig._meta_data) {} ~BasicPtree(){} inline const_iterator beginChildren() const{ return _children.begin(); } inline iterator beginChildren(){ return _children.begin(); } inline const_iterator endChildren() const{ return _children.end(); } inline iterator endChildren(){ return _children.end(); } inline void clearChildren(){ _children.clear(); } inline const KeyType & getKey() const { return _key; } inline const DataType & getData() const { return _data; } inline void* getMeta(){ return _meta_data; } inline void setMeta(void* meta){ _meta_data = meta; } inline BasicPtree & addChild(const BasicPtree & child){ _children.push_back(child); return _children.back(); } inline bool compareData(const BasicPtree & other) const{ return ( _data_cmp(_data, other._data)); } inline bool compareKey(const BasicPtree & other) const{ return ( _key_cmp(_key, other._key)); } inline int compareNode(const BasicPtree & other) const{ return (compareKey(other) && compareData(other)); } inline bool matchTree(const BasicPtree & rtree) const{ if(compareNode(rtree) == false){ return false; } for(const_iterator it_rtree = rtree.beginChildren(); it_rtree != rtree.endChildren(); ++it_rtree){ bool found=false; for(const_iterator it = beginChildren(); it != endChildren(); ++it){ if(it->matchTree(*it_rtree) ){ found = true; break; } } if(!found){ // failed to find rtree node in main tree return false; } } std::cout << " end node " << rtree._data << std::endl; return true; } /// /// Match an order chain of node as a subtree /// return the chain matched inline std::vector findChain(const std::vector & chain){ std::vector res; res.reserve(chain.size()); _findChainRec(chain.begin(), chain.end(), res); return res; } protected: // members KeyType _key; DataType _data; ChildrenList _children; void* _meta_data; // cmp PredEqualData _data_cmp; PredEqualKey _key_cmp; bool _findChainRec(typename std::vector::const_iterator begin, typename std::vector::const_iterator end, std::vector & res){ if(begin == end) return true; if( compareNode(*begin)){ res.push_back(this); begin++; for(iterator it = beginChildren(); it != endChildren(); ++it){ if( it->_findChainRec(begin, end, res) == true){ return true; } } } return false; } }; namespace Xml{ enum NodeType{ ElementStart=0x01, CData=0x02, Attribute=0x03, Comment=0x04 }; typedef BasicPtree XmlPTree; } // namespace Xml } // namespace Davix #endif // DAVIX_PTREE_HPP davix-R_0_5_0/src/xml/davpropxmlparser.cpp000066400000000000000000000235171257152637300210010ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "davpropxmlparser.hpp" #include #include #include #include using namespace StrUtil; namespace Davix { const Xml::XmlPTree prop_node(Xml::ElementStart, "propstat"); const Xml::XmlPTree prop_collection(Xml::ElementStart, "collection"); static Ptr::Scoped webDavTree; static boost::once_flag _l_init = BOOST_ONCE_INIT; struct DavPropXMLParser::DavxPropXmlIntern{ DavxPropXmlIntern() : _stack(), _props(), _current_props(), _last_response_status(500), _last_filename(){ _stack.reserve(10); char_buffer.reserve(1024); } // node stack std::vector _stack; // props std::deque _props; FileProperties _current_props; int _last_response_status; std::string _last_filename; // buffer std::string char_buffer; inline void appendChars(const char *buff, size_t len){ char_buffer.append(std::string(buff, len)); } inline void clear(){ char_buffer.clear(); } inline void add_new_elem(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " properties detected "); _current_props.clear(); _current_props.filename = _last_filename; // setup the current filename _current_props.info.mode = 0777 | S_IFREG; // default : fake access to everything } inline void store_new_elem(){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " end of properties... "); if( _last_response_status > 100 && _last_response_status < 400){ _props.push_back(_current_props); }else{ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, "Bad status code ! properties dropped"); } } }; typedef void (*properties_cb)(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name); static void check_last_modified(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " getlastmodified found -> parse it "); time_t t = parse_standard_date(name.c_str()); if(t == -1){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_XML, " getlastmodified parsing error : corrupted value ... ignored"); t = 0; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " getlastmodified found -> value {} ", t); par._current_props.info.mtime = t; } static void check_creation_date(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, "creationdate found -> parse it"); time_t t = parse_standard_date(name.c_str()); if(t == -1){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_XML, " creationdate parsing error : corrupted value ... ignored"); t = 0; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " creationdate found -> value {} ", t); par._current_props.info.ctime = t; } static void check_is_directory(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ (void) name; DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " directory pattern found -> set flag IS_DIR"); par._current_props.info.mode |= S_IFDIR; par._current_props.info.mode &= ~(S_IFREG); } static void check_content_length(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " content length found -> parse it"); try{ const unsigned long mysize = toType()(name); DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " content length found -> {}", mysize); par._current_props.info.size = static_cast(mysize); }catch(...){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_XML, " Invalid content length value in dav response"); } } static void check_mode_ext(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, "mode_t extension for LCGDM found -> parse it"); const unsigned long mymode = strtoul(name.c_str(), NULL, 8); if(mymode == ULONG_MAX){ DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_XML, "Invalid mode_t value for the LCGDM extension"); errno =0; return; } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, fmt::sprintf(" mode_t extension found -> 0%o", (mode_t) mymode).c_str()); par._current_props.info.mode = (mode_t) mymode; } static void check_href(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ std::string _href(name); rtrim(_href, isSlash()); // remove trailing slash std::string::reverse_iterator it = std::find(_href.rbegin(), _href.rend(), '/'); if( it == _href.rend()){ par._last_filename.assign(_href); }else{ par._last_filename.assign(it.base(), _href.end()); } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " href/filename parsed -> {} ", par._last_filename.c_str() ); } static void check_status(DavPropXMLParser::DavxPropXmlIntern & par, const std::string & name){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " status found -> parse it"); std::string str_status(name); ltrim(str_status, StrUtil::isSpace()); std::string::iterator it1, it2; it1 = std::find(str_status.begin(), str_status.end(), ' '); if( it1 != str_status.end()){ it2 = std::find(it1+1, str_status.end(), ' '); std::string str_status_parsed(it1+1, it2); unsigned long res = strtoul(str_status_parsed.c_str(), NULL, 10); if(res != ULONG_MAX){ DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " status value : {}", res); par._last_response_status = res; return; } } DAVIX_SLOG(DAVIX_LOG_VERBOSE, DAVIX_LOG_XML, "Invalid dav status field value"); errno =0; } void init_webdavTree(){ // Nodes list webDavTree.reset(new Xml::XmlPTree(Xml::ElementStart, "multistatus")); webDavTree->addChild(Xml::XmlPTree(Xml::ElementStart, "response")); Xml::XmlPTree::iterator it = webDavTree->beginChildren(); it->addChild(Xml::XmlPTree(Xml::ElementStart, "href", Xml::XmlPTree::ChildrenList(), (void*) &check_href)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "propstat")); it = (--it->endChildren()); it->addChild(Xml::XmlPTree(Xml::ElementStart, "status", Xml::XmlPTree::ChildrenList(), (void*) &check_status)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "prop")); it = (--it->endChildren()); it->addChild(Xml::XmlPTree(Xml::ElementStart, "getlastmodified", Xml::XmlPTree::ChildrenList(), (void*) &check_last_modified)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "creationdate", Xml::XmlPTree::ChildrenList(), (void*) &check_creation_date)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "getcontentlength", Xml::XmlPTree::ChildrenList(), (void*) &check_content_length)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "mode", Xml::XmlPTree::ChildrenList(), (void*) &check_mode_ext)); it->addChild(Xml::XmlPTree(Xml::ElementStart, "resourcetype")); it = (--it->endChildren()); it->addChild(Xml::XmlPTree(Xml::ElementStart, "collection", Xml::XmlPTree::ChildrenList(), (void*) &check_is_directory)); } DavPropXMLParser::DavPropXMLParser() : d_ptr(new DavxPropXmlIntern()) { boost::call_once(init_webdavTree, _l_init); } DavPropXMLParser::~DavPropXMLParser(){ delete d_ptr; } std::deque & DavPropXMLParser::getProperties(){ return d_ptr->_props; } int DavPropXMLParser::parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts){ (void) parent; (void) name; (void) nspace; (void) atts; // add elem to stack Xml::XmlPTree node(Xml::ElementStart, name); d_ptr->_stack.push_back(node); // if beginning of prop, add new element if(node.compareNode(prop_node)){ d_ptr->add_new_elem(); } return 1; } int DavPropXMLParser::parserCdataCb(int state, const char *cdata, size_t len){ (void) state; d_ptr->appendChars(cdata, len); return 0; } int DavPropXMLParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; Xml::XmlPTree node(Xml::ElementStart, name); // find potential interesting data std::vector chain; if(d_ptr->char_buffer.size() != 0 || node.compareNode(prop_collection)){ chain = webDavTree->findChain(d_ptr->_stack); if(chain.size() > 0){ properties_cb cb = ((properties_cb) chain.at(chain.size()-1)->getMeta()); if(cb){ StrUtil::trim(d_ptr->char_buffer); cb(*d_ptr, d_ptr->char_buffer); } } } // push props if(node.compareNode(prop_node)){ d_ptr->store_new_elem(); } // cleaning work if(d_ptr->_stack.size() == 0) throw DavixException(davix_scope_xml_parser(),StatusCode::ParsingError, "Corrupted Parser Stack, Invalid XML"); d_ptr->_stack.pop_back(); d_ptr->clear(); return 0; } } // namespace Davix davix-R_0_5_0/src/xml/davpropxmlparser.hpp000066400000000000000000000034041257152637300207770ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_DAVPROPXMLPARSER_HPP #define DAVIX_DAVPROPXMLPARSER_HPP #include #include #include namespace Davix { class DavPropXMLParser : public XMLPropParser { public: struct DavxPropXmlIntern; DavPropXMLParser(); virtual ~DavPropXMLParser(); virtual std::deque & getProperties(); protected: virtual int parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts); virtual int parserCdataCb(int state, const char *cdata, size_t len); virtual int parserEndElemCb(int state, const char *nspace, const char *name); private: DavxPropXmlIntern* d_ptr; }; inline bool match_element(const char* c_origin, const char* c_pattern){ // C style, critical function return strcmp(c_origin,c_pattern) ==0; } } // namespace Davix #endif // DAVIX_DAVPROPXMLPARSER_HPP davix-R_0_5_0/src/xml/davxmlparser.cpp000066400000000000000000000077031257152637300200770ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "davxmlparser.hpp" namespace Davix { struct InternalDavParser{ static int dav_xml_parser_ne_xml_startelm_cb(void *userdata, int parent, const char *nspace, const char *name, const char **atts){ return static_cast(userdata)->parserStartElemCb(parent, nspace, name, atts); } static int dav_xml_ne_xml_cdata_cb(void *userdata, int state, const char *cdata, size_t len){ return static_cast(userdata)->parserCdataCb(state, cdata, len); } static int ne_xml_endelm_cb(void *userdata, int state, const char *nspace, const char *name){ return static_cast(userdata)->parserEndElemCb(state,nspace, name); } }; int davParserNotImplemented(){ throw Davix::DavixException(davix_scope_xml_parser(), StatusCode::OperationNonSupported, "the parser callbacks are not configured properly"); return -1; } XMLSAXParser::XMLSAXParser() : _ne_parser(ne_xml_create()) { ne_xml_push_handler(_ne_parser, &InternalDavParser::dav_xml_parser_ne_xml_startelm_cb, &InternalDavParser::dav_xml_ne_xml_cdata_cb, &InternalDavParser::ne_xml_endelm_cb, this); } XMLSAXParser::~XMLSAXParser(){ ne_xml_destroy(_ne_parser); } int XMLSAXParser::parseChunk(const char *partial_string, dav_size_t length){ int ret = ne_xml_parse(_ne_parser,partial_string,length); if(ret != 0){ if(ret > 0){ ret =-1; const char* ne_parser_err = ne_xml_get_error(_ne_parser); throw Davix::DavixException(davix_scope_xml_parser(), StatusCode::WebDavPropertiesParsingError, "XML Parsing Error: " + std::string((ne_parser_err)?ne_parser_err:"Unknow ne error")); } throw Davix::DavixException(davix_scope_xml_parser(), StatusCode::WebDavPropertiesParsingError, "Unknow XML parsing error "); } return ret; } int XMLSAXParser::parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts){ (void) parent; (void) nspace; (void) name; (void) atts; return davParserNotImplemented(); } int XMLSAXParser::parserCdataCb(int state, const char *cdata, size_t len){ (void) state; (void) cdata; (void) len; return davParserNotImplemented(); } int XMLSAXParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; (void) name; return davParserNotImplemented(); } int XMLSAXParser::startElemCb(const Chunk & data, const std::vector & attrs){ (void) data; (void) attrs; return -1; } int XMLSAXParser::cdataCb(const Chunk & data){ (void) data; return -1; } int XMLSAXParser::endElemCb(const Chunk & data){ (void) data; return 0; } int XMLSAXParser::commentCb(const Chunk & data){ (void) data; return 0; } } // namespace Davix davix-R_0_5_0/src/xml/davxmlparser.hpp000066400000000000000000000061431257152637300201010ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef DAVIX_DAVXMLPARSER_H #define DAVIX_DAVXMLPARSER_H #include #include #include #include #include namespace Davix { class XMLSAXParser : NonCopyable { public: typedef std::string::iterator startIterChunk; typedef std::string::iterator endIterChunk; typedef std::pair Chunk; XMLSAXParser(); virtual ~XMLSAXParser(); // // parse a block of character with a maximum size of 'len' characters // return negative value if failure or 0 if success int parseChunk(const char * partial_string, dav_size_t len); inline int parseChunk(const std::string & partial_string){ return parseChunk(partial_string.c_str(), partial_string.size()); } protected: /// /// callback to reimplement in subclass for parsing /// codes : /// retcode < 0 -> error /// retcode == 0 -> skip this element /// retcode > 0 -> accept this element /// start element callback virtual int parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts); /// cdata element callback virtual int parserCdataCb(int state, const char *cdata, size_t len); /// end element callback virtual int parserEndElemCb(int state, const char *nspace, const char *name); /// start element callback virtual int startElemCb(const Chunk & data, const std::vector & attrs); virtual int cdataCb(const Chunk & data); virtual int endElemCb(const Chunk & data); virtual int commentCb(const Chunk & data); private: ne_xml_parser* _ne_parser; friend struct InternalDavParser; }; class ElementsParser { public: ElementsParser(){} virtual ~ElementsParser(){} virtual std::deque & getProperties()=0; }; class XMLPropParser: public XMLSAXParser, public ElementsParser{ public: XMLPropParser(){} virtual ~XMLPropParser(){} }; } // namespace Davix #endif // DAVIX_DAVXMLPARSER_H davix-R_0_5_0/src/xml/metalinkparser.cpp000066400000000000000000000140201257152637300203760ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "metalinkparser.hpp" #include #include namespace Davix{ using namespace StrUtil; const std::string MetalinkScope = "MetalinkParser"; const std::string tags_string[] = { "metalink", "files", "file", "size", "resources", "url" }; const size_t tags_string_size = (sizeof(tags_string))/((sizeof(std::string ))); const MetalinkTag::MetalinkParserTag url_stack[] = { MetalinkTag::Metalink, MetalinkTag::Files, MetalinkTag::File, MetalinkTag::Resources, MetalinkTag::Url }; const size_t url_stack_size= (sizeof(url_stack))/(sizeof(MetalinkTag::MetalinkParserTag)); const MetalinkTag::MetalinkParserTag url_stack_meta4[] = { MetalinkTag::Metalink, MetalinkTag::File, MetalinkTag::Url }; const size_t url_stack_size_meta4= (sizeof(url_stack_meta4))/(sizeof(MetalinkTag::MetalinkParserTag)); const MetalinkTag::MetalinkParserTag size_stack[] = { MetalinkTag::Metalink, MetalinkTag::Files, MetalinkTag::File, MetalinkTag::Size }; const size_t size_stack_size= (sizeof(size_stack))/(sizeof(MetalinkTag::MetalinkParserTag)); const MetalinkTag::MetalinkParserTag size_stack_meta4[] = { MetalinkTag::Metalink, MetalinkTag::File, MetalinkTag::Size }; const size_t size_stack_size_meta4= (sizeof(size_stack_meta4))/(sizeof(MetalinkTag::MetalinkParserTag)); static MetalinkTag::MetalinkParserTag getTag(const std::string & str){ const std::string* p = std::find(tags_string, tags_string + tags_string_size, str); if(p < ( tags_string + tags_string_size)) return static_cast(p-tags_string); return MetalinkTag::Invalid; } static bool matchStack(const MetalinkStack & s1, const MetalinkTag::MetalinkParserTag* tab, size_t s_tab){ if(s1.size() != s_tab) return false; return std::equal(s1.begin(), s1.end(), tab); } struct MetalinkParser::MetalinkParserIntern{ MetalinkParserIntern(Context & c, std::vector & fvec) : _c(c), _fvec(fvec), _tagStack(), _filesize(0){ _tagStack.reserve(5); } inline int startElem(const std::string & name){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "MetalinkParser: {}", name.c_str()); const MetalinkTag::MetalinkParserTag t = getTag(name); if( t == MetalinkTag::Invalid){ return 0; } _tagStack.push_back(t); return 1; } inline int dataElem(const char* data, size_t len){ _buffer.reserve(_buffer.size()+len+1); std::copy(data, data+len, std::back_inserter(_buffer)); return 0; } inline int endElem(const std::string & name){ const MetalinkTag::MetalinkParserTag t = getTag(name); StrUtil::trim(_buffer); std::string & replic = _buffer; // metalink 3.0 if(matchStack(_tagStack, url_stack, url_stack_size)){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "MetalinkParser 3.0 : Replica URL {}", replic.c_str()); _fvec.push_back(File(_c, Uri(replic))); } if(matchStack(_tagStack, size_stack, size_stack_size)){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "MetalinkParser 3.0 : Replica size {}", replic.c_str()); try{ _filesize = toType()(replic); }catch(...){ _filesize =0; } } // metalink 4.0 if(matchStack(_tagStack, url_stack_meta4, url_stack_size_meta4)){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "MetalinkParser 4.0 : Replica URL {}", replic.c_str()); _fvec.push_back(File(_c, Uri(replic))); } if(matchStack(_tagStack, size_stack_meta4, size_stack_size_meta4)){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "MetalinkParser 4.0 : Replica size {}", replic.c_str()); try{ _filesize = toType()(replic); }catch(...){ _filesize =0; } } _buffer.clear(); if(t == _tagStack.back()) _tagStack.pop_back(); return 0; } Context & _c; std::vector & _fvec; MetalinkStack _tagStack; dav_size_t _filesize; std::string _buffer; }; MetalinkParser::MetalinkParser(Context & u, std::vector & vec) : d_ptr(new MetalinkParserIntern(u, vec)) { } MetalinkParser::~MetalinkParser(){ delete d_ptr; } dav_size_t MetalinkParser::getSize() const{ return d_ptr->_filesize; } int MetalinkParser::parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts){ (void) parent; (void) nspace; (void) atts; return d_ptr->startElem(name); } int MetalinkParser::parserCdataCb(int state, const char *cdata, size_t len){ (void) state; return d_ptr->dataElem(cdata, len); } int MetalinkParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; return d_ptr->endElem(name); } } davix-R_0_5_0/src/xml/metalinkparser.hpp000066400000000000000000000037151257152637300204140ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef METALINKPARSER_HPP #define METALINKPARSER_HPP #include #include namespace Davix{ namespace MetalinkTag{ enum MetalinkParserTag{ Metalink = 0x00, Files = 0x01, File = 0x02, Size = 0x03, Resources = 0x04, Url = 0x05, Invalid = 0xFF }; } typedef std::vector MetalinkStack; class MetalinkParser : public XMLSAXParser { public: struct MetalinkParserIntern; MetalinkParser(Context & c, std::vector & vec); virtual ~MetalinkParser(); dav_size_t getSize() const; protected: virtual int parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts); virtual int parserCdataCb(int state, const char *cdata, size_t len); virtual int parserEndElemCb(int state, const char *nspace, const char *name); private: MetalinkParserIntern* d_ptr; }; } #endif // METALINKPARSER_HPP davix-R_0_5_0/src/xml/s3deleteparser.cpp000066400000000000000000000126071257152637300203130ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "s3deleteparser.hpp" #include #include #include namespace Davix{ const std::string delete_result_prop = "DeleteResult"; const std::string delete_prop = "Deleted"; const std::string key_prop = "Key"; const std::string error_prop = "Error"; const std::string code_prop = "Code"; const std::string message_prop = "Message"; struct S3DeleteParser::Internal{ std::string current; std::string prefix; int entry_count; std::stack stack_status; std::deque del_status; FileDeleteStatus status; std::deque props; // not used int start_elem(const std::string &elem){ // new tag, clean content; current.clear(); // check XML nested level, security protection if(stack_status.size() < 200){ stack_status.push(elem); }else{ throw DavixException(davix_scope_xml_parser(), StatusCode::ParsingError, "Impossible to parse S3 content, corrupted XML"); } // check element, if it is "deleted" this recource has beed deleted successfully // or the resource did not exist in the first place, either way, log it if( StrUtil::compare_ncase(delete_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "deleted entry found", elem.c_str()); status.clear(); entry_count = 0; } // check element, if "Error" there has been problem with deleting this resource // the code returned will have to be mapped to http code if( StrUtil::compare_ncase(error_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "error entry found", elem.c_str()); status.clear(); status.error = true; entry_count = 0; } return 1; } int add_chunk(const std::string & chunk){ current.append(chunk); return 0; } int end_elem(const std::string &elem){ StrUtil::trim(current); // if "Key", current is file name // if "Code", current is error code // if "Message", current is error message // if "Delete", end of successful delete entry for that resource, push it if( StrUtil::compare_ncase(delete_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push deleted status for {}", status.filename.c_str()); del_status.push_back(status); entry_count++; } // if "Error", end of error entry for that resource, push it if( StrUtil::compare_ncase(error_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push error status for {}", status.filename.c_str()); del_status.push_back(status); entry_count++; } // if "Key", current is file name if( StrUtil::compare_ncase(key_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "key found for {}", current); status.filename = current; } // if "Code", current is error code if( StrUtil::compare_ncase(code_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "code found {}", current); status.error_code = current; } // if "Message", current is error message if( StrUtil::compare_ncase(message_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "error message found {}", current); status.message = current; } // reduce stack size if(stack_status.size() > 0) stack_status.pop(); current.clear(); return 0; } }; S3DeleteParser::S3DeleteParser() : d_ptr(new Internal()) { } S3DeleteParser::~S3DeleteParser(){ } int S3DeleteParser::parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts){ (void) parent; (void) nspace; (void) atts; return d_ptr->start_elem(std::string(name)); } int S3DeleteParser::parserCdataCb(int state, const char *cdata, size_t len){ (void) state; (void) len; return d_ptr->add_chunk(std::string(cdata, len)); } int S3DeleteParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; return d_ptr->end_elem(std::string(name)); } std::deque & S3DeleteParser::getDeleteStatus(){ return d_ptr->del_status; } // not used std::deque & S3DeleteParser::getProperties(){ return d_ptr->props; } } davix-R_0_5_0/src/xml/s3deleteparser.hpp000066400000000000000000000033021257152637300203100ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef S3DELETEPARSER_HPP #define S3DELETEPARSER_HPP #include #include #include #include #include namespace Davix{ class S3DeleteParser : public XMLPropParser { public: struct Internal; S3DeleteParser(); virtual ~S3DeleteParser(); virtual std::deque & getProperties(); // not used std::deque & getDeleteStatus(); protected: virtual int parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts); virtual int parserCdataCb(int state, const char *cdata, size_t len); virtual int parserEndElemCb(int state, const char *nspace, const char *name); private: Ptr::Scoped d_ptr; }; } #endif // S3DELETEPARSER_HPP davix-R_0_5_0/src/xml/s3propparser.cpp000066400000000000000000000213201257152637300200210ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "s3propparser.hpp" #include #include #include namespace Davix{ const std::string col_prop = "Name"; const std::string delimiter_prop ="Contents"; const std::string name_prop = "Key"; const std::string size_prop = "Size"; const std::string prefix_prop = "Prefix"; const std::string com_prefix_prop = "CommonPrefixes"; const std::string listbucketresult_prop = "ListBucketResult"; const std::string last_modified_prop = "LastModified"; struct S3PropParser::Internal{ std::string current; std::string prefix; std::string prefix_to_remove; bool inside_com_prefix; int prop_count; std::stack stack_status; std::deque props; FileProperties property; S3ListingMode::S3ListingMode _s3_listing_mode; int start_elem(const std::string &elem){ // new tag, clean content; current.clear(); // check XML nested level, security protection if(stack_status.size() < 200){ stack_status.push(elem); }else{ throw DavixException(davix_scope_xml_parser(), StatusCode::ParsingError, "Impossible to parse S3 content, corrupted XML"); } // check element, if collection name add first entry if( StrUtil::compare_ncase(col_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "collection found", elem.c_str()); property.clear(); prop_count = 0; } // check element, if new entry clear current entry if( StrUtil::compare_ncase(delimiter_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "new element found", elem.c_str()); property.clear(); } // check element, if common prefixes set flag if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(com_prefix_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "common prefixes found", elem.c_str()); inside_com_prefix = true; } // check element, if prefix clear current entry if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(prefix_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "prefix found", elem.c_str()); property.clear(); } return 1; } int add_chunk(const std::string & chunk){ current.append(chunk); return 0; } int end_elem(const std::string &elem){ StrUtil::trim(current); // found prefix if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(prefix_prop, elem) ==0 && !current.empty()){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "new prefix {}", current.c_str()); prefix = current; if(inside_com_prefix){ // all keys would have been processed by now, just common prefixes left, use as DIRs DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push new common prefix {}", current.c_str()); current = current.erase(current.size()-1,1); property.filename = current.erase(0, prefix_to_remove.size()); property.info.mode = 0755 | S_IFDIR; property.info.mode &= ~(S_IFREG); props.push_back(property); prop_count++; } } // new name new fileprop if( StrUtil::compare_ncase(name_prop, elem) ==0){ if((_s3_listing_mode == S3ListingMode::Flat)){ // flat mode property.filename = current.erase(0,prefix.size()); } else if(prefix.empty()){ // at root level property.filename = current; } else if(!prefix.empty()){ if(prefix.compare((prefix.size()-1),1,"/")){ // prefix doesn't end with '/', file property.filename = current; } else if(!(StrUtil::compare_ncase(prefix, current) ==0)){ // folder property.filename = current.erase(0, prefix_to_remove.size()); } } if(!property.filename.empty()) property.info.mode = 0755; } if( StrUtil::compare_ncase(size_prop, elem) ==0){ try{ dav_size_t size = toType()(current); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "element size {}", size); property.info.size = size; }catch(...){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "Unable to parse element size"); } } if( StrUtil::compare_ncase(last_modified_prop, elem) ==0){ try{ time_t mtime = S3::s3TimeConverter(current); DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "element LastModified {}", current); property.info.mtime = mtime; property.info.ctime = mtime; }catch(...){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "Unable to parse element LastModified"); } } // found bucket name // push it as first item to identify bucket if( StrUtil::compare_ncase(col_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push collection", elem.c_str()); property.filename = current; property.info.mode |= S_IFDIR; property.info.mode &= ~(S_IFREG); props.push_back(property); } // check element, if end entry push new entry if( StrUtil::compare_ncase(delimiter_prop, elem) ==0){ DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push new element {}", elem.c_str()); props.push_back(property); prop_count++; } // check element, if end common prefix reset flag if( (_s3_listing_mode == S3ListingMode::Hierarchical) && StrUtil::compare_ncase(com_prefix_prop, elem) ==0){ inside_com_prefix = false; } // end of xml respond and still no property, requested key exists but isn't a directory if( (_s3_listing_mode == S3ListingMode::Hierarchical) && (StrUtil::compare_ncase(listbucketresult_prop, elem) ==0) && (prop_count ==0) ){ throw DavixException(davix_scope_directory_listing_str(), StatusCode::IsNotADirectory, "Not a S3 directory"); } // reduce stack size if(stack_status.size() > 0) stack_status.pop(); current.clear(); return 0; } }; S3PropParser::S3PropParser() : d_ptr(new Internal()) { S3PropParser(S3ListingMode::Hierarchical, ""); } S3PropParser::S3PropParser(S3ListingMode::S3ListingMode s3_listing_mode) : d_ptr(new Internal()) { S3PropParser(s3_listing_mode, ""); } S3PropParser::S3PropParser(S3ListingMode::S3ListingMode s3_listing_mode, std::string s3_prefix) : d_ptr(new Internal()) { d_ptr->_s3_listing_mode = s3_listing_mode; if(!s3_prefix.empty()){ if(s3_prefix.compare(s3_prefix.size()-1,1,"/")==0) d_ptr->prefix_to_remove = s3_prefix.erase(0,1); else d_ptr->prefix_to_remove = s3_prefix; } } S3PropParser::~S3PropParser(){ } int S3PropParser::parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts){ (void) parent; (void) nspace; (void) atts; return d_ptr->start_elem(std::string(name)); } int S3PropParser::parserCdataCb(int state, const char *cdata, size_t len){ (void) state; (void) len; return d_ptr->add_chunk(std::string(cdata, len)); } int S3PropParser::parserEndElemCb(int state, const char *nspace, const char *name){ (void) state; (void) nspace; return d_ptr->end_elem(std::string(name)); } std::deque & S3PropParser::getProperties(){ return d_ptr->props; } } davix-R_0_5_0/src/xml/s3propparser.hpp000066400000000000000000000034121257152637300200300ustar00rootroot00000000000000/* * This File is part of Davix, The IO library for HTTP based protocols * Copyright (C) CERN 2013 * Author: Adrien Devresse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef S3PROPPARSER_HPP #define S3PROPPARSER_HPP #include #include #include #include #include namespace Davix{ class S3PropParser : public XMLPropParser { public: struct Internal; S3PropParser(); S3PropParser(S3ListingMode::S3ListingMode s3_listing_mode); S3PropParser(S3ListingMode::S3ListingMode s3_listing_mode, std::string s3_prefix); virtual ~S3PropParser(); virtual std::deque & getProperties(); protected: virtual int parserStartElemCb(int parent, const char *nspace, const char *name, const char **atts); virtual int parserCdataCb(int state, const char *cdata, size_t len); virtual int parserEndElemCb(int state, const char *nspace, const char *name); private: Ptr::Scoped d_ptr; }; } #endif // S3PROPPARSER_HPP davix-R_0_5_0/test/000077500000000000000000000000001257152637300142445ustar00rootroot00000000000000davix-R_0_5_0/test/CMakeLists.txt000066400000000000000000000007011257152637300170020ustar00rootroot00000000000000# main file for src # force RPATH usage for easy test execution set(CMAKE_SKIP_RPATH OFF CACHE BOOL "" FORCE) include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src/) link_directories(${PROJECT_BINARY_DIR}/src/) set(TEST_CRED_PATH "${CMAKE_CURRENT_SOURCE_DIR}/certs/my_keycert.p12") set(TEST_CRED_PASS "testpass") add_subdirectory(unit) add_subdirectory(functional) add_subdirectory(root-tests) add_subdirectory(bench) davix-R_0_5_0/test/bench/000077500000000000000000000000001257152637300153235ustar00rootroot00000000000000davix-R_0_5_0/test/bench/CMakeLists.txt000066400000000000000000000016161257152637300200670ustar00rootroot00000000000000# main file for src if(BENCH_TESTS) LIST(APPEND src_davix_bench "davix_bench.cpp" "chunk_queue.cpp") #include_directories(/usr/include/davix) add_executable(davix-bench ${src_davix_bench}) target_link_libraries(davix-bench libdavix ${CMAKE_THREAD_LIBS_INIT}) function(test_read url opt input) add_test(test_bench_read_${url} davix-bench ${opt} ${url} ${input}) endfunction(test_read url opt) function(test_vector_read url opt input) add_test(test_bench_vector_read_${url} davix-bench ${opt} ${url} ${input}) endfunction(test_vector_read url opt) function(test_thread_read url opt input) add_test(test_bench_thread_read_${url} davix-bench ${opt} ${url} ${input}) endfunction(test_thread_read url opt) function(test_write url opt input) add_test(test_bench_write_${url} davix-bench ${opt} ${url} ${input}) endfunction(test_write url opt) include(ctest_bench.cmake) endif(BENCH_TESTS) davix-R_0_5_0/test/bench/chunk_queue.cpp000066400000000000000000000045201257152637300203440ustar00rootroot00000000000000#include "chunk_queue.h" #include #include #include ChunkQueue::ChunkQueue() { pthread_mutex_init(&workmutex, NULL); pthread_cond_init(&popconvar, NULL); pthread_cond_init(&pushconvar, NULL); state = STARTED; } ChunkQueue::~ChunkQueue() { for(unsigned int i = 0; i < workqueue.size(); ++i) { delete(workqueue[i]); } } void ChunkQueue::pushOp(long len, long oset, DAVIX_FD* davfd) { struct timespec to; bool pushed = false; pthread_mutex_lock(&workmutex); to.tv_sec = time(NULL) + DEFAULT_WAIT_TIME; to.tv_nsec = 0; while(!pushed) { if(workqueue.size() < 1000) { worktoken* tk = new(worktoken); tk->length = len; tk->offset = oset; tk->fd = davfd; workqueue.push_back(tk); pushed = true; break; } int rc = pthread_cond_timedwait(&pushconvar, &workmutex, &to); if(rc == ETIMEDOUT) { std::cerr << std::endl << "pushOp() timed out." << std::endl; break; } } //signal worker, job available pthread_mutex_unlock(&workmutex); pthread_cond_signal(&popconvar); } struct ChunkQueue::worktoken *ChunkQueue::getOp() { struct worktoken* mytk = 0; struct timespec to; pthread_mutex_lock(&workmutex); to.tv_sec = time(NULL) + DEFAULT_WAIT_TIME; to.tv_nsec = 0; while(!mytk) { if(workqueue.size() > 0) { mytk = workqueue.front(); workqueue.pop_front(); break; } int rc = pthread_cond_timedwait(&popconvar, &workmutex, &to); if(rc == ETIMEDOUT) { std::cerr << std::endl << "getOp() timed out." << std::endl; break; } } pthread_mutex_unlock(&workmutex); // there is now room in the workqueue, signal producer pthread_cond_signal(&pushconvar); return (mytk); } void ChunkQueue::StopThreads() { state = STOPPED; pthread_cond_broadcast(&pushconvar); pthread_cond_broadcast(&popconvar); } int ChunkQueue::GetQueueSize() { return workqueue.size(); } int ChunkQueue::GetQueueState() { return state; } void ChunkQueue::SetQueueState(int new_state) { state = new_state; } davix-R_0_5_0/test/bench/chunk_queue.h000066400000000000000000000014021257152637300200050ustar00rootroot00000000000000#ifndef CHUNK_QUEUE #define CHUNK_QUEUE #include #include #include #define DEFAULT_WAIT_TIME 5 const int STARTED = 1; const int STOPPED = 2; class ChunkQueue { public: ChunkQueue(); ~ChunkQueue(); struct worktoken { long length; long offset; DAVIX_FD* fd; }; void pushOp(long len, long oset, DAVIX_FD* davfd); struct worktoken *getOp(); void StopThreads(); int GetQueueSize(); int GetQueueState(); void SetQueueState(int new_state); private: /// Queue of the pending operations std::deque workqueue; pthread_mutex_t workmutex; pthread_cond_t popconvar; pthread_cond_t pushconvar; int state; }; #endif davix-R_0_5_0/test/bench/ctest_bench.cmake000066400000000000000000000022361257152637300206110ustar00rootroot00000000000000## ctest script file for automated bench tests for davix # message (" Setup tests parameters... ") set(INPUT_FILE "-iinputfile.txt") set(READ_OPT "-r") set(READ_VECTOR_OPT "-v50") set(READ_THREAD_OPT "-t4") set(WRITE_OPT "-w") set(http_desy_base "https://vm-dcache-deploy6.desy.de:2880/dteam/davix-tests" CACHE STRING "dCache test instance to use") set(http_lcgdm_base "https://lxfsra04a04.cern.ch/dpm/cern.ch/home/dteam" CACHE STRING "DPM test instance to use" ) set(http_lcgdm_base_write "https://lxfsra04a04.cern.ch/dpm/cern.ch/home/dteam/davix_bench_writetest" CACHE STRING "DPM test instance to use" ) # DPM tests test_read("${http_lcgdm_base}" "${READ_OPT}" "${INPUT_FILE}") test_vector_read("${http_lcgdm_base}" "${READ_VECTOR_OPT}" "${INPUT_FILE}") test_thread_read("${http_lcgdm_base}" "${READ_THREAD_OPT}" "${INPUT_FILE}") test_write("${http_lcgdm_base_write}" "${WRITE_OPT}" "${INPUT_FILE}") test_read("${http_desy_base}" "${READ_OPT}" "${INPUT_FILE}") test_vector_read("${http_desy_base}" "${READ_VECTOR_OPT}" "${INPUT_FILE}") test_thread_read("${http_desy_base}" "${READ_THREAD_OPT}" "${INPUT_FILE}") test_write("${http_desy_base}" "${WRITE_OPT}" "${INPUT_FILE}") davix-R_0_5_0/test/bench/davix_bench.cpp000066400000000000000000000713031257152637300203050ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include "chunk_queue.h" #define BUFFER_SIZE 100 // in MB #define MAX_READ_PER_LOOP 20480 using namespace Davix; using namespace std; // command line options struct Options { RequestParams params; char mode; int vec_size; int no_of_thread; bool check; bool debug; bool silent; bool hasinputfile; std::vector vec_arg; std::string inputfile; Options() : params(), mode(), vec_size(), no_of_thread(), check(false), debug(false), silent(false), hasinputfile(false), vec_arg(), inputfile() { } }; // producer thread arguments struct ProducerArgs { long* length; long* offset; int nread; DAVIX_FD* fd; ChunkQueue* cq; }; // reader threads arguments struct ReaderArgs { DAVIX_FD* fd; ChunkQueue* cq; struct Options* opts; DavPosix* infile; bool* iserror; long* totalreadscount; long long* totalbytesread; pthread_mutex_t* mutex; }; int ParseOptions(int argc, char* argv[], Options & p); void PrintUsage(); int ReadSome(long *offs, long *lens, int maxnread, long long &totalbytes, bool &last_iter, Options &p, ifstream& in_file); void errorPrint(DavixError ** err); void* ThreadRead(void* args); void* PopulateQueue(void* args); int main(int argc, char* argv[]) { void *buffer = NULL; timeval tv; double starttime = 0, openphasetime = 0, endtime = 0, closetime = 0; Options opts; DAVIX_FD* fd; Context context; DavixError* tmp_err = NULL; string summarypref = "$$$"; string opt_type = "read"; string filepath; bool iserror = false; bool last_batch = false; DavPosix* infile = new DavPosix(&context); std::vector filename; std::vector davfd_vec; std::vector fd_vec; std::vector dfile_vec; std::vector DavErr_vec; int file_count = 0; long long totalbytesread = 0, prevtotalbytesread = 0, totalbytestoprocess = 0; long totalreadscount = 0, totalwritecount = 0, totalbyteswritten = 0; int ret = -1; ChunkQueue cq; // enable grid mode context.loadModule("grid"); gettimeofday(&tv, 0); starttime = tv.tv_sec + tv.tv_usec / 1000000.0; closetime = openphasetime = starttime; ParseOptions(argc, argv, opts); buffer = malloc(BUFFER_SIZE*1024*1024); cout << endl; bool isURL = !(opts.vec_arg[0].find("http") == string::npos); if(isURL) { switch(opts.mode) { case 'r': case 't': case 'v': { cout << "Opening - " << opts.vec_arg[0] << " --------------------- "; if((fd = infile->open(NULL, opts.vec_arg[0], O_RDONLY, &tmp_err)) != NULL) { cout << "success" << endl; davfd_vec.push_back(fd); filename.push_back(opts.vec_arg[0]); file_count++; } else { cout << "Failed" << endl << endl; if(tmp_err != NULL) { DavErr_vec.push_back(*tmp_err); errorPrint(&tmp_err); } iserror = true; } break; } case 'w': { cout << "Creating Davix file - " << opts.vec_arg[0] << endl; DavFile f(context, opts.vec_arg[0]); dfile_vec.push_back(f); filename.push_back(opts.vec_arg[0]); file_count++; break; } default: { cerr << endl << "Invaild option." << endl; PrintUsage(); exit(-1); } } // switch } // isURL else //isfile { ifstream files(opts.vec_arg[0].c_str() ); files >> filepath; switch(opts.mode) { case 'r': case 't': case 'v': { while(!files.eof() && files.good() ) { if(!filepath.empty() ) { cout << "Opening - " << filepath << " --------------------- "; if((fd = infile->open(NULL, filepath, O_RDONLY, &tmp_err)) != NULL) { cout << "Success" << endl; davfd_vec.push_back(fd); filename.push_back(filepath); file_count++; } else { cout << "Failed" << endl << endl; if(tmp_err != NULL) { DavErr_vec.push_back(*tmp_err); errorPrint(&tmp_err); } iserror = true; } } files >> filepath; } // while file break; } case 'w': { if(!files.good() ) // empty, file is write target { cout << "Creating Davix file - " << opts.vec_arg[0] << endl; DavFile f(context, opts.vec_arg[0]); dfile_vec.push_back(f); filename.push_back(filepath); file_count++; } else // file has content, read them { while(!files.eof() && files.good() ) { if(!filepath.empty() ) { cout << "Creating Davix file - " << filepath << endl; DavFile f(context, filepath); dfile_vec.push_back(f); filename.push_back(filepath); file_count++; } files >> filepath; } // while } break; } default: { cerr << endl << "Invaild option." << endl; PrintUsage(); exit(-1); } } // switch } // isfile gettimeofday(&tv, 0); openphasetime = tv.tv_sec + tv.tv_usec / 1000000.0; cout << endl; long long bytes_read = 0; int ntoread = 0; int maxtoread = MAX_READ_PER_LOOP; long v_offsets[MAX_READ_PER_LOOP]; long v_lens[MAX_READ_PER_LOOP]; DavIOVecInput inVec[opts.vec_size]; DavIOVecOuput outVec[opts.vec_size]; // Davix doesn't support remote pwrite yet, write to tmp file before uploading to simulate the effect std::FILE* tmpf = std::tmpfile(); int fdd = fileno(tmpf); ifstream input; if(opts.hasinputfile == true) { input.open(opts.inputfile.c_str(),ios::in); if(!input) { std::cerr << endl << "Cannot open input file."; return -1; } } while((ntoread = ReadSome(v_offsets, v_lens, maxtoread, totalbytestoprocess, last_batch, opts, input))) { cout << "."; switch(opts.mode) { case 'r': // non-vectored read { for(int i = 0; i < file_count; ++i) { cout << endl << "Reading - " << filename[i] << endl << endl; for(int j = 0; j < ntoread; j++) { bytes_read = infile->pread(davfd_vec[i], buffer, v_lens[j], v_offsets[j], &tmp_err); if(tmp_err != NULL) { DavErr_vec.push_back(*tmp_err); errorPrint(&tmp_err); iserror = true; break; } if(bytes_read <= 0) { cerr << "---Read (" << j+1 << " of " << ntoread << ") " << v_lens[j] << "@" << v_offsets[j] << " returned " << bytes_read << endl; iserror = true; break; } if(!opts.silent) { printf("%20s %-20ld", "Offset: ", v_offsets[j]); printf("%s %-20ld", "Length: ", v_lens[j]); printf("%s %-20lld\n", "Read: ", bytes_read); } totalbytesread += bytes_read; totalreadscount++; // do byte check here if(opts.check == true) { for(int k = 0; k < v_lens[j]; k++) { if(((k + v_offsets[j]) % 256) != ((unsigned char *)buffer)[k]) { cerr << "%Byte check -- Error in the file offset: " << k + v_offsets << " buffer: " << (int)((unsigned char *)buffer)[k] << " expected: " << (k+v_offsets[j]) % 256 << endl; iserror = true; break; } } if(!iserror && !opts.silent) { cout << "$Byte check -- Passed." << endl; } } } } break; } case 't': // threaded read { for(int i = 0; i < file_count; ++i) { cq.SetQueueState(STARTED); pthread_mutex_t mutex; cout << endl << "Reading - " << filename[i] << endl << endl; pthread_mutex_init(&mutex,0); // populate producer args ProducerArgs tk_args; tk_args.length = v_lens; tk_args.offset = v_offsets; tk_args.fd = davfd_vec[i]; tk_args.cq = &cq; tk_args.nread = ntoread; pthread_t producer; pthread_create(&producer, NULL, PopulateQueue, &tk_args); // populate reader args ReaderArgs r_args; r_args.fd = davfd_vec[i]; r_args.cq = &cq; r_args.opts = &opts; r_args.infile = infile; r_args.iserror = &iserror; r_args.totalreadscount = &totalreadscount; r_args.totalbytesread = &totalbytesread; r_args.mutex = &mutex; pthread_t read_thread[opts.no_of_thread]; for(int ii = 0; ii < opts.no_of_thread; ++ii) { pthread_create(&read_thread[ii], NULL, ThreadRead, &r_args); } for(int j = 0; j < opts.no_of_thread; ++j) { pthread_join(read_thread[j], NULL); cq.StopThreads(); } pthread_join(producer, NULL); pthread_mutex_destroy(&mutex); } break; } case 'v': // vectored read for(int i = 0; i < file_count; ++i) { cout << endl << "Reading - " << filename[i] << endl; cout << "Vector size - " << opts.vec_size << endl << endl; int no_of_input = ntoread; int vec_size = 0; for(int j = 0; j < ntoread;) { if(no_of_input > opts.vec_size) { vec_size = opts.vec_size; } else { vec_size = no_of_input; } for(int k = 0; k < vec_size; k++) { if( (k+j) >= MAX_READ_PER_LOOP) { break; } inVec[k].diov_offset = v_offsets[k+j]; inVec[k].diov_size = v_lens[k+j]; inVec[k].diov_buffer = buffer; if(!opts.silent) { printf("%20s %-20ld", "Offset: ", v_offsets[k+j]); printf("%s %-20ld\n", "Length: ", v_lens[k+j]); } } bytes_read = infile->preadVec(davfd_vec[i], inVec, outVec, vec_size, &tmp_err); if(tmp_err != NULL) { DavErr_vec.push_back(*tmp_err); errorPrint(&tmp_err); iserror = true; break; } if(bytes_read <= 0) { cerr << "---Read (" << j+1 << " of " << ntoread << ") " << v_lens[j] << "@" << v_offsets[j] << " returned " << bytes_read << endl; iserror = true; break; } if(!opts.silent) { printf("\n%20s %-20lld\n\n", "Read: ", bytes_read); } totalbytesread += bytes_read; totalreadscount++; no_of_input -= opts.vec_size; j += opts.vec_size; } } break; case 'w': // write { for(int i = 0; i < file_count; ++i) { // if file already exists, delete it. dfile_vec[i].deletion(&opts.params, NULL); int retval = 0; DavFile df_tmp(context, filename[i]); for(int j = 0; j < ntoread; j++) { for(int k = 0; k < v_lens[j]; k++) { ((unsigned char *)buffer)[k] = (v_offsets[j]+k) % 256; } ret = pwrite(fdd, buffer, v_lens[j], v_offsets[j]); if (ret <= 0) { cout << endl << "---Write (" << j+1 << " of " << ntoread << ") " << v_lens[j] << "@" << v_offsets[j] << " returned " << ret << endl; iserror = true; break; } if(retval != 0) { cerr << "DavFile write error: putFromFd" << endl; exit(-1); } if(!opts.silent) { printf("%20s %-20ld", "Offset: ", v_offsets[j]); printf("%s %-20ld\n", "Length: ", v_lens[j]); } } fseek(tmpf,0,SEEK_END); int size = ftell(tmpf); // upload only if this is the last iteration of the input loop if(last_batch == true) { retval = df_tmp.putFromFd(&opts.params, fdd, size, &tmp_err); if(tmp_err != NULL) { DavErr_vec.push_back(*tmp_err); errorPrint(&tmp_err); iserror = true; continue; } totalbyteswritten += size; totalwritecount++; cout << endl << "Write run completed on " << filename[i] << endl << endl; } } break; } default: { cerr << endl << "Option not reconised." << endl; PrintUsage(); exit(-1); break; } }// switch if (iserror && prevtotalbytesread) { totalbytesread = prevtotalbytesread; break; } prevtotalbytesread = totalbytesread; }// while ReadSome gettimeofday(&tv, 0); closetime = tv.tv_sec + tv.tv_usec / 1000000.0; cout << endl << "--- Closing all files." << endl; for(unsigned int i = 0; i < davfd_vec.size(); ++i) { infile->close(davfd_vec[i], &tmp_err); } close(fdd); delete(infile); cout << "--- Clearing pointer vector." << endl; davfd_vec.clear(); cout << "--- Freeing buffer." << endl; free(buffer); gettimeofday(&tv, 0); endtime = tv.tv_sec + tv.tv_usec / 1000000.0; if (iserror) summarypref = "%%%"; cout << fixed; cout << endl << "Summary ----------------------------" << endl; cout << summarypref << " Start time: " << starttime << endl; cout << summarypref << " Last open time: " << openphasetime << endl; cout << summarypref << " Close time: " << closetime << endl; cout << summarypref << " End time: " << endtime << endl; cout << summarypref << " Open elapsed: " << openphasetime - starttime << endl; cout << summarypref << " Data transfer elapsed: " << closetime - openphasetime << endl; cout << summarypref << " Close elapsed: " << endtime - closetime << endl; cout << summarypref << " Total elapsed: " << endtime - starttime << endl; if(opts.mode == 'w') { cout << summarypref << " Total bytes written: " << totalbyteswritten << endl; cout << summarypref << " Max bytes written per sec: " << totalbyteswritten / (closetime - openphasetime) << endl; cout << summarypref << " Effective bytes written per sec: " << totalbyteswritten / (endtime - starttime) << endl; cout << summarypref << " Write count: " << totalwritecount << endl; } else { cout << summarypref << " Total bytes to process: " << totalbytestoprocess * file_count << endl; cout << summarypref << " Total bytes read: " << totalbytesread << endl; cout << summarypref << " Max bytes read per sec: " << totalbytesread / (closetime - openphasetime) << endl; cout << summarypref << " Effective bytes read per sec: " << totalbytesread / (endtime - starttime) << endl; cout << summarypref << " Successful read count: " << totalreadscount << endl; switch(opts.mode) { case 'v': cout << summarypref << " Vector size: " << opts.vec_size << endl; break; case 't': cout << summarypref << " Number of thread(s): " << opts.no_of_thread << endl; break; } } cout << summarypref << " Opened file count: " << file_count << endl; cout << endl; // print out any unique ocurrence of DavixError if(!DavErr_vec.empty() ) { int err_code = 0; std::vector err_code_vec; err_code = DavErr_vec[0].getStatus(); err_code_vec.push_back(err_code); std::cerr << "Total DavixError: " << DavErr_vec.size() << endl << "Printing error type(s) -" << endl; std::cerr << "("<< DavErr_vec[0].getErrScope() <<") Error: "<< DavErr_vec[0].getErrMsg() << std::endl << std::endl; for(unsigned int z = 1; z < DavErr_vec.size(); ++z) { err_code = DavErr_vec[z].getStatus(); if (std::find(err_code_vec.begin(), err_code_vec.end(), err_code) == err_code_vec.end()) { err_code_vec.push_back(err_code); std::cerr << "("<< DavErr_vec[z].getErrScope() <<") Error: "<< DavErr_vec[z].getErrMsg() << std::endl << std::endl; } } DavErr_vec.clear(); } return 0; }// end of main //=================================================================================================================== //==================================================FUNCTIONS======================================================== //=================================================================================================================== void errorPrint(DavixError ** err) { if(err && *err){ std::cerr << "("<< (*err)->getErrScope() <<") Error: "<< (*err)->getErrMsg() << std::endl << std::endl; DavixError::clearError(err); } } int ReadSome(long *offs, long *lens, int maxnread, long long &totalbytes, bool &last_iter, Options &p, ifstream& in_file) { if(p.hasinputfile) { for (int i = 0; i < maxnread;) { lens[i] = -1; offs[i] = -1; if (in_file.eof()) { last_iter = true; return i; } in_file >> lens[i] >> offs[i]; if(lens[i] > (BUFFER_SIZE*1024*1024) ) { std::cerr << endl << "Length exceeds buffer size @ length: " << lens[i] << ", buffer: " << BUFFER_SIZE*1024*1024 << endl << endl; exit(-1); } if ((lens[i] > 0) && (offs[i] >= 0)) { totalbytes += lens[i]; i++; } } return maxnread; } else { for (int i = 0; i < maxnread;) { lens[i] = -1; offs[i] = -1; if (cin.eof()) { last_iter = true; return i; } cin >> lens[i] >> offs[i]; if(lens[i] > (BUFFER_SIZE*1024*1024) ) { std::cerr << endl << "Length exceeds buffer size @ length: " << lens[i] << ", buffer: " << BUFFER_SIZE*1024*1024 << endl << endl; exit(-1); } if ((lens[i] > 0) && (offs[i] >= 0)) { totalbytes += lens[i]; i++; } } return maxnread; } } int ParseOptions(int argc, char* argv[], Options & p) { const std::string arg_tool_main= "srwdchv:t:i:"; int ret = 0; if(argc < 2) { PrintUsage(); exit(-1); } while((ret = getopt(argc, argv, arg_tool_main.c_str() )) > 0) { switch(ret) { case 'r': p.mode = ret; break; case 'v': p.mode = ret; p.vec_size = atoi(optarg); if(p.vec_size <= 0) { std::cerr << endl << "Vector size must be a positive integer." << endl << endl; exit(-1); } break; case 't': p.mode = ret; p.no_of_thread = atoi(optarg); if(p.no_of_thread <= 0) { std::cerr << endl << "Number of threads must be a positive integer." << endl << endl; exit(-1); } case 'w': p.mode = ret; break; case 'h': PrintUsage(); exit(0); break; case 'c': p.check = true; break; case 'd': p.debug = true; davix_set_log_level(15); break; case 's': p.silent = true; break; case 'i': p.hasinputfile = true; p.inputfile = optarg; break; default: PrintUsage(); exit(-1); }// switch }// while getopt ret = -1; for(int i = optind; i < argc; ++i) { p.vec_arg.push_back(argv[i]); ret = 0; } if(ret != 0 && p.mode != 'h') { PrintUsage(); exit(-1); } return ret; } void* PopulateQueue(void* args) { ProducerArgs* tk = static_cast(args); for(int i = 0; i < tk->nread; ++i) { tk->cq->pushOp(tk->length[i], tk->offset[i], tk->fd); } while(true) { if(tk->cq->GetQueueSize() == 0) { // signal all workers to exit tk->cq->StopThreads(); break; } } return 0; } void* ThreadRead(void* args) { long long bytes_read = 0; void *buffer = NULL; DavixError* tmp_err = NULL; buffer = malloc(BUFFER_SIZE*1024*1024); ReaderArgs* rd = static_cast(args); while( rd->cq->GetQueueState() != STOPPED) { ChunkQueue::worktoken* tk = rd->cq->getOp(); bytes_read = rd->infile->pread(rd->fd, buffer, tk->length, tk->offset, &tmp_err); if(!rd->opts->silent) { printf("%20s %-20ld", "Offset: ", tk->offset); printf("%s %-20ld", "Length: ", tk->length); printf("%s %-20lld\n", "Read: ", bytes_read); } if (bytes_read <= 0) { cout << "---Read " << tk->length << "@" << tk->offset << " returned " << bytes_read << endl; *rd->iserror = true; errorPrint(&tmp_err); delete(tk); continue; } delete(tk); pthread_mutex_lock(rd->mutex); (*rd->totalbytesread) += bytes_read; (*rd->totalreadscount)++; pthread_mutex_unlock(rd->mutex); } free(buffer); return 0; } void PrintUsage() { std::cout << endl << endl << "This programme gets from the standard input a sequence of" << endl << " (one for each line, with less than " << BUFFER_SIZE << "MB in byte)" << endl << " and performs the corresponding read requests towards the given URL or to ALL" << endl << " the URLS contained in the given file." << endl << endl << "Usage: davix-bench [OPTIONS ...] \n" << endl << " Options:" << endl << " -h Display help and usage." << endl << " -r Non-vectored read." << endl << " -vn Vectored read of vector size n." << endl << " -tn Concurrent read of n threads." << endl << " -d Debug mode." << endl << " -s Silent mode." << endl << " -w Write mode, create file which is compatible with the -c option." << endl << " -i Read input from file instead of standard input." << endl << " -c Verify if the value of the byte at offset i is i%256. Valid only for the non-vectored(r) read mode." << endl << endl; } davix-R_0_5_0/test/bench_inputfile_gen.sh000077500000000000000000000006331257152637300205740ustar00rootroot00000000000000#!/bin/bash # # Generates an input file for davix-bench, containing a fixed number of line, with 2 random numbers on each line. # echo "Running script..." for i in {1..100}; do n=$(shuf -i 1-10000 -n 1); m=$(shuf -i 1-$n -n 1); echo "$n $m">>../build/test/bench/inputfile.txt; done #for i in {1..10000}; # do n=$(( (RANDOM % 10000) +1)); m=$(( (RANDOM % n) +1)); # echo "$n $m">>inputfile.txt; #done davix-R_0_5_0/test/certs/000077500000000000000000000000001257152637300153645ustar00rootroot00000000000000davix-R_0_5_0/test/certs/my_keycert.p12000066400000000000000000000034321257152637300200650ustar00rootroot0000000000000000 *H 00 *H 00} *H 0 *H  0k3 UZPdy?!h?hr@@f`,|;>Hc]cPEFdl)I1p=:_L$\*.cT5tg=+_ဈø}0f*һ`} lZϕRqN#C gC[ #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; Davix_fd* fd; ssize_t ret=1; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); char buff[2050]={0}; if(argc > 2){ configure_grid_env(argv[2], p); } if( (fd =pos.open(&p, argv[1], O_RDONLY, &tmp_err)) == NULL){ std::cerr << " error while opening file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } // std::cout << "file content " << std::endl; while( fd && (ret = pos.read(fd, buff, 2048, &tmp_err)) > 0){ buff[ret] = '\0'; std::cout << buff; } std::cout << std::endl; if(tmp_err){ std::cerr << " error while readding file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } if( (ret = pos.close(fd, &tmp_err))){ std::cerr << " error while closing file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } return 0; } davix-R_0_5_0/test/functional/davix_test_lib.cpp000066400000000000000000000070161257152637300221160ustar00rootroot00000000000000 #include "davix_test_lib.h" #include #include #include #include #include #include #include #include #include #include using namespace Davix; int mycred_auth_callback_x509(void* userdata, const SessionInfo & info, X509Credential * cred, DavixError** err){ (void) info; Davix::DavixError* tmp_err= NULL; std::string path((char*) userdata); int ret = cred->loadFromFileP12( path, "", &tmp_err); if(ret != 0){ fprintf(stderr, " FATAL authentification Error : %s", tmp_err->getErrMsg().c_str()); DavixError::propagateError(err, tmp_err); } return ret; } char* generate_random_uri(const char* uri_dir, const char* prefix, char* buff, size_t s_buff){ snprintf(buff, s_buff, "%s/%s_%d%ld%ld",uri_dir, prefix, (int)getpid() ,(long) time(NULL), (long) rand()); return buff; } Davix::Uri generate_random_uri(const Davix::Uri & url_directory, const std::string & prefix){ std::ostringstream ss; ss << url_directory << "/" << prefix << static_cast(getpid()) << static_cast(time(NULL)) << static_cast(rand()); return Davix::Uri(ss.str()); } void configure_grid_env(char * cert_path, RequestParams& p){ if(strcmp(cert_path, "proxy") == 0){ // VOMS PROXY MODE X509Credential x; std::string proxy_path; char* p_str; if ( (p_str = getenv("X509_USER_PROXY") ) != NULL ){ proxy_path = p_str; }else{ std::ostringstream ss; ss << "/tmp/x509up_u" << getuid(); proxy_path = ss.str(); } x.loadFromFilePEM(proxy_path,proxy_path,"", NULL); p.setClientCertX509(x); } else{ char login_passwd[strlen(cert_path)+1]; char* pstr; strcpy(login_passwd, cert_path); pstr = strchr(login_passwd, ':'); if( pstr != NULL){ *pstr= '\0'; pstr++; p.setClientLoginPassword(std::string(login_passwd), std::string(pstr)); } p.setClientCertCallbackX509(&mycred_auth_callback_x509, cert_path); } // add standard grid certificate for wlcg test p.addCertificateAuthorityPath("/etc/grid-security/certificates/"); // add wrong cert path for testing purpose p.addCertificateAuthorityPath("/Iamnotexisting"); p.addCertificateAuthorityPath(""); p.addCertificateAuthorityPath("/etc/group"); // add a file } char * generate_random_string_content(size_t size){ char * res = (char*) malloc(size * sizeof(char)); size_t i =0; while(i < size){ res[i]= (char) (((rand()%2)?65:97)+(rand()%26)); i++; } return res; } /* DAVIX_C_DECL_BEGIN void configure_grid_env_c(char * cert_path, davix_params_t params){ davix_error_t tmp_err=NULL; char login_passwd[strlen(cert_path)+1]; char* pstr; strcpy(login_passwd, cert_path); pstr = strchr(login_passwd, ':'); if( pstr != NULL){ *pstr= '\0'; pstr++; davix_params_set_login_passwd(params, login_passwd, pstr); }else{ davix_x509_cert_t cred = davix_x509_cert_new(); davix_x509_cert_load_from_p12(cred, cert_path, "", &tmp_err); if(tmp_err){ std::cerr << " failure when load cert : " << davix_error_msg(tmp_err) << std::endl; exit(-1); } davix_params_set_client_cert_X509(params, cred); davix_x509_cert_free(cred); } davix_params_set_ssl_check(params, false, &tmp_err); } DAVIX_C_DECL_END */ davix-R_0_5_0/test/functional/davix_test_lib.h000066400000000000000000000015341257152637300215620ustar00rootroot00000000000000#ifndef DAVIX_TEST_LIB_H #define DAVIX_TEST_LIB_H #include #include int mycred_auth_callback_x509(void* userdata, const Davix::SessionInfo & info, Davix::X509Credential * cert, Davix::DavixError** err); void configure_grid_env(char * auth_args, Davix::RequestParams& p); void configure_grid_env_bis(char * auth_args, Davix::RequestParams& p); char* generate_random_uri(const char* uri_dir, const char* prefix, char* buff, size_t s_buff); Davix::Uri generate_random_uri(const Davix::Uri & url_directory, const std::string & prefix); char * generate_random_string_content(size_t size); #define DAV_ASSERT_TRUE(test, failure_msg) \ do{ \ if(! (test) ){ \ std::cerr << "f:"<< __FILE__ << ":" << __LINE__ << ": " << failure_msg << std::endl; \ exit(-1); \ } \ }while(0) #endif // DAVIX_TEST_LIB_H davix-R_0_5_0/test/functional/test_auto_rmdir_unlink_delete.cpp000066400000000000000000000063771257152637300252350ustar00rootroot00000000000000 #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } RequestParams p; struct stat st; int res =-1; p.setProtocol(RequestProtocol::Webdav); DavixError* tmp_err=NULL; char * base_dir = argv[1]; char * cert_path = argv[2]; char buffer[2048]; if(argc > 2){ configure_grid_env(cert_path, p); } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); generate_random_uri(base_dir, "rmdir_unlink_delete_test", buffer, 2048); std::string created_dir(buffer); Context c; DavPosix pos(&c); std::cout << "verify that " << created_dir << "does not exist" << std::endl; res = pos.stat(&p, created_dir, &st, &tmp_err); assert( res != 0); assert(tmp_err && tmp_err->getStatus() == StatusCode::FileNotFound); DavixError::clearError(&tmp_err); std::cout << " verify that unlink() return enoent on not existing dir" << std::endl; res = pos.unlink(&p, created_dir, &tmp_err); assert( res != 0); assert(tmp_err && tmp_err->getStatus() == StatusCode::FileNotFound); DavixError::clearError(&tmp_err); std::cout << " verify that rmdir() return enoent on not existing dir" << std::endl; res = pos.rmdir(&p, created_dir, &tmp_err); assert( res != 0); assert(tmp_err && tmp_err->getStatus() == StatusCode::FileNotFound); DavixError::clearError(&tmp_err); std::cout << " verify that WebdavQuery::davDelete() return enoent on not existing dir" << std::endl; File f(c, created_dir); res = f.deletion(&p, &tmp_err); assert( res != 0); assert(tmp_err && tmp_err->getStatus() == StatusCode::FileNotFound); DavixError::clearError(&tmp_err); std::cout << "create " << created_dir << std::endl; res = pos.mkdir(&p, created_dir, 0755, &tmp_err); assert( res ==0 && tmp_err == NULL); std::cout << "verify that " << created_dir << "exist " << std::endl; res = pos.stat(&p, created_dir, &st, &tmp_err); assert( res == 0); assert(tmp_err == NULL); DavixError::clearError(&tmp_err); std::cout << "verify that unlink() does not delete directory " << std::endl; res = pos.unlink(&p, created_dir, &tmp_err); assert( res != 0); assert(tmp_err && tmp_err->getStatus() == StatusCode::IsADirectory); DavixError::clearError(&tmp_err); std::cout << "remove dir with rmdir() " << std::endl; res = pos.rmdir(&p, created_dir, &tmp_err); assert( res == 0); assert(tmp_err == NULL); std::cout << "verify that " << created_dir << "does not exist" << std::endl; res = pos.stat(&p, created_dir, &st, &tmp_err); assert( res != 0); assert(tmp_err && tmp_err->getStatus() == StatusCode::FileNotFound); DavixError::clearError(&tmp_err); std::cout << "create again " << created_dir << std::endl; res = pos.mkdir(&p, created_dir, 0755, &tmp_err); assert( res ==0 && tmp_err == NULL); return 0; } davix-R_0_5_0/test/functional/test_auto_stat_mkdir_check.cpp000066400000000000000000000035041257152637300245010ustar00rootroot00000000000000#include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [base_dir]" << std::endl; std::cout <<"\t" << argv[0] << " [base_dir] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); p.setProtocol(RequestProtocol::Webdav); if(argc > 2){ configure_grid_env(argv[2], p); } char buff[2048]; generate_random_uri(argv[1], "davix_test_stat", buff, 2048); struct stat st; // do a first stat, should return enoent std::cout << " stat enoent dir " << buff << std::endl; int ret = pos.stat(&p, buff, &st, &tmp_err); assert( ret < 0); if(tmp_err){ std::cout << " error " << (int) tmp_err->getStatus() << " msg " << tmp_err->getErrMsg() << std::endl; } assert(tmp_err && StatusCode::FileNotFound == tmp_err->getStatus()); DavixError::clearError(&tmp_err); std::cout << " create dir " << buff << std::endl; ret = pos.mkdir(&p, buff, 0755, &tmp_err); assert(0 == ret); assert(NULL == tmp_err); std::cout << " stat new dir " << std::endl; ret = pos.stat(&p, buff, &st, &tmp_err); assert(0 == ret); assert(S_ISDIR(st.st_mode)); std::cout << "stat success" << std::endl; std::cout << " atime : " << st.st_atime << std::endl; std::cout << " mtime : " << st.st_mtime << std::endl; std::cout << " ctime : " << st.st_ctime << std::endl; std::cout << " mode : 0" << std::oct << st.st_mode << std::endl; std::cout << " len : " << st.st_size << std::endl; return 0; } davix-R_0_5_0/test/functional/test_checksum.cpp000066400000000000000000000016201257152637300217520ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 3){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url] [algo]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [algo] [CERTIFICATE_PATH] " << std::endl; return 0; } RequestParams p; DavixError* tmp_err=NULL; Uri u(argv[1]); char* algo = argv[2]; Context c; File f(c,u); if(argc > 3){ configure_grid_env(argv[3], p); } std::string chk; int ret = f.checksum(&p, chk, algo, &tmp_err); if(ret ==0) std::cout << algo << " "<< chk << std::endl; else std::cout << "checksum error "<< tmp_err->getErrMsg() << std::endl; return 0; } davix-R_0_5_0/test/functional/test_directory.cpp000066400000000000000000000027761257152637300221710ustar00rootroot00000000000000#include "test_directory.hpp" #include #include "davix_test_lib.h" using namespace Davix; #define MY_BUFFER_SIZE 65000 int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } RequestParams params; struct stat st; int res =-1; DavixError* tmp_err=NULL; char * base_dir = argv[1]; char * cert_path = argv[2]; char buffer[2048]; if(argc > 2){ configure_grid_env(cert_path, params); } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); generate_random_uri(base_dir, "rmdir_unlink_delete_test", buffer, 2048); std::string created_dir(buffer); Context c; File f(c, std::string(buffer)), f2(c,std::string(buffer)); // delete unexisting dir, should fail res = f.deletion(¶ms, &tmp_err); assert( res <0); assert(tmp_err != NULL); assert(tmp_err->getStatus() == StatusCode::FileNotFound); DavixError::clearError(&tmp_err); // create dir res= f.makeCollection(¶ms, &tmp_err); assert(res >=0); assert(tmp_err == NULL); // test dir res= f2.stat(¶ms, &st, &tmp_err); assert(res ==0); assert(tmp_err == NULL); assert( S_ISDIR(st.st_mode) ); // delete dir res= f.deletion(¶ms, &tmp_err); assert(res >=0); assert(tmp_err == NULL); return 0; } davix-R_0_5_0/test/functional/test_directory.hpp000066400000000000000000000001251257152637300221600ustar00rootroot00000000000000#ifndef TEST_DIRECTORY_HPP #define TEST_DIRECTORY_HPP #endif // TEST_DIRECTORY_HPP davix-R_0_5_0/test/functional/test_listing.cpp000066400000000000000000000017571257152637300216340ustar00rootroot00000000000000#include "test_listing.hpp" #include #include "davix_test_lib.h" using namespace Davix; #define MY_BUFFER_SIZE 65000 int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } RequestParams params; char * cert_path = argv[2]; if(argc > 2){ configure_grid_env(cert_path, params); } Uri u(argv[1]); try{ Context c; File f(c, u); int i =0; File::Iterator it = f.listCollection(¶ms); do{ i +=1; std::cout << " " << it.name() << " stat " << it.info().mode << " " << it.info().size << std::endl; }while(it.next()); }catch(DavixException & e){ std::cerr << "Error: (" < #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); RequestParams p; DavixError* tmp_err=NULL; std::auto_ptr c( new Context()); DavPosix pos(c.get()); if(argc > 2){ configure_grid_env(argv[2], p); } std::ostringstream oss; oss << argv[1] << "/"<< (rand()%20000); std::string a = oss.str(); int ret = pos.mkdir(&p, a.c_str(), 0777, &tmp_err); if(ret ==0) std::cout << "mkdir success !" << std::endl; else std::cout << "mkdir error "<< tmp_err->getErrMsg() << std::endl; return 0; } davix-R_0_5_0/test/functional/test_mkdir.h000066400000000000000000000001031257152637300207160ustar00rootroot00000000000000#ifndef TEST_MKDIR_H #define TEST_MKDIR_H #endif // TEST_STAT_H davix-R_0_5_0/test/functional/test_mv.cpp000066400000000000000000000025001257152637300205700ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); RequestParams p; DavixError* tmp_err=NULL; //std::auto_ptr c( new Context()); Context c; DavPosix pos(&c); if(argc > 2){ configure_grid_env(argv[2], p); } std::string url = argv[1]; std::string a = generate_random_uri(Davix::Uri(url), "test_move").getString(); std::string b = a+"cake"; int ret = 0; // create dir if( (ret = pos.mkdir(&p, a.c_str(), 0777, &tmp_err) <0)) { std::cerr << "mkdir error "<< tmp_err->getErrMsg() << std::endl; return -1; } // rename file if( (ret = pos.rename(&p, a.c_str(), b.c_str(), &tmp_err) <0)) { std::cerr << "mv error "<< tmp_err->getErrMsg() << std::endl; return -1; } // remove dir DavFile f(c, b); f.deletion(&p, &tmp_err); return 0; } davix-R_0_5_0/test/functional/test_opendir.cpp000066400000000000000000000022261257152637300216130ustar00rootroot00000000000000#include "test_opendir.h" #include #include #include #include "davix_test_lib.h" using namespace Davix; #define MY_BUFFER_SIZE 65000 int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); if(argc > 2){ configure_grid_env(argv[2], p); } DAVIX_DIR* d = pos.opendir(&p, argv[1], &tmp_err); if(d != NULL){ struct dirent * dir = NULL; int n =0; do{ dir= pos.readdir(d, &tmp_err); if(dir) std::cout << "N° " << ++n <<" file : " << dir->d_name << std::endl; }while(dir!= NULL); pos.closedir(d, NULL); } if(tmp_err){ std::cout << " listing directory error "<< tmp_err->getErrMsg() << std::endl; return -1; } return 0; } davix-R_0_5_0/test/functional/test_opendir.h000066400000000000000000000001121257152637300212500ustar00rootroot00000000000000#ifndef TEST_OPENDIR_H #define TEST_OPENDIR_H #endif // TEST_OPENDIR_H davix-R_0_5_0/test/functional/test_opendir_partial.cpp000066400000000000000000000032301257152637300233230ustar00rootroot00000000000000#include "test_opendir_partial.h" #include #include #include #include #include #include #include "davix_test_lib.h" /** Execute an incomplete readdir of a directory, and verify the correct closedir with the memory cleaning */ using namespace Davix; #define MY_BUFFER_SIZE 65000 int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url] [size_to_read] " << std::endl; std::cout <<"\t" << argv[0] << " [url] [size_to_read] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); int max_read= atoi(argv[2]); std::cout << " end of the dir number " << max_read << std::endl; DavixError* tmp_err=NULL; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); if(argc > 3){ configure_grid_env(argv[3], p); } DAVIX_DIR* d = pos.opendir(&p, argv[1], &tmp_err); if(d){ struct dirent * dir = NULL; int n= 0; do{ dir= pos.readdir(d, &tmp_err); if(dir) std::cout << "N° " << n <<" file : " << dir->d_name << std::endl; n++; }while(dir!= NULL && max_read > n); if(dir == NULL){ std::cout << " Normal end of the directory, too little directory, error in the test " << std::endl; return -3; } } pos.closedir(d, NULL); if(tmp_err){ std::cout << " listing directory error "<< tmp_err->getErrMsg() << std::endl; return -1; } return 0; } davix-R_0_5_0/test/functional/test_opendir_partial.h000066400000000000000000000001121257152637300227640ustar00rootroot00000000000000#ifndef TEST_OPENDIR_H #define TEST_OPENDIR_H #endif // TEST_OPENDIR_H davix-R_0_5_0/test/functional/test_opendirpp.cpp000066400000000000000000000024161257152637300221540ustar00rootroot00000000000000#include "test_opendirpp.h" #include #include #include #include "davix_test_lib.h" using namespace Davix; #define MY_BUFFER_SIZE 65000 int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); Davix::DavixError* tmp_err; if(argc > 2){ configure_grid_env(argv[2], p); } DAVIX_DIR* d = pos.opendirpp(&p, argv[1], &tmp_err); if(d){ struct dirent * dir = NULL; int n =0; do{ struct stat st; dir= pos.readdirpp(d, &st, &tmp_err); if(dir) std::cout << "N° " << ++n <<" file : " << dir->d_name <<" len : " << st.st_size << " atime: "<< st.st_atime << " mode : "<< std::oct << st.st_mode; std::cout << " mtime : " << st.st_mtime ; std::cout << " ctime : " << st.st_ctime << std::endl; }while(dir!= NULL); pos.closedirpp(d, &tmp_err); } return 0; } davix-R_0_5_0/test/functional/test_opendirpp.h000066400000000000000000000001121257152637300216100ustar00rootroot00000000000000#ifndef TEST_OPENDIR_H #define TEST_OPENDIR_H #endif // TEST_OPENDIR_H davix-R_0_5_0/test/functional/test_propfind.cpp000066400000000000000000000015641257152637300220000ustar00rootroot00000000000000#include "test_propfind.h" #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage " << argv[0] << " [url]" << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); RequestParams params; DavixError* tmp_err=NULL; Context c; if(argc >2 ){ // setup ops if credential is found params.setSSLCAcheck(false); } HttpRequest r(c, argv[1], &tmp_err); r.setParameters(params); r.addHeaderField("Depth", "1"); std::vector body = req_webdav_propfind(&r, &tmp_err); std::string v(body.begin(), body.end()); std::cout << "content "<< v << std::endl; if(tmp_err){ std::cerr << " req error " << tmp_err->getErrMsg() << std::endl; } return 0; } davix-R_0_5_0/test/functional/test_propfind.h000066400000000000000000000001131257152637300214320ustar00rootroot00000000000000#ifndef TEST_PROPFIND_H #define TEST_PROPFIND_H #endif // TEST_PROPFIND_H davix-R_0_5_0/test/functional/test_request.cpp000066400000000000000000000012071257152637300216410ustar00rootroot00000000000000#include "test_request.h" #include using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage " << argv[0] << " [url]" << std::endl; return 0; } DavixError* tmp_err=NULL; Context c; HttpRequest r(c, argv[1], &tmp_err); if(!tmp_err) r.executeRequest(&tmp_err); if(tmp_err){ std::cerr << " error in request : " << tmp_err->getErrMsg() << std::endl; }else{ std::vector body = r.getAnswerContentVec(); std::string v(body.begin(), body.end()); std::cout << "content "<< v << std::endl; } return 0; } davix-R_0_5_0/test/functional/test_request.h000066400000000000000000000001121257152637300213000ustar00rootroot00000000000000#ifndef TEST_REQUEST_H #define TEST_REQUEST_H #endif // TEST_REQUEST_H davix-R_0_5_0/test/functional/test_stat.cpp000066400000000000000000000023111257152637300211210ustar00rootroot00000000000000#include "test_stat.h" #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; RequestParams p; // p.setProtocol(RequestProtocol::Http); std::auto_ptr c( new Context()); DavPosix pos(c.get()); if(argc > 2){ configure_grid_env(argv[2], p); } struct stat st; if( pos.stat(&p, argv[1], &st, &tmp_err) < 0){ std::cerr << " error on stat req " << tmp_err->getErrMsg() << std::endl; return -1; } std::cout << "stat success" << std::endl; std::cout << " atime : " << st.st_atime << std::endl; std::cout << " mtime : " << st.st_mtime << std::endl; std::cout << " ctime : " << st.st_ctime << std::endl; std::cout << " mode : 0" << std::oct << st.st_mode << std::endl; std::cout << " len : " << st.st_size << std::endl; return 0; } davix-R_0_5_0/test/functional/test_stat.h000066400000000000000000000001011257152637300205610ustar00rootroot00000000000000#ifndef TEST_STAT_H #define TEST_STAT_H #endif // TEST_STAT_H davix-R_0_5_0/test/functional/test_stat_session.cpp000066400000000000000000000025051257152637300226710ustar00rootroot00000000000000#include "test_stat_session.h" #include #include #include #include "davix_test_lib.h" using namespace Davix; int n_call=0; int main(int argc, char** argv){ if( argc < 3){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [CERTIFICATE_PATH] [url] [url] .... " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); if(argc > 2){ configure_grid_env(argv[1], p); } for(int i =2 ; i< argc; ++i){ struct stat st; if( pos.stat(&p,argv[i], &st, &tmp_err) ==0){ std::cout << "stat success" << std::endl; std::cout << " atime : " << st.st_atime << std::endl; std::cout << " mtime : " << st.st_mtime << std::endl; std::cout << " ctime : " << st.st_ctime << std::endl; std::cout << " mode : 0" << std::oct << st.st_mode << std::endl; std::cout << " len : " << st.st_size << std::endl; }else{ std::cerr << " davix_stat error " << tmp_err->getErrMsg(); return -1; } } std::cout << "authentification callback has been called " << n_call << std::endl; return 0; } davix-R_0_5_0/test/functional/test_stat_session.h000066400000000000000000000001011257152637300223240ustar00rootroot00000000000000#ifndef TEST_STAT_H #define TEST_STAT_H #endif // TEST_STAT_H davix-R_0_5_0/test/functional/test_valid_read_generic_simple.cpp000066400000000000000000000033761257152637300253210ustar00rootroot00000000000000#include "test_stat.h" #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; Davix_fd* fd; ssize_t ret=1; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); size_t char_counter=0, chunk_counter=0; char buff[2049]={0}; if(argc > 2){ configure_grid_env(argv[2], p); } if( (fd =pos.open(&p, argv[1], O_RDONLY, &tmp_err)) == NULL){ std::cerr << " error while opening file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } // std::cout << "file content " << std::endl; while( fd && (ret = pos.read(fd, buff, 2048, &tmp_err)) > 0){ buff[ret] = '\0'; char_counter += strlen(buff); chunk_counter += ret; if(char_counter != chunk_counter){ std::cerr << " char size and read size are differents.. " << std::endl; return -1; } std::cout << buff; } std::cout << std::endl; if(tmp_err){ std::cerr << " error while readding file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } if( (ret = pos.close(fd, &tmp_err))){ std::cerr << " error while closing file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } return 0; } davix-R_0_5_0/test/functional/test_valid_write_read_davfile.cpp000066400000000000000000000047641257152637300251620ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } srand(time(NULL)); setLogScope(DAVIX_LOG_SCOPE_ALL); setLogLevel(DAVIX_LOG_ALL); RequestParams p; Context context; std::string url = argv[1]; Uri u = generate_random_uri(Davix::Uri(url), "test_davfile_read"); if(argc > 2){ configure_grid_env(argv[2], p); } std::string origin = "Obiwan Kenobi, Yoda Master, Skywalker, Wookie, Light saber"; std::string str = origin; std::istringstream istr(str); // Try with streams try{ std::cout << " set File " << std::endl; File f(context, p, u); istr >> std::noskipws; istr >> f; StatInfo info; File other(context, u); other.statInfo(&p, info); std::cout << "infos" << info.size << " " << origin.size() << std::endl; assert(info.size == origin.size()); std::ostringstream ss; ss << other; std::string result(ss.str()); assert( result.compare(origin) ==0); other.deletion(&p); }catch(std::exception & e){ std::cerr << "Execution error" << e.what() << std::endl; return -1; } /* try{ File f(context, p, u); StatInfo info; f.statInfo(&p, info); std::cout << " arrive to execute stat after deletion: error " << u << " " << info.size << std::endl; assert(false); }catch(DavixException & e){ assert(e.code() == StatusCode::FileNotFound); }*/ /// normal content, non text + put / get schema /// Uri u2 = generate_random_uri(Davix::Uri(url), "test_davfile_read_binary"); dav_size_t size_data = rand()%(1 <<20) +2; char data_buffer[size_data]; for(dav_size_t i =0; i < size_data; ++i){ data_buffer[i] = static_cast(rand()); } File fbin(context, p, u2); fbin.put(NULL, data_buffer, size_data); std::vector rece_buffer; File fbin_rece(context, p, u2); fbin_rece.get(NULL, rece_buffer); assert(memcmp(data_buffer, &(rece_buffer.at(0)), size_data) == 0); fbin_rece.deletion(); return 0; } davix-R_0_5_0/test/functional/test_valid_write_read_fd.cpp000066400000000000000000000044401257152637300241300ustar00rootroot00000000000000 #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; RequestParams p; dav_ssize_t ret; int fd, fd_out, fd_out2; Context c; const ssize_t size_content = rand()/1000000+2; std::cout << " size content" << size_content << std::endl; char url[2048]; generate_random_uri(argv[1], "test_davix_",url, 2048); char buffer_mktemp[2048]; if(argc > 2){ configure_grid_env(argv[2], p); } File f(c, std::string(url)); fd = open("/dev/urandom", O_RDONLY); DAV_ASSERT_TRUE( fd > 0, "Impossible to open random generator"); TRY_DAVIX{ f.put(&p, fd, size_content); }CATCH_DAVIX(&tmp_err); DAV_ASSERT_TRUE( tmp_err == NULL, tmp_err->getErrMsg()); strcpy(buffer_mktemp, "dav-fd-test-XXXXXXXXX"); fd_out = mkstemp(buffer_mktemp); DAV_ASSERT_TRUE( fd_out > 0, "Impossible to output file"); ret = f.getToFd(&p, fd_out, &tmp_err); DAV_ASSERT_TRUE( tmp_err == NULL, tmp_err->getErrMsg()); DAV_ASSERT_TRUE( ret == size_content, "Invalid size" << ret); dav_ssize_t half_size = size_content/2; strcpy(buffer_mktemp, "dav-fd-test-partial-XXXXXXXXX"); fd_out2 = mkstemp(buffer_mktemp); DAV_ASSERT_TRUE( fd_out2 > 0, "Impossible to output file"); ret = f.getToFd(&p, fd_out2, half_size, &tmp_err); DAV_ASSERT_TRUE( tmp_err == NULL, tmp_err->getErrMsg()); DAV_ASSERT_TRUE( ret == half_size, "Invalid size" << ret); lseek(fd_out, 0, 0); lseek(fd_out2, 0, 0); char buffer1[half_size], buffer2[half_size]; DAV_ASSERT_TRUE( read(fd_out, buffer1, half_size) == half_size, "Invalid read back from local file 1"); DAV_ASSERT_TRUE( read(fd_out2, buffer2, half_size) == half_size, "Invalid read back from local file 2"); DAV_ASSERT_TRUE( memcmp(buffer1, buffer2, half_size) ==0, "Corrupted content"); close(fd); return 0; } davix-R_0_5_0/test/functional/test_valid_write_read_generic_simple.cpp000066400000000000000000000072601257152637300265270ustar00rootroot00000000000000#include "test_stat.h" #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; Davix_fd* fd; ssize_t ret=1; RequestParams p; std::auto_ptr c( new Context()); // c->setSessionCaching(false); DavPosix pos(c.get()); const size_t size_content = rand()/1000000+2; char url[2048]; generate_random_uri(argv[1], "test_davix_",url, 2048); char buff_output[size_content+1]; char* buff_input = generate_random_string_content(size_content); if(argc > 2){ configure_grid_env(argv[2], p); } if( (fd =pos.open(&p, url, O_RDONLY, &tmp_err)) != NULL){ std::cerr << "Error ! open should fail, not an existing file and read only mode " << std::endl; return -1; } DavixError::clearError(&tmp_err); if( (fd =pos.open(&p, url, O_RDWR, &tmp_err)) != NULL){ std::cerr << "Error ! open should fail, not an existing file and not O_CREAT " << std::endl; return -1; } DavixError::clearError(&tmp_err); if( (fd =pos.open(&p, url, O_RDWR | O_CREAT, &tmp_err)) == NULL){ std::cerr << " open error "<< tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } // write content if( (ret = pos.write(fd, buff_input, size_content, &tmp_err)) < 0){ std::cerr << " write error "<< tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } if( pos.lseek(fd, 0,0, &tmp_err) != 0){ std::cerr << " error while lseek file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } // read content back ! off_t offset_buffer = 0; while( (ret = pos.read(fd, buff_output+ offset_buffer, 50, &tmp_err) ) > 0 && (size_t) offset_buffer < size_content){ offset_buffer += ret; } if(tmp_err){ std::cerr << " error while readding file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } buff_output[size_content] ='\0'; if(strncmp(buff_input, buff_output, size_content) !=0){ std::cerr << "content are different : FATAL ! " << std::endl; return -1; } // try partial read memset(buff_output, 0, sizeof(size_content)); off_t offset_read = size_content/2; size_t size_read = std::min(size_content - offset_read, 600); if( ( ret = pos.pread(fd, buff_output, size_read, offset_read, &tmp_err)) <0){ std::cerr << " error while pread " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } buff_output[size_read] ='\0'; if(strncmp(buff_input+offset_read, buff_output, size_read) !=0){ std::cerr << "content are different : FATAL ! " << std::endl; return -1; } if( (ret = pos.close(fd, &tmp_err))){ std::cerr << " error while closing file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } if( (fd =pos.open(&p, url, O_RDWR | O_CREAT | O_EXCL, &tmp_err)) != NULL){ std::cerr << " should fail , O_EXCL flag and file exist" << std::endl; return -1; } free(buff_input); return 0; } davix-R_0_5_0/test/functional/test_valid_write_read_vector_simple.cpp000066400000000000000000000064311257152637300264140ustar00rootroot00000000000000#include "test_stat.h" #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; std::pair get_random_range_read(size_t total_size){ return std::pair ( (rand()%total_size-1), (rand()%total_size)/10+1); } int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); DavixError* tmp_err=NULL; Davix_fd* fd; ssize_t ret=1; RequestParams p; std::auto_ptr c( new Context()); DavPosix pos(c.get()); const size_t size_content = rand()/10000000+2000; char url[2048]; generate_random_uri(argv[1], "test_davix_",url, 2048); char* buff_input = generate_random_string_content(size_content); if(argc > 2){ configure_grid_env(argv[2], p); } std::cout << " open remote file " << std::endl; if( (fd =pos.open(&p, url, O_RDWR | O_CREAT, &tmp_err)) == NULL){ std::cerr << " open error "<< tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } std::cout << " write content dir " << std::endl; // write content if( (ret = pos.write(fd, buff_input, size_content, &tmp_err)) < 0){ std::cerr << " write error "<< tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } pos.close(fd, &tmp_err); if(tmp_err){ std::cerr << " error while writing file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } if( (fd =pos.open(&p, url, O_RDWR | O_CREAT, &tmp_err)) == NULL){ std::cerr << " open error "<< tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } std::cout << " try stupid empty vector read" << std::endl; Davix::DavIOVecInput input; Davix::DavIOVecOuput output; dav_ssize_t res = pos.preadVec(fd, &input, &output, 0, &tmp_err); assert(res == 0 && tmp_err == NULL); const std::pair range_read = get_random_range_read(size_content); char buffer_read[range_read.second+1]; buffer_read[range_read.second]= '\0'; input.diov_buffer = buffer_read; input.diov_offset = range_read.first; input.diov_size = range_read.second; std::cout << " try to read one segment of "<< input.diov_size << " from " << input.diov_offset<< " offset of a content of " << size_content << std::endl; res = pos.preadVec(fd, &input, &output, 1, &tmp_err); assert( res == output.diov_size); assert( output.diov_size > 0); assert( tmp_err == NULL); assert( strncmp(buff_input +input.diov_offset, buffer_read, input.diov_size) ==0); if( (ret = pos.close(fd, &tmp_err))){ std::cerr << " error while closing file " << tmp_err->getErrMsg() << " code :" << (int) tmp_err->getStatus() << std::endl; return -1; } // delete trash file pos.unlink(&p, url, NULL); free(buff_input); return 0; } davix-R_0_5_0/test/functional/tool_get_replica_simple.cpp000066400000000000000000000021351257152637300237770ustar00rootroot00000000000000 #include #include "davix_test_lib.h" using namespace Davix; #define MY_BUFFER_SIZE 65000 int main(int argc, char** argv){ if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url]" << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH] " << std::endl; return 0; } davix_set_log_level(0xff); RequestParams params; DavixError* tmp_err=NULL; Uri url(argv[1]); char * cert_path = argv[2]; if(argc > 2){ configure_grid_env(cert_path, params); } Context c; std::vector reps; File f(c, url); // delete unexisting dir, should fail reps = f.getReplicas(¶ms, &tmp_err); if(tmp_err != NULL){ std::cerr << "Error: " << tmp_err->getErrMsg() << std::endl; return -1; } if(reps.size() == 0){ std::cout << "No Replicas" << std::endl; return -1; } for(std::vector::iterator it = reps.begin(); it != reps.end(); ++it){ std::cout << "Replica " << it->getUri() << std::endl; } return 0; } davix-R_0_5_0/test/functional/tool_read_vector_simple.cpp000066400000000000000000000037401257152637300240210ustar00rootroot00000000000000#include "test_stat.h" #include #include #include #include #include #include #include "davix_test_lib.h" using namespace Davix; std::pair get_random_range_read(size_t total_size){ return std::pair ( (rand()%total_size-1), (rand()%total_size)/10+1); } int main(int argc, char** argv){ DavixError* tmp_err=NULL; Davix_fd* fd; ssize_t ret=1; RequestParams p; Context c; DavPosix pos(&c); if( argc < 2){ std::cout << "Usage : " << std::endl; std::cout <<"\t" << argv[0] << " [url] " << std::endl; std::cout <<"\t" << argv[0] << " [url] [CERTIFICATE_PATH]..." << std::endl; return 0; } if(argc > 2){ configure_grid_env(argv[2], p); } srand(time(NULL)); davix_set_log_level(DAVIX_LOG_ALL); size_t vec = 10; size_t s_buff = 4096; DavIOVecInput in[vec]; DavIOVecOuput out[vec]; char buffer[vec][s_buff]; dav_size_t s[] = { 10000, 5, 20, 12 ,15 ,60, 90, 1, 88, 10}; dav_off_t off[] = { 10, 20, 2, 10 ,800 ,600, 523, 1, 0, 100}; for(size_t i = 0; i < vec; ++i){ in[i].diov_buffer= buffer[i]; in[i].diov_offset = off[i]; in[i].diov_size = s[i]; } if( (fd = pos.open(&p, argv[1], O_RDONLY, &tmp_err)) == NULL){ std::cerr << " open error : err code " << tmp_err->getStatus() << " err msg " << tmp_err->getErrMsg(); return -1; } if( ( ret = pos.preadVec(fd, in, out, vec, &tmp_err)) <0){ std::cerr << " vec read error : err code " << tmp_err->getStatus() << " err msg " << tmp_err->getErrMsg(); return -1; } for(size_t i = 0; i < vec; ++i){ std::cout << "part vector read of size " << out[i].diov_size << " with offset " << in[i].diov_offset << " :" << std::endl; std::cout << std::string((const char*) out[i].diov_buffer, out[i].diov_size) << std::endl; } return 0; } davix-R_0_5_0/test/pywebdav/000077500000000000000000000000001257152637300160655ustar00rootroot00000000000000davix-R_0_5_0/test/pywebdav/__init__.py000066400000000000000000000000001257152637300201640ustar00rootroot00000000000000davix-R_0_5_0/test/pywebdav/lib/000077500000000000000000000000001257152637300166335ustar00rootroot00000000000000davix-R_0_5_0/test/pywebdav/lib/AuthServer.py000066400000000000000000000064251257152637300213040ustar00rootroot00000000000000"""Authenticating HTTP Server This module builds on BaseHTTPServer and implements basic authentication """ import base64 import binascii import BaseHTTPServer DEFAULT_AUTH_ERROR_MESSAGE = """ %(code)s - %(message)s

Authorization Required

this server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required. """ def _quote_html(html): return html.replace("&", "&").replace("<", "<").replace(">", ">") class AuthRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): """ Simple handler that can check for auth headers In your subclass you have to define the method get_userinfo(user, password) which should return 1 or None depending on whether the password was ok or not. None means that the user is not authorized. """ # False means no authentiation DO_AUTH = 1 def parse_request(self): if not BaseHTTPServer.BaseHTTPRequestHandler.parse_request(self): return False if self.DO_AUTH: authorization = self.headers.get('Authorization', '') if not authorization: self.send_autherror(401, "Authorization Required") return False scheme, credentials = authorization.split() if scheme != 'Basic': self.send_error(501) return False credentials = base64.decodestring(credentials) user, password = credentials.split(':', 2) if not self.get_userinfo(user, password, self.command): self.send_autherror(401, "Authorization Required") return False return True def send_autherror(self, code, message=None): """Send and log an auth error reply. Arguments are the error code, and a detailed message. The detailed message defaults to the short entry matching the response code. This sends an error response (so it must be called before any output has been generated), logs the error, and finally sends a piece of HTML explaining the error to the user. """ try: short, long = self.responses[code] except KeyError: short, long = '???', '???' if message is None: message = short explain = long self.log_error("code %d, message %s", code, message) # using _quote_html to prevent Cross Site Scripting attacks (see bug # #1100201) content = (self.error_auth_message_format % {'code': code, 'message': _quote_html(message), 'explain': explain}) self.send_response(code, message) self.send_header('Content-Type', self.error_content_type) self.send_header('WWW-Authenticate', 'Basic realm="PyWebDAV"') self.send_header('Connection', 'close') self.end_headers() self.wfile.write(content) error_auth_message_format = DEFAULT_AUTH_ERROR_MESSAGE def get_userinfo(self, user, password, command): """Checks if the given user and the given password are allowed to access. """ # Always reject return None davix-R_0_5_0/test/pywebdav/lib/INI_Parse.py000066400000000000000000000030331257152637300207550ustar00rootroot00000000000000from ConfigParser import SafeConfigParser class Configuration: def __init__(self, fileName): cp = SafeConfigParser() cp.read(fileName) self.__parser = cp self.fileName = fileName def __getattr__(self, name): if name in self.__parser.sections(): return Section(name, self.__parser) else: return None def __str__(self): p = self.__parser result = [] result.append('' % self.fileName) for s in p.sections(): result.append('[%s]' % s) for o in p.options(s): result.append('%s=%s' % (o, p.get(s, o))) return '\n'.join(result) class Section: def __init__(self, name, parser): self.name = name self.__parser = parser def __getattr__(self, name): return self.__parser.get(self.name, name) def __str__(self): return str(self.__repr__()) def __repr__(self): return self.__parser.items(self.name) def getboolean(self, name): return self.__parser.getboolean(self.name, name) def __contains__(self, name): return self.__parser.has_option(self.name, name) def get(self, name, default): if name in self: return self.__getattr__(name) else: return default def set(self, name, value): self.__parser.set(self.name, name, str(value)) # Test if __name__ == '__main__': c = Configuration('Importador.ini') print c.Origem.host, c.Origem.port davix-R_0_5_0/test/pywebdav/lib/WebDAVServer.py000066400000000000000000000565231257152637300214570ustar00rootroot00000000000000"""DAV HTTP Server This module builds on BaseHTTPServer and implements DAV commands """ import AuthServer import urlparse import urllib import logging from propfind import PROPFIND from report import REPORT from delete import DELETE from davcopy import COPY from davmove import MOVE from utils import rfc1123_date, IfParser, tokenFinder from string import atoi from errors import DAV_Error, DAV_NotFound from constants import DAV_VERSION_1, DAV_VERSION_2 from locks import LockManager import gzip import StringIO from pywebdav.lib import VERSION from xml.parsers.expat import ExpatError log = logging.getLogger(__name__) BUFFER_SIZE = 128 * 1000 # 128 Ko class DAVRequestHandler(AuthServer.AuthRequestHandler, LockManager): """Simple DAV request handler with - GET - HEAD - PUT - OPTIONS - PROPFIND - PROPPATCH - MKCOL - REPORT experimental - LOCK - UNLOCK It uses the resource/collection classes for serving and storing content. """ server_version = "DAV/" + VERSION encode_threshold = 1400 # common MTU def send_body(self, DATA, code=None, msg=None, desc=None, ctype='application/octet-stream', headers={}): """ send a body in one part """ log.debug("Use send_body method") self.send_response(code, message=msg) self.send_header("Connection", "close") self.send_header("Accept-Ranges", "bytes") self.send_header('Date', rfc1123_date()) self._send_dav_version() for a, v in headers.items(): self.send_header(a, v) if DATA: if 'gzip' in self.headers.get('Accept-Encoding', '').split(',') \ and len(DATA) > self.encode_threshold: buffer = StringIO.StringIO() output = gzip.GzipFile(mode='wb', fileobj=buffer) if isinstance(DATA, str) or isinstance(DATA, unicode): output.write(DATA) else: for buf in DATA: output.write(buf) output.close() buffer.seek(0) DATA = buffer.getvalue() self.send_header('Content-Encoding', 'gzip') self.send_header('Content-Length', len(DATA)) self.send_header('Content-Type', ctype) else: self.send_header('Content-Length', 0) self.end_headers() if DATA: if isinstance(DATA, str) or isinstance(DATA, unicode): log.debug("Don't use iterator") self.wfile.write(DATA) else: if self._config.DAV.getboolean('http_response_use_iterator'): # Use iterator to reduce using memory log.debug("Use iterator") for buf in DATA: self.wfile.write(buf) self.wfile.flush() else: # Don't use iterator, it's a compatibility option log.debug("Don't use iterator") self.wfile.write(DATA.read()) def send_body_chunks_if_http11(self, DATA, code, msg=None, desc=None, ctype='text/xml; encoding="utf-8"', headers={}): if (self.request_version == 'HTTP/1.0' or not self._config.DAV.getboolean('chunked_http_response')): self.send_body(DATA, code, msg, desc, ctype, headers) else: self.send_body_chunks(DATA, code, msg, desc, ctype, headers) def send_body_chunks(self, DATA, code, msg=None, desc=None, ctype='text/xml"', headers={}): """ send a body in chunks """ self.responses[207] = (msg, desc) self.send_response(code, message=msg) self.send_header("Content-type", ctype) self.send_header("Transfer-Encoding", "chunked") self.send_header('Date', rfc1123_date()) self._send_dav_version() for a, v in headers.items(): self.send_header(a, v) if DATA: if ('gzip' in self.headers.get('Accept-Encoding', '').split(',') and len(DATA) > self.encode_threshold): buffer = StringIO.StringIO() output = gzip.GzipFile(mode='wb', fileobj=buffer) if isinstance(DATA, str): output.write(DATA) else: for buf in DATA: output.write(buf) output.close() buffer.seek(0) DATA = buffer.getvalue() self.send_header('Content-Encoding', 'gzip') self.send_header('Content-Length', len(DATA)) self.send_header('Content-Type', ctype) else: self.send_header('Content-Length', 0) self.end_headers() if DATA: if isinstance(DATA, str) or isinstance(DATA, unicode): self.wfile.write(hex(len(DATA))[2:] + "\r\n") self.wfile.write(DATA) self.wfile.write("\r\n") self.wfile.write("0\r\n") self.wfile.write("\r\n") else: if self._config.DAV.getboolean('http_response_use_iterator'): # Use iterator to reduce using memory for buf in DATA: self.wfile.write(hex(len(buf))[2:] + "\r\n") self.wfile.write(buf) self.wfile.write("\r\n") self.wfile.write("0\r\n") self.wfile.write("\r\n") else: # Don't use iterator, it's a compatibility option self.wfile.write(hex(len(DATA))[2:] + "\r\n") self.wfile.write(DATA.read()) self.wfile.write("\r\n") self.wfile.write("0\r\n") self.wfile.write("\r\n") def _send_dav_version(self): if self._config.DAV.getboolean('lockemulation'): self.send_header('DAV', DAV_VERSION_2['version']) else: self.send_header('DAV', DAV_VERSION_1['version']) ### HTTP METHODS called by the server def do_OPTIONS(self): """return the list of capabilities """ self.send_response(200) self.send_header("Content-Length", 0) if self._config.DAV.getboolean('lockemulation'): self.send_header('Allow', DAV_VERSION_2['options']) else: self.send_header('Allow', DAV_VERSION_1['options']) self._send_dav_version() self.send_header('MS-Author-Via', 'DAV') # this is for M$ self.end_headers() def _HEAD_GET(self, with_body=False): """ Returns headers and body for given resource """ dc = self.IFACE_CLASS uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) headers = {} # get the last modified date (RFC 1123!) try: headers['Last-Modified'] = dc.get_prop( uri, "DAV:", "getlastmodified") except DAV_NotFound: pass # get the ETag if any try: headers['Etag'] = dc.get_prop(uri, "DAV:", "getetag") except DAV_NotFound: pass # get the content type try: content_type = dc.get_prop(uri, "DAV:", "getcontenttype") except DAV_NotFound: content_type = "application/octet-stream" range = None status_code = 200 if 'Range' in self.headers: p = self.headers['Range'].find("bytes=") if p != -1: range = self.headers['Range'][p + 6:].split("-") status_code = 206 # get the data try: data = dc.get_data(uri, range) except DAV_Error, (ec, dd): self.send_status(ec) return ec # send the data if with_body is False: data = None if isinstance(data, str) or isinstance(data, unicode): self.send_body(data, status_code, None, None, content_type, headers) else: headers['Keep-Alive'] = 'timeout=15, max=86' headers['Connection'] = 'Keep-Alive' self.send_body_chunks_if_http11(data, status_code, None, None, content_type, headers) return status_code def do_HEAD(self): """ Send a HEAD response: Retrieves resource information w/o body """ return self._HEAD_GET(with_body=False) def do_GET(self): """Serve a GET request.""" log.debug(self.headers) try: status_code = self._HEAD_GET(with_body=True) self.log_request(status_code) return status_code except IOError, e: if e.errno == 32: self.log_request(206) else: raise def do_TRACE(self): """ This will always fail because we can not reproduce HTTP requests. We send back a 405=Method Not Allowed. """ self.send_body(None, 405, 'Method Not Allowed', 'Method Not Allowed') def do_POST(self): """ Replacement for GET response. Not implemented here. """ self.send_body(None, 405, 'Method Not Allowed', 'Method Not Allowed') def do_PROPPATCH(self): # currently unsupported return self.send_status(423) def do_PROPFIND(self): """ Retrieve properties on defined resource. """ dc = self.IFACE_CLASS # read the body containing the xml request # iff there is no body then this is an ALLPROP request body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(atoi(l)) uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) try: pf = PROPFIND(uri, dc, self.headers.get('Depth', 'infinity'), body) except ExpatError: # parse error return self.send_status(400) try: DATA = '%s\n' % pf.createResponse() except DAV_Error, (ec, dd): return self.send_status(ec) # work around MSIE DAV bug for creation and modified date # taken from Resource.py @ Zope webdav if (self.headers.get('User-Agent') == 'Microsoft Data Access Internet Publishing Provider DAV 1.1'): DATA = DATA.replace('', '') DATA = DATA.replace('', '') self.send_body_chunks_if_http11(DATA, 207, 'Multi-Status', 'Multiple responses') def do_REPORT(self): """ Query properties on defined resource. """ dc = self.IFACE_CLASS # read the body containing the xml request # iff there is no body then this is an ALLPROP request body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(atoi(l)) uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) rp = REPORT(uri, dc, self.headers.get('Depth', '0'), body) try: DATA = '%s\n' % rp.createResponse() except DAV_Error, (ec, dd): return self.send_status(ec) self.send_body_chunks_if_http11(DATA, 207, 'Multi-Status', 'Multiple responses') def do_MKCOL(self): """ create a new collection """ # according to spec body must be empty body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] body = self.rfile.read(atoi(l)) if body: return self.send_status(415) dc = self.IFACE_CLASS uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) try: dc.mkcol(uri) self.send_status(201) self.log_request(201) except DAV_Error, (ec, dd): self.log_request(ec) return self.send_status(ec) def do_DELETE(self): """ delete an resource """ dc = self.IFACE_CLASS uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) # hastags not allowed if uri.find('#') >= 0: return self.send_status(404) # locked resources are not allowed to delete if self._l_isLocked(uri): return self.send_body(None, 423, 'Locked', 'Locked') # Handle If-Match if 'If-Match' in self.headers: test = False etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass for match in self.headers['If-Match'].split(','): if match == '*': if dc.exists(uri): test = True break else: if match == etag: test = True break if not test: self.send_status(412) self.log_request(412) return # Handle If-None-Match if 'If-None-Match' in self.headers: test = True etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass for match in self.headers['If-None-Match'].split(','): if match == '*': if dc.exists(uri): test = False break else: if match == etag: test = False break if not test: self.send_status(412) self.log_request(412) return try: dl = DELETE(uri, dc) if dc.is_collection(uri): res = dl.delcol() if res: self.send_status(207, body=res) else: self.send_status(204) else: res = dl.delone() or 204 self.send_status(res) except DAV_NotFound: self.send_body(None, 404, 'Not Found', 'Not Found') def do_PUT(self): dc = self.IFACE_CLASS uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) log.debug("do_PUT: uri = %s" % uri) log.debug('do_PUT: headers = %s' % self.headers) # Handle If-Match if 'If-Match' in self.headers: log.debug("do_PUT: If-Match %s" % self.headers['If-Match']) test = False etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass log.debug("do_PUT: etag = %s" % etag) for match in self.headers['If-Match'].split(','): if match == '*': if dc.exists(uri): test = True break else: if match == etag: test = True break if not test: self.send_status(412) self.log_request(412) return # Handle If-None-Match if 'If-None-Match' in self.headers: log.debug("do_PUT: If-None-Match %s" % self.headers['If-None-Match']) test = True etag = None try: etag = dc.get_prop(uri, "DAV:", "getetag") except: pass log.debug("do_PUT: etag = %s" % etag) for match in self.headers['If-None-Match'].split(','): if match == '*': if dc.exists(uri): test = False break else: if match == etag: test = False break if not test: self.send_status(412) self.log_request(412) return # locked resources are not allowed to be overwritten ifheader = self.headers.get('If') if ( (self._l_isLocked(uri)) and (not ifheader) ): return self.send_body(None, 423, 'Locked', 'Locked') if ((self._l_isLocked(uri)) and (ifheader)): uri_token = self._l_getLockForUri(uri) taglist = IfParser(ifheader) found = False for tag in taglist: for listitem in tag.list: token = tokenFinder(listitem) if ( token and (self._l_hasLock(token)) and (self._l_getLock(token) == uri_token) ): found = True break if found: break if not found: res = self.send_body(None, 423, 'Locked', 'Locked') self.log_request(423) return res # Handle expect expect = self.headers.get('Expect', '') if (expect.lower() == '100-continue' and self.protocol_version >= 'HTTP/1.1' and self.request_version >= 'HTTP/1.1'): self.send_status(100) content_type = None if 'Content-Type' in self.headers: content_type = self.headers['Content-Type'] headers = {} headers['Location'] = uri try: etag = dc.get_prop(uri, "DAV:", "getetag") headers['ETag'] = etag except: pass expect = self.headers.get('transfer-encoding', '') if ( expect.lower() == 'chunked' and self.protocol_version >= 'HTTP/1.1' and self.request_version >= 'HTTP/1.1' ): self.send_body(None, 201, 'Created', '', headers=headers) dc.put(uri, self._readChunkedData(), content_type) else: # read the body body = None if 'Content-Length' in self.headers: l = self.headers['Content-Length'] log.debug("do_PUT: Content-Length = %s" % l) body = self._readNoChunkedData(atoi(l)) else: log.debug("do_PUT: Content-Length = empty") try: dc.put(uri, body, content_type) except DAV_Error, (ec, dd): return self.send_status(ec) self.send_body(None, 201, 'Created', '', headers=headers) self.log_request(201) def _readChunkedData(self): l = int(self.rfile.readline(), 16) while l > 0: buf = self.rfile.read(l) yield buf self.rfile.readline() l = int(self.rfile.readline(), 16) def _readNoChunkedData(self, content_length): if self._config.DAV.getboolean('http_request_use_iterator'): # Use iterator to reduce using memory return self.__readNoChunkedDataWithIterator(content_length) else: # Don't use iterator, it's a compatibility option return self.__readNoChunkedDataWithoutIterator(content_length) def __readNoChunkedDataWithIterator(self, content_length): while True: if content_length > BUFFER_SIZE: buf = self.rfile.read(BUFFER_SIZE) content_length -= BUFFER_SIZE yield buf else: buf = self.rfile.read(content_length) yield buf break def __readNoChunkedDataWithoutIterator(self, content_length): return self.rfile.read(content_length) def do_COPY(self): """ copy one resource to another """ try: self.copymove(COPY) except DAV_Error, (ec, dd): return self.send_status(ec) def do_MOVE(self): """ move one resource to another """ try: self.copymove(MOVE) except DAV_Error, (ec, dd): return self.send_status(ec) def copymove(self, CLASS): """ common method for copying or moving objects """ dc = self.IFACE_CLASS # get the source URI source_uri = urlparse.urljoin(self.get_baseuri(dc), self.path) source_uri = urllib.unquote(source_uri) # get the destination URI dest_uri = self.headers['Destination'] dest_uri = urllib.unquote(dest_uri) # check locks on source and dest if self._l_isLocked(source_uri) or self._l_isLocked(dest_uri): return self.send_body(None, 423, 'Locked', 'Locked') # Overwrite? overwrite = 1 result_code = 204 if 'Overwrite' in self.headers: if self.headers['Overwrite'] == "F": overwrite = None result_code = 201 # instanciate ACTION class cp = CLASS(dc, source_uri, dest_uri, overwrite) # Depth? d = "infinity" if 'Depth' in self.headers: d = self.headers['Depth'] if d != "0" and d != "infinity": self.send_status(400) return if d == "0": res = cp.single_action() self.send_status(res or 201) return # now it only can be "infinity" but we nevertheless check for a # collection if dc.is_collection(source_uri): try: res = cp.tree_action() except DAV_Error, (ec, dd): self.send_status(ec) return else: try: res = cp.single_action() except DAV_Error, (ec, dd): self.send_status(ec) return if res: self.send_body_chunks_if_http11(res, 207, self.responses[207][0], self.responses[207][1], ctype='text/xml; charset="utf-8"') else: self.send_status(result_code) def get_userinfo(self, user, pw): """ Dummy method which lets all users in """ return 1 def send_status(self, code=200, mediatype='text/xml; charset="utf-8"', msg=None, body=None): if not msg: msg = self.responses.get(code, ['', ''])[1] self.send_body(body, code, self.responses.get(code, [''])[0], msg, mediatype) def get_baseuri(self, dc): baseuri = dc.baseuri if 'Host' in self.headers: uparts = list(urlparse.urlparse(dc.baseuri)) uparts[1] = self.headers['Host'] baseuri = urlparse.urlunparse(uparts) return baseuri davix-R_0_5_0/test/pywebdav/lib/__init__.py000066400000000000000000000003001257152637300207350ustar00rootroot00000000000000 import pkg_resources # get version from package package = pkg_resources.require('PyWebDAV')[0] VERSION = package.version # author hardcoded here AUTHOR = 'Simon Pamies (spamsch@gmail.com)' davix-R_0_5_0/test/pywebdav/lib/constants.py000066400000000000000000000012101257152637300212130ustar00rootroot00000000000000# definition for resourcetype COLLECTION=1 OBJECT=None # attributes for resources DAV_PROPS=['creationdate', 'displayname', 'getcontentlanguage', 'getcontentlength', 'getcontenttype', 'getetag', 'getlastmodified', 'lockdiscovery', 'resourcetype', 'source', 'supportedlock'] # Request classes in propfind RT_ALLPROP=1 RT_PROPNAME=2 RT_PROP=3 # server mode DAV_VERSION_1 = { 'version' : '1', 'options' : 'GET, HEAD, COPY, MOVE, POST, PUT, PROPFIND, PROPPATCH, OPTIONS, MKCOL, DELETE, TRACE, REPORT' } DAV_VERSION_2 = { 'version' : '1,2', 'options' : DAV_VERSION_1['options'] + ', LOCK, UNLOCK' } davix-R_0_5_0/test/pywebdav/lib/davcmd.py000066400000000000000000000120721257152637300204450ustar00rootroot00000000000000""" davcmd.py --------- containts commands like copy, move, delete for normal resources and collections """ from string import split,replace,joinfields import urlparse from utils import create_treelist, is_prefix from errors import * def deltree(dc,uri,exclude={}): """ delete a tree of resources dc -- dataclass to use uri -- root uri to delete exclude -- an optional list of uri:error_code pairs which should not be deleted. returns dict of uri:error_code tuples from which another method can create a multistatus xml element. Also note that we only know Depth=infinity thus we don't have to test for it. """ tlist=create_treelist(dc,uri) result={} for i in range(len(tlist),0,-1): problem_uris=result.keys() element=tlist[i-1] # test here, if an element is a prefix of an uri which # generated an error before. # note that we walk here from childs to parents, thus # we cannot delete a parent if a child made a problem. # (see example in 8.6.2.1) ok=1 for p in problem_uris: if is_prefix(element,p): ok=None break if not ok: continue # here we test for the exclude list which is the other way round! for p in exclude.keys(): if is_prefix(p,element): ok=None break if not ok: continue # now delete stuff try: delone(dc,element) except DAV_Error, (ec,dd): result[element]=ec return result def delone(dc,uri): """ delete a single object """ if dc.is_collection(uri): return dc.rmcol(uri) # should be empty else: return dc.rm(uri) ### ### COPY ### # helper function def copy(dc,src,dst): """ only copy the element This is just a helper method factored out from copy and copytree. It will not handle the overwrite or depth header. """ # destination should have been deleted before if dc.exists(dst): raise DAV_Error, 412 # source should exist also if not dc.exists(src): raise DAV_NotFound if dc.is_collection(src): dc.copycol(src, dst) # an exception will be passed thru else: dc.copy(src, dst) # an exception will be passed thru # the main functions def copyone(dc,src,dst,overwrite=None): """ copy one resource to a new destination """ if overwrite and dc.exists(dst): delres = deltree(dc, dst) else: delres={} # if we cannot delete everything, then do not copy! if delres: return delres try: copy(dc, src, dst) # pass thru exceptions except DAV_Error, (ec, dd): return ec def copytree(dc,src,dst,overwrite=None): """ copy a tree of resources to another location dc -- dataclass to use src -- src uri from where to copy dst -- dst uri overwrite -- if 1 then delete dst uri before returns dict of uri:error_code tuples from which another method can create a multistatus xml element. """ # first delete the destination resource if overwrite and dc.exists(dst): delres=deltree(dc,dst) else: delres={} # if we cannot delete everything, then do not copy! if delres: return delres # get the tree we have to copy tlist = create_treelist(dc,src) result = {} # prepare destination URIs (get the prefix) dpath = urlparse.urlparse(dst)[2] for element in tlist: problem_uris = result.keys() # now URIs get longer and longer thus we have # to test if we had a parent URI which we were not # able to copy in problem_uris which is the prefix # of the actual element. If it is, then we cannot # copy this as well but do not generate another error. ok=1 for p in problem_uris: if is_prefix(p,element): ok=None break if not ok: continue # now create the destination URI which corresponds to # the actual source URI. -> actual_dst # ("subtract" the base src from the URI and prepend the # dst prefix to it.) esrc=replace(element,src,"") actual_dst=dpath+esrc # now copy stuff try: copy(dc,element,actual_dst) except DAV_Error, (ec,dd): result[element]=ec return result ### ### MOVE ### def moveone(dc,src,dst,overwrite=None): """ move a single resource This is done by first copying it and then deleting the original. """ # first copy it copyone(dc, src, dst, overwrite) # then delete it dc.rm(src) def movetree(dc,src,dst,overwrite=None): """ move a collection This is done by first copying it and then deleting the original. PROBLEM: if something did not copy then we have a problem when deleting as the original might get deleted! """ # first copy it res = copytree(dc,src,dst,overwrite) # then delete it res = deltree(dc,src,exclude=res) return res davix-R_0_5_0/test/pywebdav/lib/davcopy.py000066400000000000000000000061451257152637300206600ustar00rootroot00000000000000import xml.dom.minidom domimpl = xml.dom.minidom.getDOMImplementation() import sys import string import urlparse import urllib from StringIO import StringIO import utils from constants import COLLECTION, OBJECT, DAV_PROPS, RT_ALLPROP, RT_PROPNAME, RT_PROP from errors import * from utils import create_treelist, quote_uri, gen_estring class COPY: """ copy resources and eventually create multistatus responses This module implements the COPY class which is responsible for copying resources. Usually the normal copy work is done in the interface class. This class only creates error messages if error occur. """ def __init__(self,dataclass,src_uri,dst_uri,overwrite): self.__dataclass=dataclass self.__src=src_uri self.__dst=dst_uri self.__overwrite=overwrite def single_action(self): """ copy a normal resources. We try to copy it and return the result code. This is for Depth==0 """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urlparse.urlparse(self.__src)[2] pd=urlparse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error, 403 return dc.copyone(self.__src,self.__dst,self.__overwrite) #return copyone(dc,self.__src,self.__dst,self.__overwrite) def tree_action(self): """ copy a tree of resources (a collection) Here we return a multistatus xml element. """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urlparse.urlparse(self.__src)[2] pd=urlparse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error, 403 result=dc.copytree(self.__src,self.__dst,self.__overwrite) #result=copytree(dc,self.__src,self.__dst,self.__overwrite) if not result: return None ### ### create the multistatus XML element ### (this is also the same as in delete.py. ### we might make a common method out of it) ### doc = domimpl.createDocument(None, "D:multistatus", None) doc.documentElement.setAttribute("xmlns:D","DAV:") for el,ec in result.items(): re=doc.createElement("D:response") hr=doc.createElement("D:href") st=doc.createElement("D:status") huri=doc.createTextNode(quote_uri(el)) t=doc.createTextNode(gen_estring(ec)) st.appendChild(t) hr.appendChild(huri) re.appendChild(hr) re.appendChild(st) ms.appendChild(re) return doc.toxml(encoding="utf-8") davix-R_0_5_0/test/pywebdav/lib/davmove.py000066400000000000000000000043111257152637300206450ustar00rootroot00000000000000import sys import string import urlparse import urllib from StringIO import StringIO import utils from constants import COLLECTION, OBJECT, DAV_PROPS from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP from errors import * from utils import create_treelist, quote_uri, gen_estring, make_xmlresponse from davcmd import moveone, movetree class MOVE: """ move resources and eventually create multistatus responses This module implements the MOVE class which is responsible for moving resources. MOVE is implemented by a COPY followed by a DELETE of the old resource. """ def __init__(self,dataclass,src_uri,dst_uri,overwrite): self.__dataclass=dataclass self.__src=src_uri self.__dst=dst_uri self.__overwrite=overwrite def single_action(self): """ move a normal resources. We try to move it and return the result code. This is for Depth==0 """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urlparse.urlparse(self.__src)[2] pd=urlparse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error, 403 return dc.moveone(self.__src,self.__dst,self.__overwrite) def tree_action(self): """ move a tree of resources (a collection) Here we return a multistatus xml element. """ dc=self.__dataclass base=self.__src ### some basic tests # test if dest exists and overwrite is false if dc.exists(self.__dst) and not self.__overwrite: raise DAV_Error, 412 # test if src and dst are the same # (we assume that both uris are on the same server!) ps=urlparse.urlparse(self.__src)[2] pd=urlparse.urlparse(self.__dst)[2] if ps==pd: raise DAV_Error, 403 result=dc.movetree(self.__src,self.__dst,self.__overwrite) if not result: return None # create the multistatus XML element return make_xmlresponse(result) davix-R_0_5_0/test/pywebdav/lib/dbconn.py000066400000000000000000000041751257152637300204570ustar00rootroot00000000000000import logging log = logging.getLogger(__name__) try: import MySQLdb except ImportError: log.info('No SQL support - MySQLdb missing...') pass import sys class Mconn: def connect(self,username,userpasswd,host,port,db): try: connection = MySQLdb.connect(host=host, port=int(port), user=username, passwd=userpasswd,db=db) except MySQLdb.OperationalError, message: log.error("%d:\n%s" % (message[ 0 ], message[ 1 ] )) return 0 else: self.db = connection.cursor() return 1 def execute(self,qry): if self.db: try: res=self.db.execute(qry) except MySQLdb.OperationalError, message: log.error("Error %d:\n%s" % (message[ 0 ], message[ 1 ] )) return 0 except MySQLdb.ProgrammingError, message: log.error("Error %d:\n%s" % (message[ 0 ], message[ 1 ] )) return 0 else: log.debug('Query Returned '+str(res)+' results') return self.db.fetchall() def create_user(self,user,passwd): qry="select * from Users where User='%s'"%(user) res=self.execute(qry) if not res or len(res) ==0: qry="insert into Users (User,Pass) values('%s','%s')"%(user,passwd) res=self.execute(qry) else: log.debug("Username already in use") def create_table(self): qry="""CREATE TABLE `Users` ( `uid` int(10) NOT NULL auto_increment, `User` varchar(60) default NULL, `Pass` varchar(60) default NULL, `Write` tinyint(1) default '0', PRIMARY KEY (`uid`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1""" self.execute(qry) def first_run(self,user,passwd): res= self.execute('select * from Users') if res or type(res)==type(()) : pass else: self.create_table() self.create_user(user,passwd) def __init__(self,user,password,host,port,db): self.db=0 self.connect(user,password,host,port,db) davix-R_0_5_0/test/pywebdav/lib/delete.py000066400000000000000000000012371257152637300204520ustar00rootroot00000000000000import os import string import urllib from StringIO import StringIO from utils import gen_estring, quote_uri, make_xmlresponse from davcmd import deltree class DELETE: def __init__(self,uri,dataclass): self.__dataclass=dataclass self.__uri=uri def delcol(self): """ delete a collection """ dc=self.__dataclass result=dc.deltree(self.__uri) if not len(result.items()): return None # everything ok # create the result element return make_xmlresponse(result) def delone(self): """ delete a resource """ dc=self.__dataclass return dc.delone(self.__uri) davix-R_0_5_0/test/pywebdav/lib/errors.py000066400000000000000000000027211257152637300205230ustar00rootroot00000000000000""" Exceptions for the DAVserver implementation """ class DAV_Error(Exception): """ in general we can have the following arguments: 1. the error code 2. the error result element, e.g. a element """ def __init__(self,*args): if len(args)==1: self.args=(args[0],"") else: self.args=args class DAV_Secret(DAV_Error): """ the user is not allowed to know anything about it returning this for a property value means to exclude it from the response xml element. """ def __init__(self): DAV_Error.__init__(self,0) pass class DAV_NotFound(DAV_Error): """ a requested property was not found for a resource """ def __init__(self,*args): if len(args): DAV_Error.__init__(self,404,args[0]) else: DAV_Error.__init__(self,404) pass class DAV_Forbidden(DAV_Error): """ a method on a resource is not allowed """ def __init__(self,*args): if len(args): DAV_Error.__init__(self,403,args[0]) else: DAV_Error.__init__(self,403) pass class DAV_Requested_Range_Not_Satisfiable(DAV_Error): """ none of the range-specifier values overlap the current extent of the selected resource """ def __init__(self, *args): if len(args): DAV_Error.__init__(self, 416, args[0]) else: DAV_Error.__init__(self, 416) pass davix-R_0_5_0/test/pywebdav/lib/iface.py000066400000000000000000000205701257152637300202600ustar00rootroot00000000000000""" basic interface class use this for subclassing when writing your own interface class. """ from xml.dom import minidom from locks import LockManager from errors import * import time from string import lower class dav_interface: """ interface class for implementing DAV servers """ ### defined properties (modify this but let the DAV stuff there!) ### the format is namespace: [list of properties] PROPS={"DAV:" : ('creationdate', 'displayname', 'getcontentlanguage', 'getcontentlength', 'getcontenttype', 'getetag', 'getlastmodified', 'lockdiscovery', 'resourcetype', 'source', 'supportedlock'), "NS2" : ("p1","p2") } # here we define which methods handle which namespace # the first item is the namespace URI and the second one # the method prefix # e.g. for DAV:getcontenttype we call dav_getcontenttype() M_NS={"DAV:" : "_get_dav", "NS2" : "ns2" } def get_propnames(self,uri): """ return the property names allowed for the given URI In this method we simply return the above defined properties assuming that they are valid for any resource. You can override this in order to return a different set of property names for each resource. """ return self.PROPS def get_prop2(self,uri,ns,pname): """ return the value of a property """ if lower(ns)=="dav:": return self.get_dav(uri,pname) raise DAV_NotFound def get_prop(self,uri,ns,propname): """ return the value of a given property uri -- uri of the object to get the property of ns -- namespace of the property pname -- name of the property """ if self.M_NS.has_key(ns): prefix=self.M_NS[ns] else: raise DAV_NotFound mname=prefix+"_"+propname.replace('-', '_') try: m=getattr(self,mname) r=m(uri) return r except AttributeError: raise DAV_NotFound ### ### DATA methods (for GET and PUT) ### def get_data(self, uri, range=None): """ return the content of an object return data or raise an exception """ raise DAV_NotFound def put(self, uri, data, content_type=None): """ write an object to the repository return the location uri or raise an exception """ raise DAV_Forbidden ### ### LOCKing information ### def _get_dav_supportedlock(self, uri): txt = ('
\n' '\n' '\n' '
\n') xml = minidom.parseString(txt) return xml.firstChild.firstChild def _get_dav_lockdiscovery(self, uri): lcm = LockManager() if lcm._l_isLocked(uri): lock = lcm._l_getLockForUri(uri) txt = lock.asXML(discover=True, namespace='D') txtwithns = '
%s
' xml = minidom.parseString(txtwithns % txt) return xml.firstChild.firstChild return '' ### ### Methods for DAV properties ### def _get_dav_creationdate(self,uri): """ return the creationdate of a resource """ d=self.get_creationdate(uri) # format it return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(d)) def _get_dav_getlastmodified(self,uri): """ return the last modified date of a resource """ d=self.get_lastmodified(uri) # format it return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(d)) ### ### OVERRIDE THESE! ### def get_creationdate(self,uri): """ return the creationdate of the resource """ return time.time() def get_lastmodified(self,uri): """ return the last modification date of the resource """ return time.time() ### ### COPY MOVE DELETE ### ### methods for deleting a resource def rmcol(self,uri): """ delete a collection This should not delete any children! This is automatically done before by the DELETE class in DAV/delete.py return a success code or raise an exception """ raise DAV_NotFound def rm(self,uri): """ delete a single resource return a success code or raise an exception """ raise DAV_NotFound """ COPY/MOVE HANDLER These handler are called when a COPY or MOVE method is invoked by a client. In the default implementation it works as follows: - the davserver receives a COPY/MOVE method - the davcopy or davmove module will be loaded and the corresponding class will be initialized - this class parses the query and decides which method of the interface class to call: copyone for a single resource to copy copytree for a tree to copy (collection) (the same goes for move of course). - the interface class has now two options: 1. to handle the action directly (e.g. cp or mv on filesystems) 2. to let it handle via the copy/move methods in davcmd. ad 1) The first approach can be used when we know that no error can happen inside a tree or when the action can exactly tell which element made which error. We have to collect these and return it in a dict of the form {uri: error_code, ...} ad 2) The copytree/movetree/... methods of davcmd.py will do the recursion themselves and call for each resource the copy/move method of the interface class. Thus method will then only act on a single resource. (Thus a copycol on a normal unix filesystem actually only needs to do an mkdir as the content will be copied by the davcmd.py function. The davcmd.py method will also automatically collect all errors and return the dictionary described above. When you use 2) you also have to implement the copy() and copycol() methods in your interface class. See the example for details. To decide which approach is the best you have to decide if your application is able to generate errors inside a tree. E.g. a function which completely fails on a tree if one of the tree's childs fail is not what we need. Then 2) would be your way of doing it. Actually usually 2) is the better solution and should only be replaced by 1) if you really need it. The remaining question is if we should do the same for the DELETE method. """ ### MOVE handlers def moveone(self,src,dst,overwrite): """ move one resource with Depth=0 """ return moveone(self,src,dst,overwrite) def movetree(self,src,dst,overwrite): """ move a collection with Depth=infinity """ return movetree(self,src,dst,overwrite) ### COPY handlers def copyone(self,src,dst,overwrite): """ copy one resource with Depth=0 """ return copyone(self,src,dst,overwrite) def copytree(self,src,dst,overwrite): """ copy a collection with Depth=infinity """ return copytree(self,src,dst,overwrite) ### low level copy methods (you only need these for method 2) def copy(self,src,dst): """ copy a resource with depth==0 You don't need to bother about overwrite or not. This has been done already. return a success code or raise an exception if something fails """ return 201 def copycol(self,src,dst): """ copy a resource with depth==infinity You don't need to bother about overwrite or not. This has been done already. return a success code or raise an exception if something fails """ return 201 ### some utility functions you need to implement def exists(self,uri): """ return 1 or None depending on if a resource exists """ return None # no def is_collection(self,uri): """ return 1 or None depending on if a resource is a collection """ return None # no davix-R_0_5_0/test/pywebdav/lib/locks.py000066400000000000000000000200771257152637300203260ustar00rootroot00000000000000import os import sys import time import socket import string import posixpath import base64 import urlparse import urllib import random import logging log = logging.getLogger(__name__) import xml.dom from xml.dom import minidom from utils import rfc1123_date, IfParser, tokenFinder from string import atoi,split from errors import * tokens_to_lock = {} uris_to_token = {} class LockManager: """ Implements the locking backend and serves as MixIn for DAVRequestHandler """ def _init_locks(self): return tokens_to_lock, uris_to_token def _l_isLocked(self, uri): tokens, uris = self._init_locks() return uris.has_key(uri) def _l_hasLock(self, token): tokens, uris = self._init_locks() return tokens.has_key(token) def _l_getLockForUri(self, uri): tokens, uris = self._init_locks() return uris.get(uri, None) def _l_getLock(self, token): tokens, uris = self._init_locks() return tokens.get(token, None) def _l_delLock(self, token): tokens, uris = self._init_locks() if tokens.has_key(token): del uris[tokens[token].uri] del tokens[token] def _l_setLock(self, lock): tokens, uris = self._init_locks() tokens[lock.token] = lock uris[lock.uri] = lock def _lock_unlock_parse(self, body): doc = minidom.parseString(body) data = {} info = doc.getElementsByTagNameNS('DAV:', 'lockinfo')[0] data['lockscope'] = info.getElementsByTagNameNS('DAV:', 'lockscope')[0]\ .firstChild.localName data['locktype'] = info.getElementsByTagNameNS('DAV:', 'locktype')[0]\ .firstChild.localName data['lockowner'] = info.getElementsByTagNameNS('DAV:', 'owner') return data def _lock_unlock_create(self, uri, creator, depth, data): lock = LockItem(uri, creator, **data) iscollection = uri[-1] == '/' # very dumb collection check result = '' if depth == 'infinity' and iscollection: # locking of children/collections not yet supported pass if not self._l_isLocked(uri): self._l_setLock(lock) # because we do not handle children we leave result empty return lock.token, result def do_UNLOCK(self): """ Unlocks given resource """ dc = self.IFACE_CLASS if self._config.DAV.getboolean('verbose') is True: log.info('UNLOCKing resource %s' % self.headers) uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) # check lock token - must contain a dash if not self.headers.get('Lock-Token', '').find('-')>0: return self.send_status(400) token = tokenFinder(self.headers.get('Lock-Token')) if self._l_isLocked(uri): self._l_delLock(token) self.send_body(None, '204', 'Ok', 'Ok') def do_LOCK(self): """ Locking is implemented via in-memory caches. No data is written to disk. """ dc = self.IFACE_CLASS log.info('LOCKing resource %s' % self.headers) body = None if self.headers.has_key('Content-Length'): l = self.headers['Content-Length'] body = self.rfile.read(atoi(l)) depth = self.headers.get('Depth', 'infinity') uri = urlparse.urljoin(self.get_baseuri(dc), self.path) uri = urllib.unquote(uri) log.info('do_LOCK: uri = %s' % uri) ifheader = self.headers.get('If') alreadylocked = self._l_isLocked(uri) log.info('do_LOCK: alreadylocked = %s' % alreadylocked) if body and alreadylocked: # Full LOCK request but resource already locked self.responses[423] = ('Locked', 'Already locked') return self.send_status(423) elif body and not ifheader: # LOCK with XML information data = self._lock_unlock_parse(body) token, result = self._lock_unlock_create(uri, 'unknown', depth, data) if result: self.send_body(result, '207', 'Error', 'Error', 'text/xml; charset="utf-8"') else: lock = self._l_getLock(token) self.send_body(lock.asXML(), '200', 'OK', 'OK', 'text/xml; charset="utf-8"', {'Lock-Token' : '' % token}) else: # refresh request - refresh lock timeout taglist = IfParser(ifheader) found = 0 for tag in taglist: for listitem in tag.list: token = tokenFinder(listitem) if token and self._l_hasLock(token): lock = self._l_getLock(token) timeout = self.headers.get('Timeout', 'Infinite') lock.setTimeout(timeout) # automatically refreshes found = 1 self.send_body(lock.asXML(), '200', 'OK', 'OK', 'text/xml; encoding="utf-8"') break if found: break # we didn't find any of the tokens mentioned - means # that table was cleared or another error if not found: self.send_status(412) # precondition failed class LockItem: """ Lock with support for exclusive write locks. Some code taken from webdav.LockItem from the Zope project. """ def __init__(self, uri, creator, lockowner, depth=0, timeout='Infinite', locktype='write', lockscope='exclusive', token=None, **kw): self.uri = uri self.creator = creator self.owner = lockowner self.depth = depth self.timeout = timeout self.locktype = locktype self.lockscope = lockscope self.token = token and token or self.generateToken() self.modified = time.time() def getModifiedTime(self): return self.modified def refresh(self): self.modified = time.time() def isValid(self): now = time.time() modified = self.modified timeout = self.timeout return (modified + timeout) > now def generateToken(self): _randGen = random.Random(time.time()) return '%s-%s-00105A989226:%.03f' % \ (_randGen.random(),_randGen.random(),time.time()) def getTimeoutString(self): t = str(self.timeout) if t[-1] == 'L': t = t[:-1] return 'Second-%s' % t def setTimeout(self, timeout): self.timeout = timeout self.modified = time.time() def asXML(self, namespace='d', discover=False): owner_str = '' if isinstance(self.owner, str): owner_str = self.owner elif isinstance(self.owner, xml.dom.minicompat.NodeList): owner_str = "".join([node.toxml() for node in self.owner[0].childNodes]) token = self.token base = ('<%(ns)s:activelock>\n' ' <%(ns)s:locktype><%(ns)s:%(locktype)s/>\n' ' <%(ns)s:lockscope><%(ns)s:%(lockscope)s/>\n' ' <%(ns)s:depth>%(depth)s\n' ' <%(ns)s:owner>%(owner)s\n' ' <%(ns)s:timeout>%(timeout)s\n' ' <%(ns)s:locktoken>\n' ' <%(ns)s:href>opaquelocktoken:%(locktoken)s\n' ' \n' ' \n' ) % { 'ns': namespace, 'locktype': self.locktype, 'lockscope': self.lockscope, 'depth': self.depth, 'owner': owner_str, 'timeout': self.getTimeoutString(), 'locktoken': token, } if discover is True: return base s = """ %s """ % base return s davix-R_0_5_0/test/pywebdav/lib/propfind.py000066400000000000000000000266021257152637300210340ustar00rootroot00000000000000import xml.dom.minidom domimpl = xml.dom.minidom.getDOMImplementation() import logging import urlparse import urllib import utils from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP from errors import DAV_Error, DAV_NotFound log = logging.getLogger(__name__) class PROPFIND: """ parse a propfind xml element and extract props It will set the following instance vars: request_class : ALLPROP | PROPNAME | PROP proplist : list of properties nsmap : map of namespaces The list of properties will contain tuples of the form (element name, ns_prefix, ns_uri) """ def __init__(self, uri, dataclass, depth, body): self.request_type = None self.nsmap = {} self.proplist = {} self.default_ns = None self._dataclass = dataclass self._depth = str(depth) self._uri = uri.rstrip('/') self._has_body = None # did we parse a body? if dataclass.verbose: log.info('PROPFIND: Depth is %s, URI is %s' % (depth, uri)) if body: self.request_type, self.proplist, self.namespaces = \ utils.parse_propfind(body) self._has_body = True def createResponse(self): """ Create the multistatus response This will be delegated to the specific method depending on which request (allprop, propname, prop) was found. If we get a PROPNAME then we simply return the list with empty values which we get from the interface class If we get an ALLPROP we first get the list of properties and then we do the same as with a PROP method. """ # check if resource exists if not self._dataclass.exists(self._uri): raise DAV_NotFound df = None if self.request_type == RT_ALLPROP: df = self.create_allprop() if self.request_type == RT_PROPNAME: df = self.create_propname() if self.request_type == RT_PROP: df = self.create_prop() if df != None: return df # no body means ALLPROP! df = self.create_allprop() return df def create_propname(self): """ create a multistatus response for the prop names """ dc = self._dataclass # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth == "0": pnames = dc.get_propnames(self._uri) re = self.mk_propname_response(self._uri, pnames, doc) ms.appendChild(re) elif self._depth == "1": pnames = dc.get_propnames(self._uri) re = self.mk_propname_response(self._uri, pnames, doc) ms.appendChild(re) for newuri in dc.get_childs(self._uri): pnames = dc.get_propnames(newuri) re = self.mk_propname_response(newuri, pnames, doc) ms.appendChild(re) elif self._depth == 'infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() pnames = dc.get_propnames(uri) re = self.mk_propname_response(uri, pnames, doc) ms.appendChild(re) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") def create_allprop(self): """ return a list of all properties """ self.proplist = {} self.namespaces = [] for ns, plist in self._dataclass.get_propnames(self._uri).items(): self.proplist[ns] = plist self.namespaces.append(ns) return self.create_prop() def create_prop(self): """ handle a request This will 1. set up the -Framework 2. read the property values for each URI (which is dependant on the Depth header) This is done by the get_propvalues() method. 3. For each URI call the append_result() method to append the actual -Tag to the result document. We differ between "good" properties, which have been assigned a value by the interface class and "bad" properties, which resulted in an error, either 404 (Not Found) or 403 (Forbidden). """ # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth == "0": gp, bp = self.get_propvalues(self._uri) res = self.mk_prop_response(self._uri, gp, bp, doc) ms.appendChild(res) elif self._depth == "1": gp, bp = self.get_propvalues(self._uri) res = self.mk_prop_response(self._uri, gp, bp, doc) ms.appendChild(res) for newuri in self._dataclass.get_childs(self._uri): gp, bp = self.get_propvalues(newuri) res = self.mk_prop_response(newuri, gp, bp, doc) ms.appendChild(res) elif self._depth == 'infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() gp, bp = self.get_propvalues(uri) res = self.mk_prop_response(uri, gp, bp, doc) ms.appendChild(res) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") def mk_propname_response(self, uri, propnames, doc): """ make a new result element for a PROPNAME request This will simply format the propnames list. propnames should have the format {NS1 : [prop1, prop2, ...], NS2: ...} """ re = doc.createElement("D:response") if self._dataclass.baseurl: uri = self._dataclass.baseurl + '/' + '/'.join(uri.split('/')[3:]) # write href information uparts = urlparse.urlparse(uri) fileloc = uparts[2] href = doc.createElement("D:href") huri = doc.createTextNode(uparts[0] + '://' + '/'.join(uparts[1:2]) + urllib.quote(fileloc)) href.appendChild(huri) re.appendChild(href) ps = doc.createElement("D:propstat") nsnum = 0 for ns, plist in propnames.items(): # write prop element pr = doc.createElement("D:prop") nsp = "ns" + str(nsnum) pr.setAttribute("xmlns:" + nsp, ns) nsnum += 1 # write propertynames for p in plist: pe = doc.createElement(nsp + ":" + p) pr.appendChild(pe) ps.appendChild(pr) re.appendChild(ps) return re def mk_prop_response(self, uri, good_props, bad_props, doc): """ make a new result element We differ between the good props and the bad ones for each generating an extra -Node (for each error one, that means). """ re = doc.createElement("D:response") # append namespaces to response nsnum = 0 for nsname in self.namespaces: if nsname != 'DAV:': re.setAttribute("xmlns:ns" + str(nsnum), nsname) nsnum += 1 if self._dataclass.baseurl: uri = self._dataclass.baseurl + '/' + '/'.join(uri.split('/')[3:]) # write href information uparts = urlparse.urlparse(uri) fileloc = uparts[2] href = doc.createElement("D:href") huri = doc.createTextNode(uparts[0] + '://' + '/'.join(uparts[1:2]) + urllib.quote(fileloc)) href.appendChild(huri) re.appendChild(href) # write good properties ps = doc.createElement("D:propstat") if good_props: re.appendChild(ps) gp = doc.createElement("D:prop") for ns in good_props.keys(): if ns != 'DAV:': ns_prefix = "ns" + str(self.namespaces.index(ns)) + ":" else: ns_prefix = 'D:' for p, v in good_props[ns].items(): pe = doc.createElement(ns_prefix + str(p)) if isinstance(v, xml.dom.minidom.Element): pe.appendChild(v) elif isinstance(v, list): for val in v: pe.appendChild(val) else: if p == "resourcetype": if v == 1: ve = doc.createElement("D:collection") pe.appendChild(ve) else: ve = doc.createTextNode(v) pe.appendChild(ve) gp.appendChild(pe) ps.appendChild(gp) s = doc.createElement("D:status") t = doc.createTextNode("HTTP/1.1 200 OK") s.appendChild(t) ps.appendChild(s) re.appendChild(ps) # now write the errors! if len(bad_props.items()): # write a propstat for each error code for ecode in bad_props.keys(): ps = doc.createElement("D:propstat") re.appendChild(ps) bp = doc.createElement("D:prop") ps.appendChild(bp) for ns in bad_props[ecode].keys(): if ns != 'DAV:': ns_prefix = "ns" + str(self.namespaces.index(ns)) + ":" else: ns_prefix = 'D:' for p in bad_props[ecode][ns]: pe = doc.createElement(ns_prefix + str(p)) bp.appendChild(pe) s = doc.createElement("D:status") t = doc.createTextNode(utils.gen_estring(ecode)) s.appendChild(t) ps.appendChild(s) re.appendChild(ps) # return the new response element return re def get_propvalues(self, uri): """ create lists of property values for an URI We create two lists for an URI: the properties for which we found a value and the ones for which we only got an error, either because they haven't been found or the user is not allowed to read them. """ good_props = {} bad_props = {} ddc = self._dataclass for ns, plist in self.proplist.items(): good_props[ns] = {} for prop in plist: ec = 0 try: r = ddc.get_prop(uri, ns, prop) good_props[ns][prop] = r except DAV_Error, error_code: ec = error_code[0] # ignore props with error_code if 0 (invisible) if ec == 0: continue if ec in bad_props: if ns in bad_props[ec]: bad_props[ec][ns].append(prop) else: bad_props[ec][ns] = [prop] else: bad_props[ec] = {ns: [prop]} return good_props, bad_props davix-R_0_5_0/test/pywebdav/lib/report.py000066400000000000000000000104401257152637300205170ustar00rootroot00000000000000from propfind import PROPFIND from xml.dom import minidom domimpl = minidom.getDOMImplementation() from utils import get_parenturi class REPORT(PROPFIND): def __init__(self, uri, dataclass, depth, body): PROPFIND.__init__(self, uri, dataclass, depth, body) doc = minidom.parseString(body) self.filter = doc.documentElement def create_propname(self): """ create a multistatus response for the prop names """ dc=self._dataclass # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth=="0": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): pnames=dc.get_propnames(self._uri) re=self.mk_propname_response(self._uri,pnames, doc) ms.appendChild(re) elif self._depth=="1": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): pnames=dc.get_propnames(self._uri) re=self.mk_propname_response(self._uri,pnames, doc) ms.appendChild(re) for newuri in dc.get_childs(self._uri, self.filter): pnames=dc.get_propnames(newuri) re=self.mk_propname_response(newuri,pnames, doc) ms.appendChild(re) elif self._depth=='infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() if uri in self._dataclass.get_childs(get_parenturi(uri), self.filter): pnames=dc.get_propnames(uri) re=self.mk_propname_response(uri,pnames, doc) ms.appendChild(re) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") def create_prop(self): """ handle a request This will 1. set up the -Framework 2. read the property values for each URI (which is dependant on the Depth header) This is done by the get_propvalues() method. 3. For each URI call the append_result() method to append the actual -Tag to the result document. We differ between "good" properties, which have been assigned a value by the interface class and "bad" properties, which resulted in an error, either 404 (Not Found) or 403 (Forbidden). """ # create the document generator doc = domimpl.createDocument(None, "multistatus", None) ms = doc.documentElement ms.setAttribute("xmlns:D", "DAV:") ms.tagName = 'D:multistatus' if self._depth=="0": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): gp,bp=self.get_propvalues(self._uri) res=self.mk_prop_response(self._uri,gp,bp,doc) ms.appendChild(res) elif self._depth=="1": if self._uri in self._dataclass.get_childs(get_parenturi(self._uri), self.filter): gp,bp=self.get_propvalues(self._uri) res=self.mk_prop_response(self._uri,gp,bp,doc) ms.appendChild(res) for newuri in self._dataclass.get_childs(self._uri, self.filter): gp,bp=self.get_propvalues(newuri) res=self.mk_prop_response(newuri,gp,bp,doc) ms.appendChild(res) elif self._depth=='infinity': uri_list = [self._uri] while uri_list: uri = uri_list.pop() if uri in self._dataclass.get_childs(get_parenturi(uri), self.filter): gp,bp=self.get_propvalues(uri) res=self.mk_prop_response(uri,gp,bp,doc) ms.appendChild(res) uri_childs = self._dataclass.get_childs(uri) if uri_childs: uri_list.extend(uri_childs) return doc.toxml(encoding="utf-8") davix-R_0_5_0/test/pywebdav/lib/status.py000066400000000000000000000012611257152637300205300ustar00rootroot00000000000000 STATUS_CODES={ 100: "Continue", 102: "Processing", 200: "Ok", 201: "Created", 204: "No Content", 207: "Multi-Status", 201: "Created", 400: "Bad Request", 403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed", 409: "Conflict", 412: "Precondition failed", 423: "Locked", 415: "Unsupported Media Type", 507: "Insufficient Storage", 422: "Unprocessable Entity", 423: "Locked", 424: "Failed Dependency", 502: "Bad Gateway", 507: "Insufficient Storage" } davix-R_0_5_0/test/pywebdav/lib/utils.py000077500000000000000000000153251257152637300203560ustar00rootroot00000000000000import time import re from xml.dom import minidom import urlparse from string import lower, split, atoi, joinfields from StringIO import StringIO from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP from BaseHTTPServer import BaseHTTPRequestHandler def gen_estring(ecode): """ generate an error string from the given code """ ec=atoi(str(ecode)) if BaseHTTPRequestHandler.responses.has_key(ec): return "HTTP/1.1 %s %s" %(ec, BaseHTTPRequestHandler.responses[ec][0]) else: return "HTTP/1.1 %s" %(ec) def parse_propfind(xml_doc): """ Parse an propfind xml file and return a list of props """ doc = minidom.parseString(xml_doc) request_type=None props={} namespaces=[] if doc.getElementsByTagNameNS("DAV:", "allprop"): request_type = RT_ALLPROP elif doc.getElementsByTagNameNS("DAV:", "propname"): request_type = RT_PROPNAME else: request_type = RT_PROP for i in doc.getElementsByTagNameNS("DAV:", "prop"): for e in i.childNodes: if e.nodeType != minidom.Node.ELEMENT_NODE: continue ns = e.namespaceURI ename = e.localName if props.has_key(ns): props[ns].append(ename) else: props[ns]=[ename] namespaces.append(ns) return request_type,props,namespaces def create_treelist(dataclass,uri): """ create a list of resources out of a tree This function is used for the COPY, MOVE and DELETE methods uri - the root of the subtree to flatten It will return the flattened tree as list """ queue=[uri] list=[uri] while len(queue): element=queue[-1] if dataclass.is_collection(element): childs=dataclass.get_childs(element) else: childs=[] if len(childs): list=list+childs # update queue del queue[-1] if len(childs): queue=queue+childs return list def is_prefix(uri1,uri2): """ returns 1 of uri1 is a prefix of uri2 """ if uri2[:len(uri1)]==uri1: return 1 else: return None def quote_uri(uri): """ quote an URL but not the protocol part """ import urlparse import urllib up=urlparse.urlparse(uri) np=urllib.quote(up[2]) return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) def get_uriparentpath(uri): """ extract the uri path and remove the last element """ up=urlparse.urlparse(uri) return joinfields(split(up[2],"/")[:-1],"/") def get_urifilename(uri): """ extract the uri path and return the last element """ up=urlparse.urlparse(uri) return split(up[2],"/")[-1] def get_parenturi(uri): """ return the parent of the given resource""" up=urlparse.urlparse(uri) np=joinfields(split(up[2],"/")[:-1],"/") return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) ### XML utilities def make_xmlresponse(result): """ construct a response from a dict of uri:error_code elements """ doc = minidom.getDOMImplementation().createDocument(None, "multistatus", None) doc.documentElement.setAttribute("xmlns:D","DAV:") doc.documentElement.tagName = "D:multistatus" for el,ec in result.items(): re=doc.createElementNS("DAV:","response") hr=doc.createElementNS("DAV:","href") st=doc.createElementNS("DAV:","status") huri=doc.createTextNode(quote_uri(el)) t=doc.createTextNode(gen_estring(ec)) st.appendChild(t) hr.appendChild(huri) re.appendChild(hr) re.appendChild(st) doc.documentElement.appendChild(re) return doc.toxml(encoding="utf-8") # taken from App.Common weekday_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] weekday_full = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] def rfc1123_date(ts=None): # Return an RFC 1123 format date string, required for # use in HTTP Date headers per the HTTP 1.1 spec. # 'Fri, 10 Nov 2000 16:21:09 GMT' if ts is None: ts=time.time() year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts) return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (weekday_abbr[wd], day, monthname[month], year, hh, mm, ss) def iso8601_date(ts=None): # Return an ISO 8601 formatted date string, required # for certain DAV properties. # '2000-11-10T16:21:09-08:00 if ts is None: ts=time.time() return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts)) def rfc850_date(ts=None): # Return an HTTP-date formatted date string. # 'Friday, 10-Nov-00 16:21:09 GMT' if ts is None: ts=time.time() year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts) return "%s, %02d-%3s-%2s %02d:%02d:%02d GMT" % ( weekday_full[wd], day, monthname[month], str(year)[2:], hh, mm, ss) ### If: header handling support. IfParser returns a sequence of ### TagList objects in the order they were parsed which can then ### be used in WebDAV methods to decide whether an operation can ### proceed or to raise HTTP Error 412 (Precondition failed) IfHdr = re.compile( r"(?P<.+?>)?\s*\((?P[^)]+)\)" ) ListItem = re.compile( r"(?Pnot)?\s*(?P<[a-zA-Z]+:[^>]*>|\[.*?\])", re.I) class TagList: def __init__(self): self.resource = None self.list = [] self.NOTTED = 0 def IfParser(hdr): out = [] i = 0 while 1: m = IfHdr.search(hdr[i:]) if not m: break i = i + m.end() tag = TagList() tag.resource = m.group('resource') if tag.resource: # We need to delete < > tag.resource = tag.resource[1:-1] listitem = m.group('listitem') tag.NOTTED, tag.list = ListParser(listitem) out.append(tag) return out def tokenFinder(token): # takes a string like ' and returns the token # part. if not token: return None # An empty string was passed in if token[0] == '[': return None # An Etag was passed in if token[0] == '<': token = token[1:-1] return token[token.find(':')+1:] def ListParser(listitem): out = [] NOTTED = 0 i = 0 while 1: m = ListItem.search(listitem[i:]) if not m: break i = i + m.end() out.append(m.group('listitem')) if m.group('not'): NOTTED = 1 return NOTTED, out davix-R_0_5_0/test/pywebdav/server/000077500000000000000000000000001257152637300173735ustar00rootroot00000000000000davix-R_0_5_0/test/pywebdav/server/__init__.py000066400000000000000000000000011257152637300214730ustar00rootroot00000000000000 davix-R_0_5_0/test/pywebdav/server/config.ini000066400000000000000000000020351257152637300213410ustar00rootroot00000000000000 # PyWebDAV config.ini # Read documents before editing this file # Created 11:48 10-08-2006 By Vince Spicer [MySQL] # Mysql server information host=localhost port=3306 user=root passwd=rootpw # Auth Database Table, Must exists in database prior to firstrun dbtable=webDav # Create User Database Table and Insert system user # Disable after the Table is created; for performance reasons firstrun=0 [DAV] # Verbose? # verbose enabled is like loglevel = INFO verbose = 1 #log level : DEBUG, INFO, WARNING, ERROR, CRITICAL (Default is WARNING) #loglevel = WARNING # main directory directory = /home/spamies/tmp # Server address port = 8081 host = localhost # disable auth noauth = 0 # Enable mysql auth mysql_auth=0 # admin user user = test password = test00 # daemonize? daemonize = 0 daemonaction = start # instance counter counter = 0 # mimetypes support mimecheck = 1 # webdav level (1 = webdav level 2) lockemulation = 1 # internal features #chunked_http_response = 1 #http_request_use_iterator = 0 #http_response_use_iterator = 0 davix-R_0_5_0/test/pywebdav/server/daemonize.py000066400000000000000000000124521257152637300217240ustar00rootroot00000000000000#Copyright (c) 2005 Simon Pamies (s.pamies@banality.de) #Copyright (c) 2003 Clark Evans #Copyright (c) 2002 Noah Spurrier #Copyright (c) 2001 Juergen Hermann # #This 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. # #This 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 this library; if not, write to the Free #Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, #MA 02111-1307, USA ''' This module is used to fork the current process into a daemon. Almost none of this is necessary (or advisable) if your daemon is being started by inetd. In that case, stdin, stdout and stderr are all set up for you to refer to the network connection, and the fork()s and session manipulation should not be done (to avoid confusing inetd). Only the chdir() and umask() steps remain as useful. References: UNIX Programming FAQ 1.7 How do I get my program to act like a daemon? http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 Advanced Programming in the Unix Environment W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7. History: 2005/06/23 by Simon Pamies 2001/07/10 by Juergen Hermann 2002/08/28 by Noah Spurrier 2003/02/24 by Clark Evans http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 ''' import sys, os, time from signal import SIGTERM def deamonize(stdout='/dev/null', stderr=None, stdin='/dev/null', pidfile=None, startmsg = 'started with pid %s' ): ''' This forks the current process into a daemon. The stdin, stdout, and stderr arguments are file names that will be opened and be used to replace the standard file descriptors in sys.stdin, sys.stdout, and sys.stderr. These arguments are optional and default to /dev/null. Note that stderr is opened unbuffered, so if it shares a file with stdout then interleaved output may not appear in the order that you expect. ''' # Do first fork. try: pid = os.fork() if pid > 0: sys.exit(0) # Exit first parent. except OSError, e: sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) # Decouple from parent environment. os.chdir("/") os.umask(0) os.setsid() # Do second fork. try: pid = os.fork() if pid > 0: sys.exit(0) # Exit second parent. except OSError, e: sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) # Open file descriptors and print start message if not stderr: stderr = stdout si = file(stdin, 'r') so = file(stdout, 'a+') se = file(stderr, 'a+', 0) pid = str(os.getpid()) sys.stderr.write("\n%s\n" % startmsg % pid) sys.stderr.flush() if pidfile: file(pidfile,'w+').write("%s\n" % pid) if sys.stdin.closed: sys.stdin = open('/dev/null', 'r') if sys.stdout.closed: sys.stdout = open('/dev/null', 'a+') if sys.stderr.closed: sys.stderr = open('/dev/null', 'a+') # Redirect standard file descriptors. os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) def startstop(stdout='/dev/null', stderr=None, stdin='/dev/null', pidfile='pid.txt', startmsg = 'started with pid %s', action='start' ): if action: try: pf = file(pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if 'stop' == action or 'restart' == action: if not pid: mess = "Could not stop, pid file '%s' missing.\n" sys.stderr.write(mess % pidfile) if 'stop' == action: sys.exit(1) action = 'start' pid = None else: try: while 1: os.kill(pid,SIGTERM) time.sleep(1) except OSError, err: err = str(err) if err.find("No such process") > 0: os.remove(pidfile) if 'stop' == action: sys.exit(0) action = 'start' pid = None else: print str(err) sys.exit(1) if 'start' == action: if pid: mess = "Start aborted since pid file '%s' exists.\n" sys.stderr.write(mess % pidfile) sys.exit(1) deamonize(stdout,stderr,stdin,pidfile,startmsg) return if 'status' == action: if not pid: sys.stderr.write('Status: Stopped\n') else: sys.stderr.write('Status: Running\n') sys.exit(0) davix-R_0_5_0/test/pywebdav/server/fileauth.py000066400000000000000000000034621257152637300215530ustar00rootroot00000000000000#Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de) # #This 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. # #This 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 this library; if not, write to the Free #Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, #MA 02111-1307, USA """ Python WebDAV Server. This is an example implementation of a DAVserver using the DAV package. """ import sys import logging from pywebdav.lib.WebDAVServer import DAVRequestHandler from pywebdav.lib.dbconn import Mconn from fshandler import FilesystemHandler log = logging.getLogger() class DAVAuthHandler(DAVRequestHandler): """ Provides authentication based on parameters. The calling class has to inject password and username into this. (Variables: auth_user and auth_pass) """ # Do not forget to set IFACE_CLASS by caller # ex.: IFACE_CLASS = FilesystemHandler('/tmp', 'http://localhost/') verbose = False def _log(self, message): if self.verbose: log.info(message) def get_userinfo(self,user,pw,command): """ authenticate user """ if user == self._config.DAV.user and pw == self._config.DAV.password: log.info('Successfully authenticated user %s' % user) return 1 log.info('Authentication failed for user %s' % user) return 0 davix-R_0_5_0/test/pywebdav/server/fshandler.py000066400000000000000000000267051257152637300217250ustar00rootroot00000000000000import sys import urlparse import os import time from string import joinfields, split, lower import logging import types import shutil from pywebdav.lib.constants import COLLECTION, OBJECT from pywebdav.lib.errors import * from pywebdav.lib.iface import * from pywebdav.lib.davcmd import copyone, copytree, moveone, movetree, delone, deltree log = logging.getLogger(__name__) BUFFER_SIZE = 128 * 1000 # include magic support to correctly determine mimetypes MAGIC_AVAILABLE = False try: import mimetypes MAGIC_AVAILABLE = True log.info('Mimetype support ENABLED') except ImportError: log.info('Mimetype support DISABLED') pass class Resource(object): # XXX this class is ugly def __init__(self, fp, file_size): self.__fp = fp self.__file_size = file_size def __len__(self): return self.__file_size def __iter__(self): while 1: data = self.__fp.read(BUFFER_SIZE) if not data: break yield data time.sleep(0.005) self.__fp.close() def read(self, length = 0): if length == 0: length = self.__file_size data = self.__fp.read(length) return data class FilesystemHandler(dav_interface): """ Model a filesystem for DAV This class models a regular filesystem for the DAV server The basic URL will be http://localhost/ And the underlying filesystem will be /tmp Thus http://localhost/gfx/pix will lead to /tmp/gfx/pix """ def __init__(self, directory, uri, verbose=False): self.setDirectory(directory) self.setBaseURI(uri) # should we be verbose? self.verbose = verbose log.info('Initialized with %s %s' % (directory, uri)) def setDirectory(self, path): """ Sets the directory """ if not os.path.isdir(path): raise Exception, '%s not must be a directory!' % path self.directory = path def setBaseURI(self, uri): """ Sets the base uri """ self.baseuri = uri def uri2local(self,uri): """ map uri in baseuri and local part """ uparts=urlparse.urlparse(uri) fileloc=uparts[2][1:] filename=os.path.join(self.directory,fileloc) filename=os.path.normpath(filename) return filename def local2uri(self,filename): """ map local filename to self.baseuri """ pnum=len(split(self.directory.replace("\\","/"),"/")) parts=split(filename.replace("\\","/"),"/")[pnum:] sparts="/"+joinfields(parts,"/") uri=urlparse.urljoin(self.baseuri,sparts) return uri def get_childs(self, uri, filter=None): """ return the child objects as self.baseuris for the given URI """ fileloc=self.uri2local(uri) filelist=[] if os.path.exists(fileloc): if os.path.isdir(fileloc): try: files=os.listdir(fileloc) except: raise DAV_NotFound for file in files: newloc=os.path.join(fileloc,file) filelist.append(self.local2uri(newloc)) log.info('get_childs: Childs %s' % filelist) return filelist def get_data(self,uri, range = None): """ return the content of an object """ path=self.uri2local(uri) if os.path.exists(path): if os.path.isfile(path): file_size = os.path.getsize(path) if range == None: fp=open(path,"r") log.info('Serving content of %s' % uri) return Resource(fp, file_size) else: if range[1] == '': range[1] = file_size else: range[1] = int(range[1]) if range[0] == '': range[0] = file_size - range[1] else: range[0] = int(range[0]) if range[0] > file_size: raise DAV_Requested_Range_Not_Satisfiable if range[1] > file_size: range[1] = file_size fp=open(path,"r") fp.seek(range[0]) log.info('Serving range %s -> %s content of %s' % (range[0], range[1], uri)) return Resource(fp, range[1] - range[0]) elif os.path.isdir(path): # GET for collections is defined as 'return s/th meaningful' :-) from StringIO import StringIO stio = StringIO('Directory at %s' % uri) return Resource(StringIO('Directory at %s' % uri), stio.len) else: # also raise an error for collections # don't know what should happen then.. log.info('get_data: %s not found' % path) raise DAV_NotFound def _get_dav_resourcetype(self,uri): """ return type of object """ path=self.uri2local(uri) if os.path.isfile(path): return OBJECT elif os.path.isdir(path): return COLLECTION raise DAV_NotFound def _get_dav_displayname(self,uri): raise DAV_Secret # do not show def _get_dav_getcontentlength(self,uri): """ return the content length of an object """ path=self.uri2local(uri) if os.path.exists(path): if os.path.isfile(path): s=os.stat(path) return str(s[6]) return '0' def get_lastmodified(self,uri): """ return the last modified date of the object """ path=self.uri2local(uri) if os.path.exists(path): s=os.stat(path) date=s[8] return date raise DAV_NotFound def get_creationdate(self,uri): """ return the last modified date of the object """ path=self.uri2local(uri) if os.path.exists(path): s=os.stat(path) date=s[9] return date raise DAV_NotFound def _get_dav_getcontenttype(self,uri): """ find out yourself! """ path=self.uri2local(uri) if os.path.exists(path): if os.path.isfile(path): if MAGIC_AVAILABLE is False \ or self.mimecheck is False: return 'application/octet-stream' else: ret, encoding = mimetypes.guess_type(path) # for non mimetype related result we # simply return an appropriate type if ret.find('/')==-1: if ret.find('text')>=0: return 'text/plain' else: return 'application/octet-stream' else: return ret elif os.path.isdir(path): return "httpd/unix-directory" raise DAV_NotFound, 'Could not find %s' % path def put(self, uri, data, content_type=None): """ put the object into the filesystem """ path=self.uri2local(uri) try: fp=open(path, "w+") if isinstance(data, types.GeneratorType): for d in data: fp.write(d) else: if data: fp.write(data) fp.close() log.info('put: Created %s' % uri) except: log.info('put: Could not create %s' % uri) raise DAV_Error, 424 return None def mkcol(self,uri): """ create a new collection """ path=self.uri2local(uri) # remove trailing slash if path[-1]=="/": path=path[:-1] # test if file already exists if os.path.exists(path): raise DAV_Error,405 # test if parent exists h,t=os.path.split(path) if not os.path.exists(h): raise DAV_Error, 409 # test, if we are allowed to create it try: os.mkdir(path) log.info('mkcol: Created new collection %s' % path) return 201 except: log.info('mkcol: Creation of %s denied' % path) raise DAV_Forbidden ### ?? should we do the handler stuff for DELETE, too ? ### (see below) def rmcol(self,uri): """ delete a collection """ path=self.uri2local(uri) if not os.path.exists(path): raise DAV_NotFound try: shutil.rmtree(path) except OSError: raise DAV_Forbidden # forbidden return 204 def rm(self,uri): """ delete a normal resource """ path=self.uri2local(uri) if not os.path.exists(path): raise DAV_NotFound try: os.unlink(path) except OSError, ex: log.info('rm: Forbidden (%s)' % ex) raise DAV_Forbidden # forbidden return 204 ### ### DELETE handlers (examples) ### (we use the predefined methods in davcmd instead of doing ### a rm directly ### def delone(self,uri): """ delete a single resource You have to return a result dict of the form uri:error_code or None if everything's ok """ return delone(self,uri) def deltree(self,uri): """ delete a collection You have to return a result dict of the form uri:error_code or None if everything's ok """ return deltree(self,uri) ### ### MOVE handlers (examples) ### def moveone(self,src,dst,overwrite): """ move one resource with Depth=0 """ return moveone(self,src,dst,overwrite) def movetree(self,src,dst,overwrite): """ move a collection with Depth=infinity """ return movetree(self,src,dst,overwrite) ### ### COPY handlers ### def copyone(self,src,dst,overwrite): """ copy one resource with Depth=0 """ return copyone(self,src,dst,overwrite) def copytree(self,src,dst,overwrite): """ copy a collection with Depth=infinity """ return copytree(self,src,dst,overwrite) ### ### copy methods. ### This methods actually copy something. low-level ### They are called by the davcmd utility functions ### copytree and copyone (not the above!) ### Look in davcmd.py for further details. ### def copy(self,src,dst): """ copy a resource from src to dst """ srcfile=self.uri2local(src) dstfile=self.uri2local(dst) try: shutil.copy(srcfile, dstfile) except (OSError, IOError): log.info('copy: forbidden') raise DAV_Error, 409 def copycol(self, src, dst): """ copy a collection. As this is not recursive (the davserver recurses itself) we will only create a new directory here. For some more advanced systems we might also have to copy properties from the source to the destination. """ return self.mkcol(dst) def exists(self,uri): """ test if a resource exists """ path=self.uri2local(uri) if os.path.exists(path): return 1 return None def is_collection(self,uri): """ test if the given uri is a collection """ path=self.uri2local(uri) if os.path.isdir(path): return 1 else: return 0 davix-R_0_5_0/test/pywebdav/server/mysqlauth.py000066400000000000000000000036371257152637300220050ustar00rootroot00000000000000#Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de) # #This 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. # #This 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 this library; if not, write to the Free #Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, #MA 02111-1307, USA from fileauth import DAVAuthHandler class MySQLAuthHandler(DAVAuthHandler): """ Provides authentication based on a mysql table """ def get_userinfo(self,user,pw,command): """ authenticate user """ # Commands that need write access nowrite=['OPTIONS','PROPFIND','GET'] Mysql=self._config.MySQL DB=Mconn(Mysql.user,Mysql.passwd,Mysql.host,Mysql.port,Mysql.dbtable) if self.verbose: print >>sys.stderr,user,command qry="select * from %s.Users where User='%s' and Pass='%s'"%(Mysql.dbtable,user,pw) Auth=DB.execute(qry) if len(Auth) == 1: can_write=Auth[0][3] if not can_write and not command in nowrite: self._log('Authentication failed for user %s using command %s' %(user,command)) return 0 else: self._log('Successfully authenticated user %s writable=%s' % (user,can_write)) return 1 else: self._log('Authentication failed for user %s' % user) return 0 self._log('Authentication failed for user %s' % user) return 0 davix-R_0_5_0/test/pywebdav/server/server.py000077500000000000000000000307211257152637300212610ustar00rootroot00000000000000#!/usr/bin/env python """ Python WebDAV Server. This is an example implementation of a DAVserver using the DAV package. """ import getopt, sys, os import logging logging.basicConfig(level=logging.WARNING) log = logging.getLogger('pywebdav') from BaseHTTPServer import HTTPServer from SocketServer import ThreadingMixIn try: import pywebdav.lib except ImportError: print 'pywebdav.lib package not found! Please install into site-packages or set PYTHONPATH!' sys.exit(2) from fileauth import DAVAuthHandler from mysqlauth import MySQLAuthHandler from fshandler import FilesystemHandler from daemonize import startstop from pywebdav.lib.INI_Parse import Configuration from pywebdav.lib import VERSION, AUTHOR LEVELS = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL} class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): """Handle requests in a separate thread.""" def runserver( port = 8008, host='localhost', directory='/tmp', verbose = False, noauth = False, user = '', password = '', handler = DAVAuthHandler, server = ThreadedHTTPServer): directory = directory.strip() directory = directory.rstrip('/') host = host.strip() if not os.path.isdir(directory): log.error('%s is not a valid directory!' % directory) return sys.exit(233) # basic checks against wrong hosts if host.find('/') != -1 or host.find(':') != -1: log.error('Malformed host %s' % host) return sys.exit(233) # no root directory if directory == '/': log.error('Root directory not allowed!') sys.exit(233) # dispatch directory and host to the filesystem handler # This handler is responsible from where to take the data handler.IFACE_CLASS = FilesystemHandler(directory, 'http://%s:%s/' % (host, port), verbose ) # put some extra vars handler.verbose = verbose if noauth: log.warning('Authentication disabled!') handler.DO_AUTH = False log.info('Serving data from %s' % directory) if handler._config.DAV.getboolean('lockemulation') is False: log.info('Deactivated LOCK, UNLOCK (WebDAV level 2) support') handler.IFACE_CLASS.mimecheck = True if handler._config.DAV.getboolean('mimecheck') is False: handler.IFACE_CLASS.mimecheck = False log.info('Disabled mimetype sniffing (All files will have type application/octet-stream)') if handler._config.DAV.baseurl: log.info('Using %s as base url for PROPFIND requests' % handler._config.DAV.baseurl) handler.IFACE_CLASS.baseurl = handler._config.DAV.baseurl # initialize server on specified port runner = server( (host, port), handler ) print('Listening on %s (%i)' % (host, port)) try: runner.serve_forever() except KeyboardInterrupt: log.info('Killed by user') usage = """PyWebDAV server (version %s) Standalone WebDAV server Make sure to activate LOCK, UNLOCK using parameter -J if you want to use clients like Windows Explorer or Mac OS X Finder that expect LOCK working for write support. Usage: ./server.py [OPTIONS] Parameters: -c, --config Specify a file where configuration is specified. In this file you can specify options for a running server. For an example look at the config.ini in this directory. -D, --directory Directory where to serve data from The user that runs this server must have permissions on that directory. NEVER run as root! Default directory is /tmp -B, --baseurl Behind a proxy pywebdav needs to generate other URIs for PROPFIND. If you are experiencing problems with links or such when behind a proxy then just set this to a sensible default (e.g. http://dav.domain.com). Make sure that you include the protocol. -H, --host Host where to listen on (default: localhost) -P, --port Port to bind server to (default: 8008) -u, --user Username for authentication -p, --password Password for given user -n, --noauth Pass parameter if server should not ask for authentication This means that every user has access -m, --mysql Pass this parameter if you want MySQL based authentication. If you want to use MySQL then the usage of a configuration file is mandatory. -J, --nolock Deactivate LOCK and UNLOCK mode (WebDAV Version 2). -M, --nomime Deactivate mimetype sniffing. Sniffing is based on magic numbers detection but can be slow under heavy load. If you are experiencing speed problems try to use this parameter. -T, --noiter Deactivate iterator. Use this if you encounter file corruption during download. Also disables chunked body response. -i, --icounter If you want to run multiple instances then you have to give each instance it own number so that logfiles and such can be identified. Default is 0 -d, --daemon Make server act like a daemon. That means that it is going to background mode. All messages are redirected to logfiles (default: /tmp/pydav.log and /tmp/pydav.err). You need to pass one of the following values to this parameter start - Start daemon stop - Stop daemon restart - Restart complete server status - Returns status of server -v, --verbose Be verbose. -l, --loglevel Select the log level : DEBUG, INFO, WARNING, ERROR, CRITICAL Default is WARNING -h, --help Show this screen Please send bug reports and feature requests to %s """ % (VERSION, AUTHOR) def setupDummyConfig(**kw): class DummyConfigDAV: def __init__(self, **kw): self.__dict__.update(**kw) def getboolean(self, name): return (str(getattr(self, name, 0)) in ('1', "yes", "true", "on", "True")) class DummyConfig: DAV = DummyConfigDAV(**kw) return DummyConfig() def run(): verbose = False directory = '/tmp' port = 8008 host = 'localhost' noauth = False user = '' password = '' daemonize = False daemonaction = 'start' counter = 0 mysql = False lockemulation = True http_response_use_iterator = True chunked_http_response = True configfile = '' mimecheck = True loglevel = 'warning' baseurl = '' # parse commandline try: opts, args = getopt.getopt(sys.argv[1:], 'P:D:H:d:u:p:nvhmJi:c:Ml:TB:', ['host=', 'port=', 'directory=', 'user=', 'password=', 'daemon=', 'noauth', 'help', 'verbose', 'mysql', 'icounter=', 'config=', 'nolock', 'nomime', 'loglevel', 'noiter', 'baseurl=']) except getopt.GetoptError, e: print usage print '>>>> ERROR: %s' % str(e) sys.exit(2) for o,a in opts: if o in ['-i', '--icounter']: counter = int(str(a).strip()) if o in ['-m', '--mysql']: mysql = True if o in ['-M', '--nomime']: mimecheck = False if o in ['-J', '--nolock']: lockemulation = False if o in ['-T', '--noiter']: http_response_use_iterator = False chunked_http_response = False if o in ['-c', '--config']: configfile = a if o in ['-D', '--directory']: directory = a if o in ['-H', '--host']: host = a if o in ['-P', '--port']: port = a if o in ['-v', '--verbose']: verbose = True if o in ['-l', '--loglevel']: loglevel = a.lower() if o in ['-h', '--help']: print usage sys.exit(2) if o in ['-n', '--noauth']: noauth = True if o in ['-u', '--user']: user = a if o in ['-p', '--password']: password = a if o in ['-d', '--daemon']: daemonize = True daemonaction = a if o in ['-B', '--baseurl']: baseurl = a.lower() # This feature are disabled because they are unstable http_request_use_iterator = 0 conf = None if configfile != '': log.info('Reading configuration from %s' % configfile) conf = Configuration(configfile) dv = conf.DAV verbose = bool(int(dv.verbose)) loglevel = dv.get('loglevel', loglevel).lower() directory = dv.directory port = dv.port host = dv.host noauth = bool(int(dv.noauth)) user = dv.user password = dv.password daemonize = bool(int(dv.daemonize)) if daemonaction != 'stop': daemonaction = dv.daemonaction counter = int(dv.counter) lockemulation = dv.lockemulation mimecheck = dv.mimecheck if 'chunked_http_response' not in dv: dv.set('chunked_http_response', chunked_http_response) if 'http_request_use_iterator' not in dv: dv.set('http_request_use_iterator', http_request_use_iterator) if 'http_response_use_iterator' not in dv: dv.set('http_response_use_iterator', http_response_use_iterator) else: _dc = { 'verbose' : verbose, 'directory' : directory, 'port' : port, 'host' : host, 'noauth' : noauth, 'user' : user, 'password' : password, 'daemonize' : daemonize, 'daemonaction' : daemonaction, 'counter' : counter, 'lockemulation' : lockemulation, 'mimecheck' : mimecheck, 'chunked_http_response': chunked_http_response, 'http_request_use_iterator': http_request_use_iterator, 'http_response_use_iterator': http_response_use_iterator, 'baseurl' : baseurl } conf = setupDummyConfig(**_dc) if verbose and (LEVELS[loglevel] > LEVELS['info']): loglevel = 'info' logging.getLogger().setLevel(LEVELS[loglevel]) formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') for handler in logging.getLogger().handlers: handler.setFormatter(formatter) if mysql == True and configfile == '': log.error('You can only use MySQL with configuration file!') sys.exit(3) if daemonaction != 'stop': log.info('Starting up PyWebDAV server (version %s)' % VERSION) else: log.info('Stopping PyWebDAV server (version %s)' % VERSION) if not noauth and daemonaction not in ['status', 'stop']: if not user: print usage print >>sys.stderr, '>> ERROR: No parameter specified!' print >>sys.stderr, '>> Example: davserver -D /tmp -n' sys.exit(3) if daemonaction == 'status': log.info('Checking for state...') if type(port) == type(''): port = int(port.strip()) log.info('chunked_http_response feature %s' % (conf.DAV.getboolean('chunked_http_response') and 'ON' or 'OFF' )) log.info('http_request_use_iterator feature %s' % (conf.DAV.getboolean('http_request_use_iterator') and 'ON' or 'OFF' )) log.info('http_response_use_iterator feature %s' % (conf.DAV.getboolean('http_response_use_iterator') and 'ON' or 'OFF' )) if daemonize: # check if pid file exists if os.path.exists('/tmp/pydav%s.pid' % counter) and daemonaction not in ['status', 'stop']: log.error( 'Found another instance! Either use -i to specifiy another instance number or remove /tmp/pydav%s.pid!' % counter) sys.exit(3) startstop(stdout='/tmp/pydav%s.log' % counter, stderr='/tmp/pydav%s.err' % counter, pidfile='/tmp/pydav%s.pid' % counter, startmsg='>> Started PyWebDAV (PID: %s)', action=daemonaction) # start now handler = DAVAuthHandler if mysql == True: handler = MySQLAuthHandler # injecting options handler._config = conf runserver(port, host, directory, verbose, noauth, user, password, handler=handler) if __name__ == '__main__': run() davix-R_0_5_0/test/root-tests/000077500000000000000000000000001257152637300163675ustar00rootroot00000000000000davix-R_0_5_0/test/root-tests/CMakeLists.txt000066400000000000000000000020761257152637300211340ustar00rootroot00000000000000 option(ROOT_TESTS "Root functional test execution " FALSE) if(ROOT_TESTS) ## the root tests are compatibility tests with the ROOT analysis framework (http://root.cern.ch/) ## The root tests need to be compiled and executed : ## - the ROOT framework ## - a valid proxy credential for the dteam VO find_package(ROOT REQUIRED) add_definitions(-Wall) add_definitions( ${INTERN_ROOT_CONFIG_CFLAGS} -lTreePlayer) link_directories( ${ROOT_LIBRARY_DIR}) include_directories( ${ROOT_INCLUDE_DIR}) add_executable(test_event "h2fastnew_main.cpp") target_link_libraries(test_event ${ROOT_LIBRARIES} TreePlayer) function(test_root_event name url) add_test(test_root_event_${name} test_event ${url}) endfunction(test_root_event name url) ## official root website test_root_event(root_website http://root.cern.ch/files/h1big.root) ## DPM test https test_root_event(root_DPM_testbed https://lxfsra04a04.cern.ch/dpm/cern.ch/home/dteam/h1big.root) ## Dcache test http test_root_event(root_dCache_testbed http://vm-dcache-deploy6.desy.de:2881/dteam/h1big.root) endif(ROOT_TESTS) davix-R_0_5_0/test/root-tests/h2fastnew_main.cpp000066400000000000000000000034251257152637300220040ustar00rootroot00000000000000#include #include "Riostream.h" #include "TROOT.h" #include "TDavixFile.h" #include "TFile.h" #include "TNetFile.h" #include "TRandom.h" #include "TTree.h" #include "TTreeCache.h" #include "TTreePerfStats.h" #include "TBranch.h" #include "TClonesArray.h" #include "TStopwatch.h" #include "TTreeCacheUnzip.h" #include "TEnv.h" #include #include #include void h2fast(const char *url , Bool_t draw=kFALSE, Long64_t cachesize=10000000, Int_t learn=1) { // gEnv->SetValue("TFile.DavixLog", 10); // gDebug= 0x02; TStopwatch sw; TTree* T = NULL; sw.Start(); Long64_t oldb = TFile::GetFileBytesRead(); TFile *f = TFile::Open(url); if (!f || f->IsZombie()) { printf("File h1big.root does not exist\n"); exit (-1); } // TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kEnable); T= (TTree*)f->Get("h42"); Long64_t nentries = T->GetEntries(); T->SetCacheSize(cachesize); TTreeCache::SetLearnEntries(learn); TFileCacheRead *tpf = f->GetCacheRead(); //tpf->SetEntryRange(0,nentries); if (draw) T->Draw("rawtr","E33>20"); else { TBranch *brawtr = T->GetBranch("rawtr"); TBranch *bE33 = T->GetBranch("E33"); Float_t E33; bE33->SetAddress(&E33); for (Long64_t i=0;iLoadTree(i); bE33->GetEntry(i); if (E33 > 0) brawtr->GetEntry(i); } } if (tpf) tpf->Print(); printf("Bytes read = %lld\n",TFile::GetFileBytesRead()-oldb); printf("Real Time = %7.3f s, CPUtime = %7.3f s\n",sw.RealTime(),sw.CpuTime()); delete T; delete f; } int main(int argc, char** argv){ if(argc <2 ){ std::cout << "Usage: " << (char*) argv[0] << " [remote_url] " << std::endl; return -1; } h2fast(argv[1]); return 0; } davix-R_0_5_0/test/setup_test_env.sh000077500000000000000000000006141257152637300176530ustar00rootroot00000000000000#!/bin/bash MY_DIR=$(dirname $(readlink -f "$BASH_SOURCE")) ARGS="$1" export ACTION="start" if [[ "$1" == "stop" ]]; then ACTION="stop" fi OPTS_SERV_1=" -D /tmp -n -d ${ACTION} -P 8008 -i 0" OPTS_SERV_2=" -D /tmp -u test -p tester -d ${ACTION} -P 8009 -i 1" export PYTHONPATH=$MY_DIR/ $MY_DIR/pywebdav/server/server.py $OPTS_SERV_1 $MY_DIR/pywebdav/server/server.py $OPTS_SERV_2 davix-R_0_5_0/test/unit/000077500000000000000000000000001257152637300152235ustar00rootroot00000000000000davix-R_0_5_0/test/unit/CMakeLists.txt000066400000000000000000000026431257152637300177700ustar00rootroot00000000000000# main file for src if(UNIT_TESTS) include_directories(${PROJECT_SOURCE_DIR}/src "." ${GTEST_INCLUDE_DIRS}) include_directories(${HEADER_RAPIDJSON}) ## alibxx file(GLOB src_alibxx alibxx/*.cpp) file(GLOB src_neon neon/*.cpp) file(GLOB src_datetime datetime/*.cpp) file(GLOB src_credential credential/*.cpp) file(GLOB src_context context/*.cpp) file(GLOB src_session session/*.cpp) file(GLOB src_parser xmlparser/*.cpp) file(GLOB src_files files/*.cpp) file(GLOB src_auth auth/*.cpp) LIST(APPEND src_utils utils/utils_test.cpp ${SRC_STRING_UTILS_CPP}) LIST(APPEND src_parser parser/parser_test.cpp) LIST(APPEND src_httprequest sessionfactory/test_factory.cpp) add_definitions( -DTEST_VALID_CERT="${TEST_CRED_PATH}" -DTEST_VALID_CERT_PASS="${TEST_CRED_PASS}") add_executable(g_test_unit_davix_exe ${src_context} ${src_session} ${src_credential} ${src_httprequest} ${src_datetime} ${src_neon} ${src_parser} ${src_auth} ${src_utils} ${src_parser} ${SRC_BASE64} ${SRC_HMACSHA1} ${davix_tool_common_src} ${src_files} ${src_alibxx}) target_link_libraries(g_test_unit_davix_exe alibxx_core davix gtest gtest_main ${CMAKE_THREAD_LIBS_INIT} ${LIBSSL_PKG_LIBRARIES} ${Boost_LIBRARIES}) if(HAVE_CLOCK_GETTIME) target_link_libraries(g_test_unit_davix_exe rt) endif(HAVE_CLOCK_GETTIME) add_dependencies(g_test_unit_davix_exe libdavix) add_test(g_test_unit_davix g_test_unit_davix_exe ) endif(UNIT_TESTS) davix-R_0_5_0/test/unit/alibxx/000077500000000000000000000000001257152637300165125ustar00rootroot00000000000000davix-R_0_5_0/test/unit/alibxx/cache_tests.cpp000066400000000000000000000024641257152637300215110ustar00rootroot00000000000000 #include #include #include #include #undef A_LIB_NAMESPACE #define A_LIB_NAMESPACE Davix #include using namespace std; struct DummyStruct{ std::string dude; }; // instanciate and play with gates TEST(ALibxx, CacheTest){ Davix::Cache cache; ASSERT_TRUE(cache.find("hello").get() == NULL); boost::shared_ptr dumb( new DummyStruct()); dumb->dude = "bob"; ASSERT_STREQ("bob",cache.insert("hello", dumb)->dude.c_str()); ASSERT_STREQ("bob", cache.find("hello")->dude.c_str()); ASSERT_EQ(1, cache.getSize()); ASSERT_STREQ("bob", cache.take("hello")->dude.c_str()); ASSERT_EQ(0, cache.getSize()); ASSERT_TRUE(cache.find("hello").get() == NULL); ASSERT_STREQ("bob",cache.insert("alice", dumb)->dude.c_str()); ASSERT_STREQ("bob",cache.insert("test", dumb)->dude.c_str()); ASSERT_STREQ("bob",cache.insert("john", dumb)->dude.c_str()); ASSERT_STREQ("bob", cache.find("john").get()->dude.c_str()); ASSERT_EQ(3, cache.getSize()); ASSERT_TRUE(cache.erase("john")); ASSERT_FALSE(cache.erase("john")); ASSERT_EQ(2, cache.getSize()); ASSERT_TRUE( cache.find("john").get() == NULL); cache.clear(); ASSERT_EQ(0, cache.getSize()); } davix-R_0_5_0/test/unit/alibxx/chrono_tests.cpp000066400000000000000000000025141257152637300217320ustar00rootroot00000000000000#include #include #include #include #include #include #undef A_LIB_NAMESPACE #define A_LIB_NAMESPACE Davix #include using namespace std; // instanciate and play with gates TEST(ALibxx, ChronoTest){ using namespace Davix::Chrono; TimePoint pp; ASSERT_EQ(0, pp.toTimestamp()); pp = Clock(Clock::Monolitic).now(); #ifdef HAVE_CLOCK_GETTIME struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); ASSERT_GE(t.tv_sec, pp.toTimestamp()); ASSERT_LE(t.tv_sec, pp.toTimestamp()+5); #endif TimePoint copy_time = pp; ASSERT_EQ(pp, copy_time); copy_time = copy_time + Duration(5); ASSERT_NE(copy_time, pp); ASSERT_EQ(copy_time, pp + Duration(5)); ASSERT_GE(copy_time, pp); ASSERT_GE(copy_time, pp + Duration(5)); ASSERT_GT(copy_time, pp); ASSERT_LE(copy_time, pp + Duration(5)); ASSERT_LE(copy_time, pp + Duration(10)); ASSERT_LT(copy_time, pp + Duration(10)); ASSERT_EQ(copy_time + Duration(5), pp + Duration(10)); copy_time = pp; ASSERT_EQ(copy_time, pp + Duration(10) - Duration(20) + Duration(10)); TimePoint dd; ASSERT_ANY_THROW( Duration res = dd - pp; ); Duration res = pp - dd; ASSERT_EQ( dd + res, pp); } davix-R_0_5_0/test/unit/alibxx/typeconv.cpp000066400000000000000000000050251257152637300210670ustar00rootroot00000000000000 #include #include #include #include #undef A_LIB_NAMESPACE #define A_LIB_NAMESPACE Davix #include using namespace std; struct DummyStruct{ std::string dude; }; // instanciate and play with gates TEST(ALibxx, StringToULong){ using namespace Davix; std::string str_ulong("123456"); toType conv; unsigned long ul = conv(str_ulong); ASSERT_EQ(ul, 123456); str_ulong = "0"; ul= conv(str_ulong); ASSERT_EQ(ul, 0); try{ std::string str2 = "random string"; Davix::toType()(str2); FAIL(); }catch(TypeConvException & e){ // silent } try{ std::string str2 = "-15"; Davix::toType()(str2); FAIL(); }catch(TypeConvException & e){ // silent } unsigned long long super_long = std::numeric_limits::max(); std::ostringstream ss; ss << super_long; ss << super_long; // overflow try{ ul =toType()(ss.str()); FAIL(); }catch(...){ // silent } } // instanciate and play with gates TEST(ALibxx, StringToLong){ using namespace Davix; std::string str_long("123456"); toType conv; long l = conv(str_long); ASSERT_EQ(l, 123456); str_long = "0"; l= conv(str_long); ASSERT_EQ(l, 0); try{ std::string str2 = "random string"; Davix::toType()(str2); FAIL(); }catch(TypeConvException & e){ // silent } str_long = "-9865743"; l = conv(str_long); ASSERT_EQ(l, -9865743); } // instanciate and play with gates TEST(ALibxx, StringToInt){ using namespace Davix; std::string str_int("123456"); toType conv; int l = conv(str_int); ASSERT_EQ(l, 123456); str_int = "0"; l= conv(str_int); ASSERT_EQ(l, 0); try{ std::string str2 = "random string"; toType()(str2); FAIL(); }catch(TypeConvException & e){ // silent } str_int = "-9865743"; l = conv(str_int); ASSERT_EQ(l, -9865743); long long super_long = std::numeric_limits::max(); std::ostringstream ss; ss << super_long; ss << super_long; // overflow try{ l =toType()(ss.str()); FAIL(); }catch(...){ // silent } } davix-R_0_5_0/test/unit/auth/000077500000000000000000000000001257152637300161645ustar00rootroot00000000000000davix-R_0_5_0/test/unit/auth/testcert.cpp000066400000000000000000000036421257152637300205320ustar00rootroot00000000000000#include "testcert.hpp" #include #include #include #include #include using namespace std; using namespace Davix; // instanciate and play with gates TEST(CredTest, basicLoad){ DavixError* tmp_err=NULL; davix_set_log_level(DAVIX_LOG_DEBUG | DAVIX_LOG_WARNING | DAVIX_LOG_TRACE); Context c; X509Credential cred; ASSERT_FALSE(cred.hasCert()); string cert_path(TEST_VALID_CERT); string cert_pass(TEST_VALID_CERT_PASS); cout << " cred: " << cert_path << "pass " << cert_pass << endl; int ret = cred.loadFromFileP12(cert_path.c_str(), cert_pass.c_str(), &tmp_err); if(tmp_err){ cout << "err :" << tmp_err->getErrMsg() << endl; } ASSERT_EQ(0, ret); ASSERT_EQ(NULL, tmp_err); ASSERT_TRUE(cred.hasCert()); X509Credential cred2(cred); ASSERT_TRUE(cred2.hasCert()); ret = cred.loadFromFileP12("/random/stupid/path", "", &tmp_err); ASSERT_EQ(-1, ret); ASSERT_EQ(StatusCode::CredentialNotFound, tmp_err->getStatus()); DavixError::clearError(&tmp_err); ASSERT_FALSE(cred.hasCert()); ASSERT_TRUE(cred2.hasCert()); ret = cred.loadFromFileP12(cert_path.c_str(), "", &tmp_err); ASSERT_EQ(-1, ret); ASSERT_EQ(StatusCode::LoginPasswordError, tmp_err->getStatus()); DavixError::clearError(&tmp_err); } TEST(testAWS, awsToken){ std::string p_key("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"); std::string a_key("AKIAIOSFODNN7EXAMPLE"); std::string req("GET\n" "\n" "\n" "Tue, 27 Mar 2007 19:36:42 +0000\n" "/johnsmith/photos/puppy.jpg"); std::string token("AWS AKIAIOSFODNN7EXAMPLE:" "bWq2s1WEIj+Ydj0vQ697zp+IXMU="); std::string res = getAwsAuthorizationField(req, p_key, a_key); ASSERT_STREQ(res.c_str(), token.c_str()); } davix-R_0_5_0/test/unit/auth/testcert.hpp000066400000000000000000000001041257152637300205250ustar00rootroot00000000000000#ifndef TESTCERT_HPP #define TESTCERT_HPP #endif // TESTCERT_HPP davix-R_0_5_0/test/unit/context/000077500000000000000000000000001257152637300167075ustar00rootroot00000000000000davix-R_0_5_0/test/unit/context/test_context.cpp000066400000000000000000000075221257152637300221440ustar00rootroot00000000000000#include #include #include // instanciate and play with gates TEST(ContextTest, CreateDelete){ Davix::Context c1; Davix::Context* c2 = c1.clone(); ASSERT_TRUE(c2 != NULL); Davix::Context* c3 = c1.clone(); delete c2; delete c3; } TEST(RequestParametersTest, CreateDelete){ Davix::RequestParams params; ASSERT_EQ(params.getSSLCACheck(), true); ASSERT_EQ(params.getOperationTimeout()->tv_sec, DAVIX_DEFAULT_OPS_TIMEOUT); ASSERT_EQ(params.getConnectionTimeout()->tv_sec, DAVIX_DEFAULT_CONN_TIMEOUT); ASSERT_TRUE((params.getClientCertCallbackX509().second == NULL)); ASSERT_TRUE((params.getClientCertCallbackX509().first == NULL)); ASSERT_TRUE( params.getTransparentRedirectionSupport()); params.setSSLCAcheck(false); struct timespec timeout_co, timeout_ops; timeout_co.tv_sec =10; timeout_co.tv_nsec=99; timeout_ops.tv_sec=20; timeout_ops.tv_nsec=0xFF; ASSERT_EQ(params.getSSLCACheck(), false); params.setOperationTimeout(&timeout_co); ASSERT_EQ(params.getOperationTimeout()->tv_sec, 10); params.setConnectionTimeout(&timeout_ops); ASSERT_EQ(params.getConnectionTimeout()->tv_sec, 20); params.setTransparentRedirectionSupport(false); ASSERT_FALSE( params.getTransparentRedirectionSupport()); Davix::RequestParams p2(¶ms); Davix::RequestParams p3(p2); ASSERT_EQ(p2.getOperationTimeout()->tv_sec, 10); ASSERT_EQ(p3.getOperationTimeout()->tv_sec, 10); ASSERT_EQ(p2.getConnectionTimeout()->tv_sec, 20); ASSERT_EQ(p3.getConnectionTimeout()->tv_sec, 20); ASSERT_FALSE( p2.getTransparentRedirectionSupport()); Davix::RequestParams p4 = p3; // test deep copy ASSERT_EQ(p2.getOperationTimeout()->tv_sec, 10); ASSERT_EQ(p3.getOperationTimeout()->tv_sec, 10); ASSERT_EQ(p4.getConnectionTimeout()->tv_sec, 20); } TEST(RequestParametersTest, CreateDeleteDyn){ Davix::RequestParams* params = new Davix::RequestParams(); ASSERT_EQ(params->getSSLCACheck(), true); ASSERT_EQ(params->getOperationTimeout()->tv_sec, DAVIX_DEFAULT_OPS_TIMEOUT); ASSERT_EQ(params->getConnectionTimeout()->tv_sec, DAVIX_DEFAULT_CONN_TIMEOUT); ASSERT_TRUE(params->getClientCertCallbackX509().second == NULL); ASSERT_TRUE(params->getClientCertCallbackX509().first == NULL); params->setSSLCAcheck(false); struct timespec timeout_co, timeout_ops; timeout_co.tv_sec =10; timeout_co.tv_nsec=99; timeout_ops.tv_sec=20; timeout_ops.tv_nsec=0xFF; ASSERT_EQ(params->getSSLCACheck(), false); params->setOperationTimeout(&timeout_co); ASSERT_EQ(params->getOperationTimeout()->tv_sec, 10); params->setConnectionTimeout(&timeout_ops); ASSERT_EQ(params->getConnectionTimeout()->tv_sec, 20); Davix::RequestParams *p2 = new Davix::RequestParams(params); Davix::RequestParams *p3 = new Davix::RequestParams(*p2); Davix::RequestParams p4(params); Davix::RequestParams p5(*p3); ASSERT_EQ(p2->getOperationTimeout()->tv_sec, 10); ASSERT_EQ(p3->getOperationTimeout()->tv_sec, 10); ASSERT_EQ(p2->getConnectionTimeout()->tv_sec, 20); ASSERT_EQ(p3->getConnectionTimeout()->tv_sec, 20); delete params; delete p2; delete p3; } TEST(DavixErrorTest, CreateDelete){ Davix::DavixError err("test_dav_scope", Davix::StatusCode::IsNotADirectory, " problem"); ASSERT_EQ(err.getErrMsg(), " problem"); ASSERT_EQ(err.getStatus(), Davix::StatusCode::IsNotADirectory); Davix::DavixError * err2=NULL; Davix::DavixError::setupError(&err2,"test_dav_scope2", Davix::StatusCode::ConnectionProblem, "connexion problem"); ASSERT_EQ(err2->getErrMsg(), "connexion problem"); ASSERT_EQ(err2->getStatus(), Davix::StatusCode::ConnectionProblem); Davix::DavixError::clearError(&err2); Davix::DavixError::clearError(&err2); } davix-R_0_5_0/test/unit/datetime/000077500000000000000000000000001257152637300170175ustar00rootroot00000000000000davix-R_0_5_0/test/unit/datetime/test_datetime.cpp000066400000000000000000000006641257152637300223640ustar00rootroot00000000000000#include #include #include TEST(DateTimeTest, testConvert){ time_t res, t = time(NULL); struct tm* tmp = gmtime(&t); char buff[2048]; strftime(buff, 2048, "%Y-%m-%dT%H:%M:%SZ", tmp); printf("new iso8601 time %s \n",buff); res= parse_iso8601date(buff); ASSERT_EQ(t,res); res = parse_iso8601date("unknow invalid time"); ASSERT_EQ(-1, res); } davix-R_0_5_0/test/unit/files/000077500000000000000000000000001257152637300163255ustar00rootroot00000000000000davix-R_0_5_0/test/unit/files/files_test.cpp000066400000000000000000000034561257152637300212020ustar00rootroot00000000000000#include #include #include #include TEST(MetalinkReplica, HeaderMetalinkParsing){ std::string header_key, header_value, header_key_location, header_value_torrent, header_value_invalid; Davix::Uri origin("http:////lxfsra04a04.cern.ch:80/dpm/cern.ch/home/dteam/group"), origin2("https://google.com/"); Davix::Uri u; int ret = -1; header_key = "Link"; header_key_location = "Location"; header_value = "; rel=describedby; type=\"application/metalink+xml\""; header_value_torrent = "; rel=describedby; type=\"application/x-bittorrent\"; name=\"differentname.ext\""; header_value_invalid = ""; ret = Davix::davix_metalink_header_parser(header_key, header_value, origin, u); ASSERT_EQ(ret,1); ASSERT_EQ(u.getStatus(), Davix::StatusCode::OK); ASSERT_STREQ("http://lxfsra04a04.cern.ch:80/dpm/cern.ch/home/dteam/group?metalink", u.getString().c_str()); ret = Davix::davix_metalink_header_parser(header_key, header_value, origin2, u); ASSERT_EQ(ret,1); ASSERT_EQ(u.getStatus(), Davix::StatusCode::OK); ASSERT_STREQ("https://lxfsra04a04.cern.ch:80/dpm/cern.ch/home/dteam/group?metalink", u.getString().c_str()); ret = Davix::davix_metalink_header_parser(header_key, header_value_torrent, origin, u); ASSERT_EQ(ret,0); ret = Davix::davix_metalink_header_parser(header_key_location, header_value, origin, u); ASSERT_EQ(ret, 0); ret = Davix::davix_metalink_header_parser(header_key_location, header_value_invalid, origin, u); ASSERT_EQ(ret, 0); } davix-R_0_5_0/test/unit/neon/000077500000000000000000000000001257152637300161625ustar00rootroot00000000000000davix-R_0_5_0/test/unit/neon/test_neon.cpp000066400000000000000000000044511257152637300206700ustar00rootroot00000000000000#include #include #include #include #include #include using namespace Davix; static const char* list_urls[] = { "http://localhost:80/", "sfdfsdfdsfds://localhost:rrrrrrr/path", "http://monurlrandom/", "www.google.com" }; static const size_t list_port[]={ 80, 0, 0, 80 }; static const char* list_host[] ={ "localhost", "localhost", "monurlrandom", "nothing" }; static const char* list_path[] ={ "/", "/path", "/", "nothing", }; static const char* list_proto[] ={ "http", "http", "http", "nothing" }; static bool failure[]={ false, true, false, true }; const size_t len_list= (sizeof(list_proto))/(sizeof(const char*)); TEST(testNeon, testParsing){ davix_set_log_level(DAVIX_LOG_ALL); for(size_t i=0; i < len_list; ++i){ Uri uri(list_urls[i]); if(failure[i] == false){ ASSERT_EQ(StatusCode::OK, uri.getStatus()); ASSERT_STREQ(list_proto[i], uri.getProtocol().c_str() ); ASSERT_STREQ(list_host[i], uri.getHost().c_str()); ASSERT_STREQ(list_path[i], uri.getPath().c_str()); ASSERT_EQ(list_port[i], uri.getPort()); }else{ ASSERT_EQ(StatusCode::UriParsingError, uri.getStatus()); } } } TEST(testUri, testCopyEQ){ Uri uri; std::ostringstream ss; ASSERT_EQ(uri.getStatus(), StatusCode::UriParsingError); uri = Uri("http://wikipedia.org:80/bonus?salut"); ASSERT_EQ(uri.getStatus(), StatusCode::OK); ss << uri; ASSERT_STREQ(ss.str().c_str(),uri.getString().c_str()); std::string pathAndString("http://wikipedia.org:80/bonus?salut=bob"); uri = pathAndString; std::string::reverse_iterator rit = std::find(pathAndString.rbegin(), pathAndString.rend(), '/'); std::string::iterator it = pathAndString.begin() + (pathAndString.rend() - rit); ASSERT_STREQ(uri.getPathAndQuery().c_str(), std::string(it-1, pathAndString.end()).c_str() ); Uri uri2(uri); ASSERT_TRUE(uri == uri2); } TEST(testUri, testEscape){ std::string s("http://wikipedia.org:80/bonus a toi \\ é voilù ?salut"); std::string r = Davix::Uri::unescapeString(Davix::Uri::escapeString(s)); ASSERT_STREQ(s.c_str(), r.c_str()); } davix-R_0_5_0/test/unit/parser/000077500000000000000000000000001257152637300165175ustar00rootroot00000000000000davix-R_0_5_0/test/unit/parser/parser_test.cpp000066400000000000000000000606641257152637300215720ustar00rootroot00000000000000#include "parser_test.hpp" #include #include #include #include #include #include #include #include #include #include using namespace Davix; char normal_vector_range_cstr[] = "2894597227-2894599011,2894600789-2894601667,2894616262-2894617140,2894619865-2894623464,2906287380-2906491436,2907014445-2907025728,2907228889-2907232035,2913226796-2913239685,2913337799-2913538354," "2920341488-2920341660,2920376486-2920376595,2920377869-2920377987,2920398615-2920398721,2920400327-2920400537,2920407068-2920407263,2920534929-2920547408,2921309945-2921313091,2921314945-2921315052,2921353972-29" "21354079,2921355415-2921355519,2921381888-2921382006,2921385811-2921385927,2921386275-2921386384,2923832488-2923835417,2923842762-2923845463,2924345912-2924347518,2924350009-2924351321,2924382902-2924383512,2924" "429449-2924432057,2924516324-2924530870,2924556078-2924561911,2924634939-2924667831,2924698529-2924708631,2924718737-2924738719,2924778907-2924800458,2924878902-2924889766,2924898497-2924907906,2925060054-292507" "1537,2925082948-2925094376,2925120965-2925136938,2925148273-2925158039,2925178780-2925189684,2925374210-2925385276,2925801184-2925810640,2925970960-2926032309,2926283634-2926317832,2926329105-2926340581,29265320" "22-2926541735,2926546946-2926552967,2926597986-2926610425,2926638816-2926644264,2926651300-2926658488,2926813925-2926848245,2927386412-2927397410,2933217130-2933259050,2933262387-2933302854,2933329834-2933334347" ",2933338835-2933343477,2933349022-2933358181,2933365316-2933466065,2933626155-2933770574,2933848103-2933862205,2933917894-2933955396,2934057518-2934258138,2935669360-2935844362,2935849059-2935877127,2935879476-2" "935885804,2935908849-2935941795,2935944191-2936003068,2936005415-2936088351,2936197558-2936205691,2936213456-2936221551,2936225112-2936228755,2936247929-2936256670,2936263673-2936280963,2940282303-2940294386,294" "4698750-2945205175,2945396985-2945397107,2945766398-2945766731,2945775515-2945780462,2946147455-2946150395,2946230445-2946234636,2946241098-2946252531,2946282324-2946298429,2946436685-2946452956,2946532686-29465" "36848,2946641704-2946673847,2946760945-2946793165,2946920499-2946924499,2947274177-2947275056,2947277728-2947279512,2947281290-2947282168,2947296763-2947297641,2947300366-2947303965,2958286340-2958492725,2959848059-2959860798" ",2959958124-2959961270,2966061833-2966074209,2966170876-2966372789,2973222698-2973222869,2973257655-2973257764,2973259043-2973259152,2973279662-2973279768,2973281374-2973281589,2973288114-2973288312,2973318356-2973328837,2973425694-2973428840," "2976471316-2976474220,2976481466-2976484169,2976983761-2976985381,2976987860-2976989172,2977019939-2977020545,2977064174-2977066750,2977146792-2977160755,2977185134-2977190682,2977262055-2977293837,2977323593-2977333439," "2977343224-2977362718,2977401793-2977422570,2977498630-2977509169,2977517744-2977526878,2977675930-2977687013,2977698033-2977709079,2977734868-2977750346,2977761310-2977770807,2977790863-2977801395,2977978772-2977989474,2978389575-2978398709," "2978552485-2978610681,2978850242-2978883265,2978894197-2978905293,2979090337-2979099769,2979104869-2979110654,2979154473-2979166708,2979194475-2979199737,2979206487-2979213303,2979363203-2979396434,2979916534-2979927163,2985820683-2985863430,2985866696-2985907937,2985935195-2985939801,2985944387-2985949123,2985954606-2985963642,2985970585-2986073297,2986244661-2986391877,2986471584-2986486117,2986542589-2986580155,2986682014-2986886459,2988278869-2988447401,2988452088-2988479695,2988482035-2988488170,2988510304-2988542091,2988544463-2988601553,2988603898-2988684202,2988788984-2988796734,2988804177-2988811923,2988815352-2988818817,2988837573-2988845953,2988852643-2988869416,2992871574-2992883478,2996506775-2996965110,2997190827-2997190949,2997548560-2997548924,2997557956-2997563036,2997937427-2997941053,2998021650-2998025988,2998032525-2998044002,2998073943-2998090372,2998232114-2998248632,2998327934-2998332159,2998438036-2998470383,2998558645-2998591384,2998720455-2998724414,2999082210-2999083089,2999085761-2999087545,2999089323-2999090201,2999104796-2999105674,2999108399-2999111998, 2694452992-2694465611,2746390592-2746402250,2798560058-2798571419,2804195110-2804400838,2805751552-2805762858,2805859068-2805862214,2811940340-2811950464,2812046764-2812251087,2813703640-2813703814," "2819114229-2819114338,2819115652-2819115761,2819136413-2819136519,2819138125-2819138337,2819144814-2819145015,2819174973-2819186728,2819283826-2819286972,2819288838-2819288945,2819327826-2819327933,2819329269-28" "19329373,2819355743-2819355871,2819359717-2819359834,2819360180-2819360297,2821830034-2821832958,2821840349-2821843110,2822362368-2822363981,2822366454-2822367777,2822397860-2822398458,2822440809-2822443382,2822" "521209-2822534994,2822558999-2822564556,2822635102-2822666100,2822695336-2822705027,2822714640-2822733567,2822771618-2822791908,2822866132-2822876379,2822884625-2822893492,2823041407-2823052245,2823062999-282307" "3783,2823098969-2823114083,2823124792-2823134031,2823153653-2823163909,2823338124-2823348557,2823738948-2823747837,2823898889-2823955268,2824190305-2824222631,2824233317-2824244161,2824425048-2824434424,28244394" "86-2824445166,2824488577-2824500792,2824528659-2824533870,2824540565-2824547393,2824694274-2824726649,2825235071-2825245434,2831022985-2831065125,2831068370-2831108767,2831135652-2831140188,2831144741-2831149437" ",2831154915-2831163895,2831170853-2831272511,2831440783-2831586337,2831665263-2831679584,2831735448-2831773114,2831873965-2832075890,2833445981-2833611751,2833616420-2833643532,2833645857-2833651889,2833673852-2" "833705305,2833707683-2833764157,2833766480-2833845088,2833947916-2833955670,2833963034-2833970747,2833974199-2833977678,2833996116-2834004435,2834011055-2834027584,2837963479-2837975148,2841911291-2842391545,284" "2581999-2842582121,2842937329-2842937678,2842946394-2842951289,2843325409-2843329045,2843408591-2843412887,2843419493-2843431179,2843461534-2843478329,2843621898-2843638611,2843718479-2843722767,2843830205-28438" "63003,2843952215-2843985337,2844117237-2844121570,2844474125-2844475004,2844477676-2844479460,2844481238-2844482116,2844496711-2844497589,2844500314-2844503913,2849752576-2849764487,2855338133-2855542823,2856891" "989-2856907940,2863121983-2863135646,2863232633-2863431065,2864879845-2864880018,2864915167-2864915280,2864916579-2864916688,2864937365-2864937471,2864939077-2864939290,2864945837-2864946035,2870336419-287035218" "1,2870354035-2870354142,2870393010-2870393117,2870394453-2870394557,2870420895-2870421012"; char singular_vector_range_cstr[] = "2894597227-2894599011,2894600789-2894601667,2894616262-2894617140,2894619865-2894623464,2906287380-2906491436,2907014445-2907025728,2907228889-2907232035,2913226796-2913239685,2913337799-2913538354," "2920341488-2920341660,2920376486-2920376595,2920377869-2920377987,2920398615-2920398721,2920400327-2920400537,2920407068-2920407263,2920534929-2920547408,2921309945-2921313091,2921314945-2921315052,2921353972-29" "21354079,2921355415-2921355519,2921381888-2921382006,2921385811-2921385927,2921386275-2921386384,2923832488-2923835417,2923842762-2923845463,2924345912-2924347518,2924350009-2924351321,2924382902-2924383512,2924" "429449-2924432057,2924516324-2924530870,2924556078-2924561911,2924634939-2924667831,2924698529-2924708631,2924718737-2924738719,2924778907-2924800458,2924878902-2924889766,2924898497-2924907906,2925060054-292507" "1537,2925082948-2925094376,2925120965-2925136938,2925148273-2925158039,2925178780-2925189684,2925374210-2925385276,2925801184-2925810640,2925970960-2926032309,2926283634-2926317832,2926329105-2926340581,29265320" "22-2926541735,2926546946-2926552967,2926597986-2926610425,2926638816-2926644264,2926651300-2926658488,2926813925-2926848245,2927386412-2927397410,2933217130-2933259050,2933262387-2933302854,2933329834-2933334347" ",2933338835-2933343477,2933349022-2933358181,2933365316-2933466065,2933626155-2933770574,2933848103-2933862205,2933917894-2933955396,2934057518-2934258138,2935669360-2935844362,2935849059-2935877127,2935879476-2" "935885804,2935908849-2935941795,2935944191-2936003068,2936005415-2936088351,2936197558-2936205691,2936213456-2936221551,2936225112-2936228755,2936247929-2936256670,2936263673-2936280963,2940282303-2940294386,294" "4698750-2945205175,2945396985-2945397107,2945766398-2945766731,2945775515-2945780462,2946147455-2946150395,2946230445-2946234636,2946241098-2946252531,2946282324-2946298429,2946436685-2946452956,2946532686-29465" "36848,2946641704-2946673847,2946760945-2946793165,2946920499-2946924499,2947274177-2947275056,2947277728-2947279512,2947281290-2947282168,2947296763-2947297641,2947300366-2947303965,2958286340-2958492725,2959848059-2959860798" ",2959958124-2959961270,2966061833-2966074209,2966170876-2966372789,2973222698-2973222869,2973257655-2973257764,2973259043-2973259152,2973279662-2973279768,2973281374-2973281589,2973288114-2973288312,2973318356-2973328837,2973425694-2973428840," "2976471316-2976474220,2976481466-2976484169,2976983761-2976985381,2976987860-2976989172,2977019939-2977020545,2977064174-2977066750,2977146792-2977160755,2977185134-2977190682,2977262055-2977293837,2977323593-2977333439," "2977343224-2977362718,2977401793-2977422570,2977498630-2977509169,2977517744-2977526878,2977675930-2977687013,2977698033-2977709079,2977734868-2977750346,2977761310-2977770807,2977790863-2977801395,2977978772-2977989474,2978389575-2978398709," "2978552485-2978610681,2978850242-2978883265,2978894197-2978905293,2979090337-2979099769,2979104869-2979110654,2979154473-2979166708,2979194475-2979199737,2979206487-2979213303,2979363203-2979396434,2979916534-2979927163,2985820683-2985863430,2985866696-2985907937,2985935195-2985939801,2985944387-2985949123,2985954606-2985963642,2985970585-2986073297,2986244661-2986391877,2986471584-2986486117,2986542589-2986580155,2986682014-2986886459,2988278869-2988447401,2988452088-2988479695,2988482035-2988488170,2988510304-2988542091,2988544463-2988601553,2988603898-2988684202,2988788984-2988796734,2988804177-2988811923,2988815352-2988818817,2988837573-2988845953,2988852643-2988869416,2992871574-2992883478,2996506775-2996965110,2997190827-2997190949,2997548560-2997548924,2997557956-2997563036,2997937427-2997941053,2998021650-2998025988,2998032525-2998044002,2998073943-2998090372,2998232114-2998248632,2998327934-2998332159,2998438036-2998470383,2998558645-2998591384,2998720455-2998724414,2999082210-2999083089,2999085761-2999087545,2999089323-2999090201,2999104796-2999105674,2999108399-2999111998, 2694452992-2694465611,2746390592-2746402250,2798560058-2798571419,2804195110-2804400838,2805751552-2805762858,2805859068-2805862214,2811940340-2811950464,2812046764-2812251087,2813703640-2813703814," "2819114229-2819114338,2819115652-2819115761,2819136413-2819136519,2819138125-2819138337,2819144814-2819145015,2819174973-2819186728,2819283826-2819286972,2819288838-2819288945,2819327826-2819327933,2819329269-28" "19329373,2819355743-2819355871,2819359717-2819359834,2819360180-2819360297,2821830034-2821832958,2821840349-2821843110,2822362368-2822363981,2822366454-2822367777,2822397860-2822398458,2822440809-2822443382,2822" "521209-2822534994,2822558999-2822564556,2822635102-2822666100,2822695336-2822705027,2822714640-2822733567,2822771618-2822791908,2822866132-2822876379,2822884625-2822893492,2823041407-2823052245,2823062999-282307" "3783,2823098969-2823114083,2823124792-2823134031,2823153653-2823163909,2823338124-2823348557,2823738948-2823747837,2823898889-2823955268,2824190305-2824222631,2824233317-2824244161,2824425048-2824434424,28244394" "86-2824445166,2824488577-2824500792,2824528659-2824533870,2824540565-2824547393,2824694274-2824726649,2825235071-2825245434,2831022985-2831065125,2831068370-2831108767,2831135652-2831140188,2831144741-2831149437" ",2831154915-2831163895,2831170853-2831272511,2831440783-2831586337,2831665263-2831679584,2831735448-2831773114,2831873965-2832075890,2833445981-2833611751,2833616420-2833643532,2833645857-2833651889,2833673852-2" "833705305,2833707683-2833764157,2833766480-2833845088,2833947916-2833955670,2833963034-2833970747,2833974199-2833977678,2833996116-2834004435,2834011055-2834027584,2837963479-2837975148,2841911291-2842391545,284" "2581999-2842582121,2842937329-2842937678,2842946394-2842951289,2843325409-2843329045,2843408591-2843412887,2843419493-2843431179,2843461534-2843478329,2843621898-2843638611,2843718479-2843722767,2843830205-28438" "63003,2843952215-2843985337,2844117237-2844121570,2844474125-2844475004,2844477676-2844479460,2844481238-2844482116,2844496711-2844497589,2844500314-2844503913,2849752576-2849764487,2855338133-2855542823,2856891" "989-2856907940,2863121983-2863135646,2863232633-2863431065,2864879845-2864880018,2864915167-2864915280,2864916579-2864916688,2864937365-2864937471,2864939077-2864939290,2864945837-2864946035,2870336419-287035218" "1,2870354035-2870354142,2870393010-2870393117,2870394453-2870394557,2870420895-2870421012,2870424812-2870424933,2870425283-2870425398,2872897076-2872899957,2872907320-2872910179,2873421207-2873422827,2873425312-" "2873426624,2873459902-2873460505,2873501613-2873504138,2873579634-2873593015,2873616270-2873621691,2873690666-2873720736,2873749003-2873758321,2873767613-2873785919,2873822523-2873842126,2873914014-2873923939,28" "73932161-2873940985,2874086014-2874096421,2874106823-2874117213,2874141572-2874156207,2874166520-2874175394,2874194283-2874204212,2874372723-2874382807,2874761523-2874770206,2874918539-2874973443,2875202781-2875" "234075,2875244393-2875254892,2875429805-2875438930,2875443796-2875449344,2875491430-2875503320,2875530432-2875535526,2875541928-2875548496,2875690125-2875721370,2876213600-2876223621,2881893880-2881936152,288193" "9433-2881980116,2882007211-2882011755,2882016296-2882021005,2882026484-2882035590,2882042577-2882144346,2882313188-2882459082,2882537928-2882552213,2882608291-2882645978,2882747765-2882950560,2884257342-28844154" "78,2884420113-2884446503,2884448822-2884454634,2884475526-2884505692,2884508048-2884562124,2884564433-2884639476,2884735800-2884743363,2884750668-2884758224,2884761726-2884765245,2884783598-2884791660,2884798311" "-2884814319,2888674449-2888686751,2892050274-2892515560,2892708900-2892709022,2893068732-2893069081,2893077811-2893082715,2893451044-2893454294,2893534657-2893538912,2893545469-2893557026,2893587035-2893603411,2" "893744017-2893760682,2893840332-2893844616,2893950557-2893982883,2894070929-2894103592,2894232130-2894235963,2894593676-2894594555"; int parse_range(std::istringstream & stream, size_t & n, dav_off_t & begin, dav_off_t & end){ std::string part; char trash; if(stream.eof()) return -1; std::getline(stream, part, ','); std::istringstream ss(part); ss >> begin; ss >> trash; ss >> end; std::cout << "range: " << begin << " " << end << std::endl; return ++n; } // with this number of element, the result will be exactly 178 *2 = 356 elems // regression test for LCGUTIL-456 TEST(IOVecMultiPartPaser, generateSingularRangeTest){ using namespace boost; std::string singular_vector_range(singular_vector_range_cstr); std::istringstream stream(singular_vector_range); size_t n =0; OffsetCallback generator_range( boost::bind(&parse_range, boost::ref(stream), boost::ref(n), _1, _2)); std::vector< std::pair > res = generateRangeHeaders(3900, generator_range); ASSERT_EQ(356, n); ASSERT_EQ(2, res.size()); for(std::vector >::iterator it = res.begin(); it < res.end(); ++it){ ASSERT_EQ(178, it->first); ASSERT_LE(5, it->second.size()); } } // with this number of element, the result will be exactly 178 *2 = 356 elems // regression test for LCGUTIL-456 TEST(IOVecMultiPartPaser, generateNormalRangeTest){ using namespace boost; std::string singular_vector_range(normal_vector_range_cstr); std::istringstream stream(singular_vector_range); size_t n =0; OffsetCallback generator_range( boost::bind(&parse_range, boost::ref(stream), boost::ref(n), _1, _2)); std::vector< std::pair > res = generateRangeHeaders(3900, generator_range); ASSERT_EQ(287, n); ASSERT_EQ(2, res.size()); std::pair e = res.at(0); ASSERT_EQ(178, e.first); ASSERT_LE(5, e.second.size()); e = res.at(1); ASSERT_EQ(287-178, e.first); ASSERT_LE(5, e.second.size()); } TEST(IOVecMultiPartParser, headerParser){ std::string header; dav_size_t size; dav_off_t offset; header = "Content-type: application/xml"; // random generic header int ret = find_header_params((char*) header.c_str(), header.size(), &size, &offset); ASSERT_EQ(ret,0); header = "big brother is wathing you"; ret = find_header_params((char*) header.c_str(), header.size(), &size, &offset); ASSERT_EQ(ret,-1); header = "Content-Range: bytes 600-900/8000"; ret = find_header_params((char*) header.c_str(), header.size(), &size, &offset); ASSERT_EQ(1,ret); ASSERT_EQ(301, size); ASSERT_EQ(600, offset); header = "conTent-range: bytes 600-900/8000"; // break case ret = find_header_params((char*) header.c_str(), header.size(), &size, &offset); ASSERT_EQ(1,ret); ASSERT_EQ(301, size); ASSERT_EQ(600, offset); header = "conTent-range: bytes 600ssss-9e00/8000"; // break case ret = find_header_params((char*) header.c_str(), header.size(),&size, &offset); ASSERT_EQ(ret,-1); header = "Content-Range: GalaticCreditStandard 600-900/8000"; ret = find_header_params((char*) header.c_str(), header.size(), &size, &offset); ASSERT_EQ(-1,ret); } TEST(IOVecMultiPartParser, BoundaryExtract){ std::string header, boundary; DavixError* tmp_err = NULL; header = " multipart/mixed; boundary=gc0p4Jq0M2Yt08jU534c0p"; int ret = http_extract_boundary_from_content_type(header, boundary, &tmp_err); ASSERT_EQ(0,ret ); ASSERT_STREQ(boundary.c_str(), "gc0p4Jq0M2Yt08jU534c0p"); ASSERT_EQ(NULL, tmp_err); boundary = ""; header = " multipart/mixed; boundary="; ret = http_extract_boundary_from_content_type(header, boundary, &tmp_err); ASSERT_EQ(-1,ret ); ASSERT_TRUE(tmp_err != NULL); DavixError::clearError(&tmp_err); boundary = ""; header = " multipart/mixed; boundary=\"helloworld\""; ret = http_extract_boundary_from_content_type(header, boundary, &tmp_err); ASSERT_EQ(0,ret ); ASSERT_STREQ(boundary.c_str(), "helloworld"); ASSERT_EQ(NULL, tmp_err); boundary = ""; header = " multipart/mixed; boundary=helloworld; some trash strng"; ret = http_extract_boundary_from_content_type(header, boundary, &tmp_err); ASSERT_EQ(0,ret ); ASSERT_STREQ(boundary.c_str(), "helloworld"); ASSERT_EQ(NULL, tmp_err); } TEST(IOVecMultiPartParser, BoundaryPart){ std::string boundary, part; DavixError* tmp_err = NULL; boundary = "gc0p4Jq0M2Yt08jU534c0p"; part = "--gc0p4Jq0M2Yt08jU534c0p"; bool ret = is_a_start_boundary_part((char*) part.c_str(), part.size(), boundary, &tmp_err); ASSERT_TRUE(ret ); ASSERT_EQ(NULL, tmp_err); boundary = "gc0p4Jq0M2Yt08jU534c0p"; part = "--++gc0p4Jq0M2Yt08jU534c0p"; ret = is_a_start_boundary_part((char*) part.c_str(), part.size(), boundary, &tmp_err); ASSERT_FALSE(ret); ASSERT_TRUE(tmp_err != NULL); DavixError::clearError(&tmp_err); } int numb_it=0; static int callback_offset_stupid(dav_off_t & begin, dav_off_t & end){ begin = numb_it*1000+100; end=numb_it*1000+500; numb_it++; if(numb_it > 1000) return -1; return 0; } TEST(headerParser, generateRange){ std::string header; const dav_size_t max_header_size = rand()%8000+30; OffsetCallback o(callback_offset_stupid); std::vector > ranges; ranges = generateRangeHeaders(max_header_size, o); std::cout << " ranges size " << ranges.size() << std::endl; for(std::vector > ::iterator it = ranges.begin(); it < ranges.end(); it++){ ASSERT_LE(it->second.size(), max_header_size+20); ASSERT_GE(it->first, 1); std::cout << "NRange: " << (*it).first << std::endl; std::cout << "Range: " << (*it).second << std::endl; } ASSERT_LE(2, ranges.size()); } // JSON parser tutorial test TEST(ParserJSONTestTuto, JSONTuto){ //////////////////////////////////////////////////////////////////////////// // 1. Parse a JSON text string to a document. const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } "; //printf("Original JSON:\n %s\n", json); rapidjson::Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator. #if 0 // "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream(). if (document.Parse<0>(json).HasParseError()) ASSERT_TRUE(false); #else // In-situ parsing, decode strings directly in the source string. Source must be string. char buffer[sizeof(json)]; memcpy(buffer, json, sizeof(json)); if (document.ParseInsitu<0>(buffer).HasParseError()) ASSERT_TRUE(false); #endif // printf("\nParsing to document succeeded.\n"); } // JSON parser tutorial test TEST(ParserJSONTestTuto, JSONReplicaParsing){ //////////////////////////////////////////////////////////////////////////// // 1. Parse a JSON text string to a document. const char json[] = "[" "{" "\"server\" : \"datagrid.lbl.gov\"," "\"rfn\" : \"http://datagrid.lbl.gov/testdata//R/test01.data\"," "\"atime\" : 1384793007," "\"status\" : \"-\"," "\"type\" : \"V\"," "\"ltime\" : 1385397803," "\"extra\": {}" "}" "]"; //printf("Original JSON:\n %s\n", json); rapidjson::Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator. #if 0 // "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream(). if (document.Parse<0>(json).HasParseError()) ASSERT_TRUE(false); #else // In-situ parsing, decode strings directly in the source string. Source must be string. char buffer[sizeof(json)]; memcpy(buffer, json, sizeof(json)); if (document.ParseInsitu<0>(buffer).HasParseError()) ASSERT_TRUE(false); #endif //printf("\nParsing to replicas with success. \n"); ASSERT_TRUE(document.IsArray()); ASSERT_EQ(document.Size(),1); ASSERT_TRUE(document[static_cast(0)].IsObject()); ASSERT_FALSE(document[static_cast(0)].HasMember("test_random")); ASSERT_TRUE(document[static_cast(0)].HasMember("rfn")); ASSERT_STREQ("http://datagrid.lbl.gov/testdata//R/test01.data", document[static_cast(0)]["rfn"].GetString()); ASSERT_STREQ("datagrid.lbl.gov", document[static_cast(0)]["server"].GetString()); } // JSON parser tutorial test TEST(UriTests, testRelativeUri){ Davix::Uri u("http://datagrid.lbl.gov/testdata/R/test01.data"); std::string proto_rel("//example.org/test"), abs_path("/hello/world/"), rel_path("blabla/test"); Davix::Uri res = Uri::fromRelativePath(u, proto_rel); ASSERT_EQ(StatusCode::OK, res.getStatus()); ASSERT_STREQ("http://example.org/test", res.getString().c_str()); res = Uri::fromRelativePath(u, abs_path); ASSERT_EQ(StatusCode::OK, res.getStatus()); ASSERT_STREQ("http://datagrid.lbl.gov/hello/world/", res.getString().c_str()); res = Uri::fromRelativePath(u, rel_path); ASSERT_EQ(StatusCode::OK, res.getStatus()); ASSERT_STREQ("http://datagrid.lbl.gov/testdata/R/test01.data/blabla/test", res.getString().c_str()); } davix-R_0_5_0/test/unit/parser/parser_test.hpp000066400000000000000000000001171257152637300215620ustar00rootroot00000000000000#ifndef PARSER_TESTS_HPP #define PARSER_TESTS_HPP #endif // PARSER_TESTS_HPP davix-R_0_5_0/test/unit/request/000077500000000000000000000000001257152637300167135ustar00rootroot00000000000000davix-R_0_5_0/test/unit/request/test_request.cpp000066400000000000000000000040261257152637300221500ustar00rootroot00000000000000 #include #include #include #include #include "test_request.h" using namespace Davix; void test_request_chunk(){ // prepare local files char* tmp_file = tempnam(NULL, "test_file_request_"); const char * content = "Hello"; const size_t times = 4000; FILE* f = fopen(tmp_file, "w+"); if(f == NULL){ assert_true_with_message(FALSE, " unable to create tmp_file"); return; } for(size_t i=0; i < times; ++i){ fwrite(content, strlen(content), 1, f); } fseek(f, 0,SEEK_SET); try{ char buffer[6000]; // original data const size_t s_read=20; std::auto_ptr s( new NEONSessionFactory()); std::string tmp_file_url("file:///"); tmp_file_url.append(tmp_file); std::cout << " file url :" << tmp_file_url << std::endl; Request* r(s->create_request(tmp_file_url)); char v[6000]; r->execute_block(); ssize_t n = r->read_block(v,s_read); v[n] = '\0'; fread(buffer,1,s_read, f); buffer[s_read] = '\0'; assert_true_with_message(strncmp(buffer, v, s_read) ==0 , "must be the same content %s | %s", buffer,v); const size_t s_read2 = 60; memset(v, 0, 6000); n= r->read_block(v, s_read2); v[n] = '\0'; fread(buffer,1,s_read2, f); buffer[s_read2] = '\0'; assert_true_with_message(strncmp(buffer, v, s_read2) ==0 , "must be the same content %s %s 2 ", buffer, v); s->delete_request(r); }catch(Glib::Error & e){ assert_true_with_message(FALSE, " error occures : N° %d %s", e.code(), e.what().c_str()); }catch(std::exception & e){ assert_true_with_message(FALSE, " unknow error occures : %s", e.what()); } free(tmp_file); fclose(f); } TestSuite * request_suite (void) { TestSuite *s2 = create_test_suite(); // verbose test case / add_test(s2, test_request_chunk); return s2; } davix-R_0_5_0/test/unit/session/000077500000000000000000000000001257152637300167065ustar00rootroot00000000000000davix-R_0_5_0/test/unit/session/test_session.cpp000066400000000000000000000005051257152637300221340ustar00rootroot00000000000000 #include #include #include #include TEST(SessionTest, create_session){ Davix_error * tmp_err=NULL; Davix::Context c; Davix::Context* ctxt = new Davix::Context(); ASSERT_TRUE(ctxt != NULL); ASSERT_TRUE(tmp_err==NULL); delete ctxt; } davix-R_0_5_0/test/unit/sessionfactory/000077500000000000000000000000001257152637300202765ustar00rootroot00000000000000davix-R_0_5_0/test/unit/sessionfactory/test_factory.cpp000066400000000000000000000062031257152637300235110ustar00rootroot00000000000000#include #include #include using namespace Davix; TEST(testRedirectCache, testCacheSimple){ davix_set_log_level(DAVIX_LOG_ALL); boost::shared_ptr dest(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf")); boost::shared_ptr dest2(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf")); Uri u("http://higgs.boson/is/watchingus"); Uri u_sec("https://higgs.boson/is/watchingus"); Uri u_port("http://higgs.boson:8668/is/watchingus"); NEONSessionFactory f; f.addRedirection("GET", u, dest); ASSERT_TRUE(f.redirectionResolve("GET", u) == dest); ASSERT_TRUE(f.redirectionResolve("GET", u_sec).get() == NULL); ASSERT_TRUE(f.redirectionResolve("GET", u_port).get() == NULL); // add redirection f.addRedirection("GET", u_port, dest2); ASSERT_TRUE(f.redirectionResolve("GET", u) != dest2); ASSERT_TRUE(f.redirectionResolve("GET", u_port) == dest2); // remove redirection f.redirectionClean("GET", u); ASSERT_TRUE(f.redirectionResolve("GET", u).get() == NULL); ASSERT_TRUE(f.redirectionResolve("GET", u_port) == dest2); } TEST(testRedirectCache, testCacheChainRedirection){ davix_set_log_level(DAVIX_LOG_ALL); Uri u("http://higgs.boson/is/watchingus"); boost::shared_ptr url1(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf")); boost::shared_ptr url2(new Uri("http://server2.com/dsffds/sfdfdsfsdfdsfdsfds")); boost::shared_ptr url3(new Uri("http://server2.com:8080/dsffds/sfdfdsfsdfdsfdsfds")); boost::shared_ptr url4(new Uri("http://server3.com/dsffds/fsdaaaaa")); NEONSessionFactory f; f.addRedirection("GET", u, url1); f.addRedirection("GET",*url1, url2); f.addRedirection("GET", *url2, url3); f.addRedirection("GET", *url3, url4); ASSERT_TRUE(f.redirectionResolve("GET", u) == url4); ASSERT_TRUE(f.redirectionResolve("GET", *url2) == url4); f.redirectionClean("GET", u); ASSERT_TRUE(f.redirectionResolve("GET", u).get() == NULL); ASSERT_TRUE(f.redirectionResolve("GET", *url2).get() == NULL); ASSERT_TRUE(f.redirectionResolve("GET", *url4).get() == NULL); } TEST(testRedirectCache, test_GET_HEAD){ davix_set_log_level(DAVIX_LOG_ALL); Uri u("http://higgs.boson/is/watchingus"); boost::shared_ptr url1(new Uri("http://sffsdfsd.com/dsffds/fsdfsdsdf")); boost::shared_ptr url2(new Uri("http://server2.com/dsffds/sfdfdsfsdfdsfdsfds")); NEONSessionFactory f; f.addRedirection("GET", u, url1); ASSERT_TRUE(f.redirectionResolve("GET", u) == url1); ASSERT_TRUE(f.redirectionResolve("HEAD", u) == url1); ASSERT_TRUE(f.redirectionResolve("PUT", u).get() == NULL); f.redirectionClean("GET", u); ASSERT_TRUE(f.redirectionResolve("GET", u) == NULL); ASSERT_TRUE(f.redirectionResolve("HEAD", u) == NULL); f.addRedirection("PUT", u, url1); ASSERT_TRUE(f.redirectionResolve("GET", u).get() == NULL); ASSERT_TRUE(f.redirectionResolve("PUT", u) == url1); f.addRedirection("HEAD", u, url1); ASSERT_TRUE(f.redirectionResolve("GET", u) == url1); ASSERT_TRUE(f.redirectionResolve("HEAD", u) == url1); } davix-R_0_5_0/test/unit/utils/000077500000000000000000000000001257152637300163635ustar00rootroot00000000000000davix-R_0_5_0/test/unit/utils/utils_test.cpp000066400000000000000000000132501257152637300212670ustar00rootroot00000000000000#include "utils_test.hpp" #include #include #include #include #include #include #include using namespace std; using namespace Davix; using namespace StrUtil; TEST(StringUtils, splitok){ std::string str, delimiter; str= "hello world test"; delimiter= " "; std::vector res = tokenSplit(str, delimiter); ASSERT_EQ(3, res.size()); ASSERT_STREQ("hello", res.at(0).c_str()); str=" bytes 0-90/15872 \t"; delimiter="bytes -/\t"; res = tokenSplit(str, delimiter); ASSERT_EQ(3, res.size()); ASSERT_STREQ("0", res.at(0).c_str()); ASSERT_STREQ("90", res.at(1).c_str()); ASSERT_STREQ("15872", res.at(2).c_str()); str = " Obi;wan Kenobi.droid*pass$*"; delimiter=" ;.*$ù^°="; res = tokenSplit(str, delimiter); ASSERT_EQ(5, res.size()); ASSERT_STREQ("Obi", res.at(0).c_str()); ASSERT_STREQ("Kenobi", res.at(2).c_str()); } TEST(testBase64, cmpbase){ size_t s_buff= rand()%100000; char buff_input[s_buff]; for(size_t i = 0; i < s_buff; i++) buff_input[i]= (char) rand()%255; std::string conv = Base64::base64_encode((unsigned char*)buff_input, s_buff); // std::cout << conv << std::endl; std::string res= Base64::base64_decode(conv); ASSERT_EQ(s_buff, res.length()); ASSERT_TRUE( memcmp(buff_input, res.c_str(), s_buff) == 0); } TEST(testhmacsha1, testhmac){ const std::string data("obi wan kenobi"); const std::string key("bob dylan"); const std::string result("337a4432486ea5a175c35ed1a138d6f9dd481f15"); const std::string prod = hmac_sha1(key, data); std::ostringstream ss; ss << std::hex << prod; ASSERT_STREQ(prod.c_str(), ss.str().c_str()); } TEST(testS3, test_hash_s3){ const std::string key= "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"; const std::string str("GET\n" "\n" "\n" "Tue, 27 Mar 2007 19:36:42 +0000\n" "/johnsmith/photos/puppy.jpg"); const std::string res("bWq2s1WEIj+Ydj0vQ697zp+IXMU="); const std::string hmac_str = hmac_sha1(key,str); const std::string prod = Base64::base64_encode((unsigned char*) hmac_str.c_str(), hmac_str.size()); std::cout << "hash : " << prod << std::endl; ASSERT_STREQ(res.c_str(), prod.c_str()); } TEST(testStringMode, test_mode){ mode_t m = 0755; string m_str = Tool::string_from_mode(m); //std::cout << m_str << std::endl; ASSERT_STREQ("-rwxr-xr-x", m_str.c_str()); m = 040777; m_str = Tool::string_from_mode(m); ASSERT_STREQ("drwxrwxrwx", m_str.c_str()); } TEST(testAuthS3, ReqToSign){ RequestParams params; Uri url("http://johnsmith.s3.amazonaws.com/photos/puppy.jpg"); params.setAwsAuthorizationKeys("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "AKIAIOSFODNN7EXAMPLE"); HeaderVec vec; vec.push_back(std::pair("Date", "Tue, 27 Mar 2007 19:36:42 +0000")); S3::signRequest(params, "GET", url, vec); ASSERT_EQ(std::string("Authorization"),vec.at(1).first); ASSERT_EQ(std::string("AWS AKIAIOSFODNN7EXAMPLE:bWq2s1WEIj+Ydj0vQ697zp+IXMU="),vec.at(1).second); } TEST(testAuthS3, ReqToSignAWS){ RequestParams params; Uri url("http://static.johnsmith.net:8080/db-backup.dat.gz"); params.setAwsAuthorizationKeys("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "AKIAIOSFODNN7EXAMPLE"); HeaderVec vec; vec.push_back(HeaderLine("Date", "Tue, 27 Mar 2007 21:06:08 +0000")); vec.push_back(HeaderLine("x-amz-acl","public-read")); vec.push_back(HeaderLine("X-Amz-Meta-ReviewedBy", "joe@johnsmith.net,jane@johnsmith.net")); vec.push_back(HeaderLine("X-Amz-Meta-FileChecksum","0x02661779")); vec.push_back(HeaderLine("X-Amz-Meta-ChecksumAlgorithm", "crc32")); vec.push_back(HeaderLine("Content-Disposition","attachment; filename=database.dat")); vec.push_back(HeaderLine("Content-Encoding","gzip")); vec.push_back(HeaderLine("Content-Length","5913339")); S3::signRequest(params, "PUT", url, vec); ASSERT_EQ(std::string("Authorization"),vec.back().first); ASSERT_EQ(std::string("AWS AKIAIOSFODNN7EXAMPLE:mRp45AGRkcT9u0ssDHIkjUqmPWk="),vec.back().second); } TEST(testAuthS3, ReqToToken){ RequestParams params; Uri url("http://johnsmith.s3.amazonaws.com/photos/puppy.jpg"); params.setAwsAuthorizationKeys("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "AKIAIOSFODNN7EXAMPLE"); HeaderVec vec; Uri u = S3::tokenizeRequest(params, "GET", url, vec, static_cast(1175139620UL)); Uri resu("http://johnsmith.s3.amazonaws.com/photos/puppy.jpg?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=NpgCjnDzrM%2BWFzoENXmpNDUsSn8%3D&Expires=1175139620"); ASSERT_TRUE(StrUtil::compare_ncase(resu.getString(), u.getString()) ==0); } TEST(testAuthS3, ReqToTokenWithHeaders){ RequestParams params; Uri url("http://firwen-bucket.s3.amazonaws.com/testfile1234"); params.setAwsAuthorizationKeys("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "AKIAIOSFODNN7EXAMPLE"); HeaderVec vec; vec.push_back(HeaderLine("x-amz-meta-fed-acl", "adevress : rwx, furano : rwx")); Uri u = S3::tokenizeRequest(params, "PUT", url, vec, static_cast(1415835686)); Uri resu("http://firwen-bucket.s3.amazonaws.com/testfile1234?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=8DnY/3Te1GOcC01S6BGNHZErJMo%3d&Expires=1415835686&x-amz-meta-fed-acl=adevress%20%3a%20rwx%2c%20furano%20%3a%20rwx"); std::cout << u << "\n" << resu << std::endl; ASSERT_TRUE(StrUtil::compare_ncase(resu.getString(), u.getString()) ==0); } davix-R_0_5_0/test/unit/utils/utils_test.hpp000066400000000000000000000001711257152637300212720ustar00rootroot00000000000000#ifndef UTILS_TEST_HPP #define UTILS_TEST_HPP class utils_test { public: utils_test(); }; #endif // UTILS_TEST_HPP davix-R_0_5_0/test/unit/xmlparser/000077500000000000000000000000001257152637300172405ustar00rootroot00000000000000davix-R_0_5_0/test/unit/xmlparser/test_parser.cpp000066400000000000000000000675521257152637300223160ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include const char* simple_stat_propfind_content = "" "" "" "/pnfs/desy.de/data/dteam/" "" "" "2012-10-22T07:50:51Z" "Mon, 22 Oct 2012 07:50:51 GMT" "dteam" "" "" "text/html" "000033743EFFCFC64360A82A6B0A814C2C87_-2022446850" "" "HTTP/1.1 200" "" "" ""; const char* simple_bad_content_http = "lkfsdlkfdsklmkmlkmlsfdoiretopôiptrefdlzeamllvmg" "sfdfsjgsdmbkmlbkl,,klmd848486468+4666666666666666" "sfdfsjgsdmbkmlbkl,,klmd848486468+4666666666666666" "sfdfsjgsdmbkmlbkl,,klmd848486468+4666666666666666" "sfdfsjgsdmbkmlbkl,,klmd848486468+4666666666666666" "sfdfsjgsdmbkmlbkl,,klmd848486468+4666666666666666"; const char* recursive_listing = " " " " " /pnfs/desy.de/data/dteam/" " " " " " 2012-10-22T10:50:46Z" " Mon, 22 Oct 2012 10:50:46 GMT" " dteam" " " " " " text/html" " 000033743EFFCFC64360A82A6B0A814C2C87_-2011651620" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/g2/" " " " " " 2012-10-22T01:14:23Z" " Mon, 22 Oct 2012 01:14:23 GMT" " g2" " " " " " text/html" " 000071F56A6971D444C6B923205B8A6C8B5B_-2046234581" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/generated/" " " " " " 2011-12-19T09:48:58Z" " Mon, 19 Dec 2011 09:48:58 GMT" " generated" " " " " " text/html" " 0000CF0EFBD2343E45099A3664C9E52A5035_1438212009" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/test/" " " " " " 2012-03-23T14:14:35Z" " Fri, 23 Mar 2012 14:14:35 GMT" " test" " " " " " text/html" " 00002EBC0878E36B43FE98754FC725CFFA59_1072213609" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/speed_test2/" " " " " " 2012-03-23T15:58:26Z" " Fri, 23 Mar 2012 15:58:26 GMT" " speed_test2" " " " " " text/html" " 000001C9BF5FAA6740F2BCFD7F9454C7CEF0_1078444680" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/speed_test/" " " " " " 2012-03-23T15:44:47Z" " Fri, 23 Mar 2012 15:44:47 GMT" " speed_test" " " " " " text/html" " 000003C8148BB6574B03820B3953A1E09E3E_1077625629" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/speed_test3/" " " " " " 2012-03-23T16:55:34Z" " Fri, 23 Mar 2012 16:55:34 GMT" " speed_test3" " " " " " text/html" " 0000C0F214B189464616B08D01F540445829_1081872745" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/testwrite" " " " " " 2012-03-23T16:47:11Z" " Fri, 23 Mar 2012 16:47:11 GMT" " testwrite" " 65536" " 0000DA13494AE9764029BE48D6D264AF2E0C_1081369798" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/test_dir/" " " " " " 2012-05-24T16:22:28Z" " Thu, 24 May 2012 16:22:28 GMT" " test_dir" " " " " " text/html" " 000066C9BA492C3440E081A6CF0A75479B98_2141719820" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/testgfgfgfdg9999tw3" " " " " " 2012-07-13T13:25:01Z" " Fri, 13 Jul 2012 13:25:02 GMT" " testgfgfgfdg9999tw3" " 187" " 0000AF211A13EC96400393F4769AC24CD82F_-2138860744" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/UGRtest/" " " " " " 2012-07-19T14:50:51Z" " Thu, 19 Jul 2012 14:50:51 GMT" " UGRtest" " " " " " text/html" " 00009BF2D07746D14CB4BEB74097309AB707_-1615312788" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/ugrtest/" " " " " " 2012-07-19T14:53:42Z" " Wed, 25 Jul 2012 10:01:02 GMT" " ugrtest" " " " " " text/html" " 0000D40132559B244F7597EDB2EAE617D56B_-1114301154" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/fbxtest.txt" " " " " " 2012-07-19T14:38:31Z" " Thu, 19 Jul 2012 14:38:33 GMT" " fbxtest.txt" " text/plain" " 640999" " 00004769A9ACEB1647EF8C8D6298FE1D5909_-1616050534" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/testdir/" " " " " " 2012-07-19T14:39:05Z" " Thu, 19 Jul 2012 14:39:05 GMT" " testdir" " " " " " text/html" " 0000CA3E0FFC5E684F639541654D7FD99B72_-1616018106" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/testdir8888/" " " " " " 2012-07-19T14:39:16Z" " Thu, 19 Jul 2012 14:39:16 GMT" " testdir8888" " " " " " text/html" " 0000BFDBF3DE079E407F92396F58D65FE656_-1616006747" " " " HTTP/1.1 200" " " " " " " " /pnfs/desy.de/data/dteam/testdir8889/" " " " " " 2012-07-19T14:51:35Z" " Thu, 19 Jul 2012 14:51:35 GMT" " testdir8889" " " " " " text/html" " 0000DB00326864EC43529E1CE8137A4F9A00_-1615267437" " " " HTTP/1.1 200" " " " " " "; const char * caldav_item = "" "/dteam/Wed, 18 Dec 2013 14:41:52 GMTdteam2013-12-18T14:41:52ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/foo2.txt12Sat, 16 Jul 2011 17:03:02 GMTfoo2.txt2011-07-16T17:03:02ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/foo.txt12Sat, 16 Jul 2011 06:30:51 GMTfoo.txt2011-07-16T06:30:51ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/EA-check-file-N_1-13112628794440Thu, 21 Jul 2011 15:41:19 GMTEA-check-file-N_1-13112628794442011-07-21T15:41:19ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/fpalapzorp1286144Wed, 14 Sep 2011 11:43:41 GMTfpalapzorp2011-09-14T11:43:41ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/EA-check-file-N_1-13141259875900Tue, 23 Aug 2011 18:59:47 GMTEA-check-file-N_1-13141259875902011-08-23T18:59:47ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/somefilename1286144Wed, 14 Sep 2011 14:16:03 GMTsomefilename2011-09-14T14:16:03ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found/dteam/generatedSat, 26 Feb 2011 14:39:48 GMTgenerated2011-02-26T14:39:48ZHTTP/1.1 200 OKHTTP/1.1 404 Not Found"; const char* list_item[] = { "g2", "generated", "test", "speed_test2", "speed_test", "speed_test3", "testwrite", "test_dir", "testgfgfgfdg9999tw3", "UGRtest", "ugrtest", "fbxtest.txt", "testdir", "testdir8888", "testdir8889" }; const char metalink_item_lcgdm[] = "" "" "" "" " 494391600" " " " http://datagrid.lbl.gov/testdata//L/test02.data" " " "" "" ""; const char metalink_item_generic[]= " " "" " " " " " " " example-md5-hash" " example-sha1-hash" " " " " " ftp://ftp.example1.com/example.ext" " ftp://ftp.example2.com/example.ext" " http://www.example1.com/example.ext " " http://www.example2.com/example.ext" " http://www.example3.com/example.ext " " http://www.ex.com/example.ext.torrent" " " " " " " " " " " " "; const std::string s3_xml_response = "a-random-random-bucket1000falseh1big.root2014-09-19T14:27:33.000Z"bf5b1efa7fe677965bf3ecd41e20be2a"280408881STANDARDmhellmicMartin Hellmichservices2014-10-03T14:58:12.000Z"3e73cc5c77799fd3e7a02c62474107bb"\t 19558 \tSTANDARDmhellmicMartin Hellmich"; TEST(XmlParserInstance, createParser){ ASSERT_NO_THROW({ Davix::XMLSAXParser * parser = new Davix::XMLSAXParser(); delete parser; }); } TEST(XmlParserInstance, parseOneStat){ davix_set_log_level(DAVIX_LOG_ALL); Davix::DavPropXMLParser parser; ASSERT_NO_THROW({ int ret = parser.parseChunk(simple_stat_propfind_content, strlen(simple_stat_propfind_content)); if( ret !=0){ ASSERT_TRUE(false); } ASSERT_EQ(1u, parser.getProperties().size()); parser.parseChunk(NULL, 0); ASSERT_EQ(1u, parser.getProperties().size()); Davix::FileProperties f = parser.getProperties().at(0); ASSERT_TRUE(S_ISDIR(f.info.mode)); ASSERT_FALSE(S_ISLNK(f.info.mode)); ASSERT_STREQ("dteam",f.filename.c_str()); //q ASSERT_EQ(f.mtime, 1350892251L); }); } TEST(XMLParserInstance,ParseList){ ASSERT_NO_THROW({ Davix::DavPropXMLParser parser; int ret = parser.parseChunk(recursive_listing, strlen(recursive_listing)); if( ret !=0){ ASSERT_TRUE(false); } ASSERT_EQ(16u, parser.getProperties().size()); parser.parseChunk(NULL, 0); ASSERT_EQ(16u, parser.getProperties().size()); // test the parent directory stats Davix::FileProperties f = parser.getProperties().at(0); ASSERT_TRUE(S_ISDIR(f.info.mode)); ASSERT_FALSE(S_ISLNK(f.info.mode)); ASSERT_STREQ("dteam",f.filename.c_str()); for(int i =1; i < 16; ++i){ Davix::FileProperties f_local = parser.getProperties()[i]; ASSERT_STREQ(list_item[i-1], f_local.filename.c_str()); ASSERT_TRUE( f_local.info.size > 0 || S_ISDIR(f.info.mode)); } // test the children stats }); } TEST(XMLParserInstance, ParseCalDav){ ASSERT_NO_THROW({ davix_set_log_level(DAVIX_LOG_ALL); Davix::DavPropXMLParser parser; int ret = parser.parseChunk(caldav_item, strlen(caldav_item)); if( ret !=0){ ASSERT_TRUE(false); } ASSERT_GT(parser.getProperties().size(),0); }); } TEST(XmlParserInstance,parserNonWebdav){ Davix::DavPropXMLParser parser; try{ parser.parseChunk(simple_bad_content_http, strlen(simple_bad_content_http)); parser.parseChunk(NULL, 0); ASSERT_TRUE(false); }catch(Davix::DavixException & e){ std::cerr << "error : " << e.what(); ASSERT_EQ(0u, parser.getProperties().size()); ASSERT_TRUE(Davix::StatusCode::OK != e.code()); ASSERT_EQ(Davix::StatusCode::WebDavPropertiesParsingError, e.code()); } } TEST(XmlPaserInstance, destroyPartial){ davix_set_log_level(DAVIX_LOG_ALL); Davix::DavPropXMLParser* parser = new Davix::DavPropXMLParser(); ASSERT_NO_THROW({ int ret = parser->parseChunk(simple_stat_propfind_content, strlen(simple_stat_propfind_content)/2); if( ret !=0){ ASSERT_TRUE(false); } // destroy the parser with still parsing on the stack }); delete parser; } TEST(XmlMetalinkParserTest, parserMetalinkSimpl){ ASSERT_NO_THROW({ Davix::Context c; std::vector r; Davix::MetalinkParser parser(c, r); int ret = parser.parseChunk(metalink_item_lcgdm, strlen(metalink_item_lcgdm)); ASSERT_EQ(0, ret); ASSERT_EQ(1, r.size()); Davix::Uri u = r[0].getUri(); ASSERT_EQ(Davix::StatusCode::OK, u.getStatus()); ASSERT_STREQ("http://datagrid.lbl.gov/testdata//L/test02.data", u.getString().c_str()); ASSERT_EQ(494391600, parser.getSize()); }); } TEST(XmlMetalinkParserTest, parserMetalinkGeneric){ ASSERT_NO_THROW({ Davix::Context c; std::vector r; Davix::MetalinkParser parser(c, r); int ret = parser.parseChunk(metalink_item_generic, strlen(metalink_item_generic)); //std::cout << parser.getLastErr()->getErrMsg(); ASSERT_EQ(0, ret); // const Davix::Properties& p = parser.getProps(); ASSERT_EQ(8, r.size()); Davix::Uri u = r[0].getUri(); ASSERT_EQ(Davix::StatusCode::OK, u.getStatus()); ASSERT_STREQ("ftp://ftp.example1.com/example.ext", u.getString().c_str()); u = r[1].getUri(); ASSERT_STREQ("ftp://ftp.example2.com/example.ext", u.getString().c_str()); ASSERT_STREQ("ftp",u.getProtocol().c_str()); }); } TEST(XmlPTreeTest, testPTreeBase){ using namespace Davix::Xml; XmlPTree base(Attribute,"start", XmlPTree::ChildrenList(1, XmlPTree(Attribute, "hello", XmlPTree::ChildrenList(1, XmlPTree(CData, "BoB"))))); XmlPTree baseItem(Attribute, "start"); XmlPTree randomItem(Attribute, "no"); XmlPTree elem1(CData, "1"), elem2(CData, "2"), elemBob(CData, "BoB"); XmlPTree::ChildrenList l; l.push_back(elem1); l.push_back(elem2); l.push_back(elemBob); XmlPTree hello(Attribute, "hello", l), nihao(Attribute, "你好", XmlPTree::ChildrenList(1, elem1)); XmlPTree tree(Attribute, "start", XmlPTree::ChildrenList(1, hello)); ASSERT_TRUE( base.compareKey(baseItem)); ASSERT_TRUE( baseItem.compareKey(randomItem)); ASSERT_TRUE(base.compareNode(baseItem)); ASSERT_FALSE( randomItem.compareNode(baseItem)); ASSERT_FALSE(elemBob.compareNode(elem1)); ASSERT_TRUE( tree.matchTree(base)); ASSERT_FALSE( base.matchTree(tree)); ASSERT_FALSE( tree.matchTree(nihao)); } TEST(XmlPTreeTest, testPTreeChain){ using namespace Davix::Xml; XmlPTree base(Attribute,"start", XmlPTree::ChildrenList(1, XmlPTree(Attribute, "hello", XmlPTree::ChildrenList(1, XmlPTree(CData, "BoB"))))); XmlPTree baseItem(Attribute, "start"); XmlPTree randomItem(Attribute, "no"); XmlPTree helloItem(Attribute, "hello"); XmlPTree bobItem(CData, "BoB"); std::vector vec_node; std::vector res; res = base.findChain(vec_node); ASSERT_EQ(0, res.size()); vec_node.clear(); vec_node.push_back(baseItem); res = base.findChain(vec_node); ASSERT_EQ(1, res.size()); ASSERT_TRUE(res.at(0)->compareNode(baseItem)); ASSERT_EQ(res.at(0), &(base)); vec_node.clear(); // invalid nodes vec_node.push_back(randomItem); res = base.findChain(vec_node); ASSERT_EQ(0, res.size()); vec_node.clear(); vec_node.push_back(baseItem); vec_node.push_back(helloItem); vec_node.push_back(bobItem); res = base.findChain(vec_node); ASSERT_EQ(3, res.size()); ASSERT_TRUE(res.at(0)->compareNode(baseItem)); ASSERT_TRUE(res.at(1)->compareNode(helloItem)); ASSERT_TRUE(res.at(2)->compareNode(bobItem)); ASSERT_EQ(res.at(0), &(base)); ASSERT_EQ(res.at(1), &(*base.beginChildren())); ASSERT_EQ(res.at(2), &(*base.beginChildren()->beginChildren())); vec_node.clear(); vec_node.push_back(base); res = baseItem.findChain(vec_node); ASSERT_EQ(1, res.size()); ASSERT_TRUE(res.at(0)->compareNode(baseItem)); vec_node.clear(); } TEST(XmlS3parsing, TestListingBucket){ using namespace Davix; davix_set_log_level(DAVIX_LOG_ALL); S3PropParser parser; int ret = parser.parseChunk(s3_xml_response); ASSERT_EQ(ret, 0); ASSERT_EQ(3, parser.getProperties().size()); // verify name ASSERT_EQ(std::string("a-random-random-bucket"), parser.getProperties().at(0).filename); ASSERT_EQ(std::string("h1big.root"), parser.getProperties().at(1).filename); ASSERT_EQ(std::string("services"), parser.getProperties().at(2).filename); // verify size ASSERT_EQ(280408881, parser.getProperties().at(1).info.size); ASSERT_EQ(19558, parser.getProperties().at(2).info.size); }