diff --git a/build/depends.py b/build/depends.py index 9d5efa2293f..1663efb8c2b 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1304,7 +1304,7 @@ def sources(self, build): 'preferences/dialog/dlgprefvinyldlg.ui', 'preferences/dialog/dlgprefwaveformdlg.ui', ] - map(Qt.uic(build), ui_files) + list(map(Qt.uic(build), ui_files)) if build.platform_is_windows: # Add Windows resource file with icons and such diff --git a/build/features.py b/build/features.py index 1a7bfe1ccc0..2ed32cb5254 100644 --- a/build/features.py +++ b/build/features.py @@ -812,14 +812,32 @@ def enabled(self, build): def add_options(self, build, vars): vars.Add('shoutcast', 'Set to 1 to enable live broadcasting support', 1) + vars.Add('shoutcast_internal', 'Set to 1 to use internal libshout', 0) def configure(self, build, conf): if not self.enabled(build): return - libshout_found = conf.CheckLib(['libshout', 'shout']) build.env.Append(CPPDEFINES='__BROADCAST__') + build.flags['shoutcast_internal'] = util.get_flags(build.env, 'shoutcast_internal', 0) + if build.platform_is_linux and not int(build.flags['shoutcast_internal']): + # Check if system lib is lower 2.4.2 or 2.4.3 and not suffering bug + # https://bugs.launchpad.net/mixxx/+bug/1833225 + if not conf.CheckForPKG('shout', '2.4.3'): + if conf.CheckForPKG('shout', '2.4.2'): + print("System's libshout 2.4.2 suffers lp1833225, using internal shout_mixxx") + build.flags['shoutcast_internal'] = 1 + else: + print("(no) here is fine here we just don't want 2.4.2") + + if int(build.flags['shoutcast_internal']): + build.env.Append(CPPPATH='include') + build.env.Append(CPPPATH='src') + return + + libshout_found = conf.CheckLib(['libshout', 'shout']) + if not libshout_found: raise Exception('Could not find libshout or its development headers. Please install it or compile Mixxx without Shoutcast support using the shoutcast=0 flag.') @@ -829,6 +847,26 @@ def configure(self, build, conf): conf.CheckLib('gdi32') def sources(self, build): + if int(build.flags['shoutcast_internal']): + # Clone our main environment so we don't change any settings in the + # Mixxx environment + libshout_env = build.env.Clone() + + if build.toolchain_is_gnu: + libshout_env.Append(CCFLAGS='-pthread') + libshout_env.Append(LINKFLAGS='-pthread') + + libshout_env.Append(CPPPATH="#lib/libshout") + libshout_dir = libshout_env.Dir("#lib/libshout") + + env = libshout_env + SCons.Export('env') + SCons.Export('build') + env.SConscript(env.File('SConscript', libshout_dir)) + + build.env.Append(LIBPATH=libshout_dir) + build.env.Append(LIBS=['shout_mixxx', 'ogg', 'vorbis', 'theora', 'speex', 'ssl', 'crypto']) + depends.Qt.uic(build)('preferences/dialog/dlgprefbroadcastdlg.ui') return ['preferences/dialog/dlgprefbroadcast.cpp', 'broadcast/broadcastmanager.cpp', diff --git a/lib/libshout/COPYING b/lib/libshout/COPYING new file mode 100644 index 00000000000..92b8903ff3f --- /dev/null +++ b/lib/libshout/COPYING @@ -0,0 +1,481 @@ + 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 + + 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 + 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! diff --git a/lib/libshout/HACKING b/lib/libshout/HACKING new file mode 100644 index 00000000000..3187e8d5d5a --- /dev/null +++ b/lib/libshout/HACKING @@ -0,0 +1,48 @@ +Note that these instructions are *not* necessary for distribution +tarballs; they have separate configure/build instructions. + +Building this package from subversion is mainly intended for developers. +General users should obtain official distribution packages; both +source and binary distributions are available at +http://www.icecast.org/ + +----- + +These are *brief* instructions on how to build this package from subversion. +Yes, there are details left out. + +There are generally four steps necessary when building from subversion (i.e., +a developer's copy): + +1. svn checkout of the sources, or svn update. RTFM from your + favorite flavor of svn documentation; information on the xiph.org + svn repository can be found at http://www.xiph.org/svn/. + +2. [re-]generate files such as "configure" and "Makefile.in" with the + GNU autoconf/automake tools. Run the "autogen.sh" script to + perform this step. + + *** IF YOU ARE NOT BUILDING WITH GNU MAKE *AND* GCC: you must set + the AUTOMAKE_FLAGS environment variable to "--include-deps" + before running autogen.sh. For example: + + csh% setenv AUTOMAKE_FLAGS --include-deps + csh% ./autogen.sh + or + sh% AUTOMAKE_FLAGS=--include-deps ./autogen.sh + +3. Run configure. There are several options available; see + "./configure --help" for more information. + +4. Run "make" to build the source. + +In general, steps 2 and 3 need to be re-run every time any of the +following files are modified (either manually or by a svn update): + + configure.in + m4/* + +Running "make clean" after running steps 2 and 3 is generally also +advisable before running step 4. It isn't *always* necessary, but +unless you understand the workings of autoconf/automake, it's safest +to just do it. diff --git a/lib/libshout/INSTALL b/lib/libshout/INSTALL new file mode 100644 index 00000000000..c285b16973a --- /dev/null +++ b/lib/libshout/INSTALL @@ -0,0 +1,41 @@ +Prerequisites +------------- + +libvorbis +libogg + +Both of these libraries must be installed before you can build +libshout. If they aren't available in your OS's package system, you +can find them at vorbis.com. You may also want libtheora if you're +interested in doing video streaming. + +Building +-------- + +Normally, just ./configure; make + +You may need to specify --with-ogg-prefix and/or --with-vorbis-prefix +if you have installed those libraries in a non-standard +location. The arguments to these will match the --prefix you used when +configuring ogg and vorbis, respectively. + +You may also choose to build libshout without thread safety, with the +--disable-pthread argument to configure. Only do this if you know you +will never be using the library in a threaded application, or if you +intend to make all calls to libshout threadsafe by hand in your +calling application. + +Installation +------------ +(as root) make install + +This will install header files in $(prefix)/shout and library files in +$(prefix)/lib. + +configure will have detected whether or not you have pkg-config +automatically. If you have, it will place a pkg-config data file in +$(prefix)/lib/pkgconfig, otherwise it will place a shout-config script +in $(prefix)/bin. You can force libshout to use shout-config instead +of pkgconfig with the configure option --disable-pkgconfig. + +$Id$ diff --git a/lib/libshout/Makefile.am b/lib/libshout/Makefile.am new file mode 100644 index 00000000000..3974a2b801d --- /dev/null +++ b/lib/libshout/Makefile.am @@ -0,0 +1,30 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = 1.6 foreign +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = include src examples doc win32 + +EXTRA_DIST = INSTALL m4/shout.m4 m4/acx_pthread.m4 \ + m4/ogg.m4 m4/vorbis.m4 m4/xiph_compiler.m4 m4/xiph_net.m4 \ + m4/xiph_types.m4 libshout.ckport + +docdir = $(datadir)/doc/$(PACKAGE) +doc_DATA = COPYING NEWS README examples/example.c examples/nonblocking.c + +m4datadir = $(datadir)/aclocal +m4data_DATA = m4/shout.m4 + +ckportdir = $(libdir)/ckport/db +ckport_DATA = libshout.ckport + +if HAVE_PKGCONFIG + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = shout.pc +endif + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" diff --git a/lib/libshout/NEWS b/lib/libshout/NEWS new file mode 100644 index 00000000000..144c7a01159 --- /dev/null +++ b/lib/libshout/NEWS @@ -0,0 +1,49 @@ +libshout 2.4.1 (20151120) + +* Fixed issue with missing file in distribution + +libshout 2.4.0 (20151111) + +* Audio only WebM support. +* Protocol level meta data support improved. + Some API calls got replaced and marked as obsolete. +* Code hardened. +* Fixed overlinking. +* Removed Debian packaging. +* TLS support (RFC2818 and RFC2817, mode can be autodetected). +* Improved HTTP protocol: + * Set Host:-header (vhosting), + * Check for server capabilities. +* Basic support for RoarAudio protocol. + +libshout 2.3.1 (20120525) + +* Opus support + +libshout 2.3.0 (20120201) + +* Rough WebM support +* removed the shout-config script + +libshout 2.2.2 (20060619) + +* Handle Oggs that don't begin with zero granulepos. +* Install header in correct location (broken in 2.2.1). +* Theora memory leak fix. +* Non-blocking shout_open was failing unnecessarily in the + connect_pending state. +* Cast some size_ts to ints for display purposes. + +libshout 2.2.1 (20060417) + +* Fix error handling while opening a connection, so that shout_open + can be retried. +* pkgconfig fix for header installation +* Fix a memory leak in HTTP authentication + +libshout 2.2 (20060103) + +* Speex support +* Fix a double-free bug when login fails +* More robust server response parser +* Theora timing fix diff --git a/lib/libshout/README b/lib/libshout/README new file mode 100644 index 00000000000..785b3dbfdea --- /dev/null +++ b/lib/libshout/README @@ -0,0 +1,20 @@ +libshout +-------- + +Libshout is a library for communicating with and sending data to an +icecast server. It handles the socket connection, the timing of the +data, and prevents bad data from getting to the icecast server. + +With just a few lines of code, a programmer can easily turn any application +into a streaming source for an icecast server. Libshout also allows +developers who want a specific feature set (database access, request taking) +to concentrate on that feature set, instead of worrying about how server +communication works. + +Please refer to the api reference and example code to start learning how to +use libshout in your own code. + +Libshout is licensed under the LGPL. Please see the COPYING file for details. + +If you have any questions or comments, please visit us at +http://www.icecast.org or email us at team@icecast.org. diff --git a/lib/libshout/SConscript b/lib/libshout/SConscript new file mode 100644 index 00000000000..7502884e098 --- /dev/null +++ b/lib/libshout/SConscript @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +Import('env') +env = env.Clone() + +libshout_sources = [ + 'src/common/avl/avl.c', + 'src/common/net/sock.c', + 'src/common/net/resolver.c', + 'src/common/timing/timing.c', + 'src/common/httpp/httpp.c', + 'src/common/httpp/encoding.c', + 'src/common/thread/thread.c', + 'src/shout.c', + 'src/util.c', + 'src/queue.c', + 'src/proto_http.c', + 'src/proto_xaudiocast.c', + 'src/proto_icy.c', + 'src/proto_roaraudio.c', + 'src/format_ogg.c', + 'src/format_webm.c', + 'src/format_mp3.c', + 'src/codec_vorbis.c', + 'src/codec_opus.c', + 'src/codec_theora.c', + 'src/codec_speex.c', + 'src/tls.c' +] + +env.Append(CPPDEFINES='HAVE_CONFIG_H') +env.Append(CPPPATH='src/common') +env.Append(CPPPATH='include') + +env.StaticLibrary(target='libshout_mixxx', source=libshout_sources) diff --git a/lib/libshout/autogen.sh b/lib/libshout/autogen.sh new file mode 100755 index 00000000000..1ba99817cc3 --- /dev/null +++ b/lib/libshout/autogen.sh @@ -0,0 +1,116 @@ +#!/bin/sh +# Run this to set up the build system: configure, makefiles, etc. +# (based on the version in enlightenment's cvs) + +package="libshout" + +olddir=`pwd` +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +cd "$srcdir" +DIE=0 + +echo "checking for autoconf... " +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9]\.[0-9]*\).*/\1/" +VERSIONMKINT="sed -e s/[^0-9]//" + +# do we need automake? +if test -r Makefile.am; then + AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am` + AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP` + if test "$AM_NEEDED" = "$AM_OPTIONS"; then + AM_NEEDED="" + fi + if test -z $AM_NEEDED; then + echo -n "checking for automake... " + AUTOMAKE=automake + ACLOCAL=aclocal + if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then + echo "yes" + else + echo "no" + AUTOMAKE= + fi + else + echo -n "checking for automake $AM_NEEDED or later... " + for am in automake-$AM_NEEDED automake$AM_NEEDED automake; do + ($am --version < /dev/null > /dev/null 2>&1) || continue + ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP | $VERSIONMKINT` + verneeded=`echo $AM_NEEDED | $VERSIONMKINT` + if test $ver -ge $verneeded; then + AUTOMAKE=$am + echo $AUTOMAKE + break + fi + done + test -z $AUTOMAKE && echo "no" + echo -n "checking for aclocal $AM_NEEDED or later... " + for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED aclocal; do + ($ac --version < /dev/null > /dev/null 2>&1) || continue + ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP | $VERSIONMKINT` + verneeded=`echo $AM_NEEDED | $VERSIONMKINT` + if test $ver -ge $verneeded; then + ACLOCAL=$ac + echo $ACLOCAL + break + fi + done + test -z $ACLOCAL && echo "no" + fi + test -z $AUTOMAKE || test -z $ACLOCAL && { + echo + echo "You must have automake installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + exit 1 + } +fi + +echo -n "checking for libtool... " +for LIBTOOLIZE in libtoolize glibtoolize nope; do + ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break +done +if test x$LIBTOOLIZE = xnope; then + echo "nope." + LIBTOOLIZE=libtoolize +else + echo $LIBTOOLIZE +fi +($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have libtool installed to compile $package." + echo "Download the appropriate package for your system," + echo "or get the source from one of the GNU ftp sites" + echo "listed in http://www.gnu.org/order/ftp.html" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +echo "Generating configuration files for $package, please wait...." + +ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4" +echo " $ACLOCAL $ACLOCAL_FLAGS" +$ACLOCAL $ACLOCAL_FLAGS || exit 1 +echo " autoheader" +autoheader || exit 1 +echo " $LIBTOOLIZE --automake" +$LIBTOOLIZE --automake || exit 1 +echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS" +$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1 +echo " autoconf" +autoconf || exit 1 + +cd $olddir +#$srcdir/configure "$@" && echo diff --git a/lib/libshout/config.h b/lib/libshout/config.h new file mode 100644 index 00000000000..74cd3290dc7 --- /dev/null +++ b/lib/libshout/config.h @@ -0,0 +1,217 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ 1 + +/* Define if you have the C99 integer types */ +#define HAVE_C99_INTTYPES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `endhostent' function. */ +#define HAVE_ENDHOSTENT 1 + +/* Define to 1 if you have the `ftime' function. */ +#define HAVE_FTIME 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +#define HAVE_GETADDRINFO 1 + +/* Define if you have the getnameinfo function */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the `inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the nanosleep function */ +#define HAVE_NANOSLEEP 1 + +/* Define if you have libogg installed */ +#define HAVE_OGG 1 + +/* Define if you have libopenssl. */ +#define HAVE_OPENSSL 1 + +/* Define if you have POSIX threads libraries and header files. */ +/* #undef HAVE_PTHREAD */ + +/* Define to 1 if you have the `pthread_spin_lock' function. */ +#define HAVE_PTHREAD_SPIN_LOCK 1 + +/* Define if you have the sethostent function */ +#define HAVE_SETHOSTENT 1 + +/* Define to 1 if the system has the type `socklen_t'. */ +#define HAVE_SOCKLEN_T 1 + +/* Define if you want speex streams supported */ +#define HAVE_SPEEX 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIMEB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you want theora streams supported */ +#define HAVE_THEORA 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have winsock2.h on MINGW */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the `writev' function. */ +#define HAVE_WRITEV 1 + +/* Shout library major version */ +#define LIBSHOUT_MAJOR 2 + +/* Shout library patch version */ +#define LIBSHOUT_MICRO 1 + +/* Shout library minor version */ +#define LIBSHOUT_MINOR 4 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define if you don't want to use the thread library */ +/* #undef NO_THREAD */ + +/* Name of package */ +#define PACKAGE "libshout" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "icecast-dev@xiph.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libshout" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libshout 2.4.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libshout" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.4.1" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* 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 `short', as computed by sizeof. */ +/* #undef SIZEOF_SHORT */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define VERSION "2.4.1" + +#ifndef HAVE_C99_INTTYPES +# if SIZEOF_SHORT == 4 +typedef unsigned short uint32_t; +# elif SIZEOF_INT == 4 +typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 +typedef unsigned long uint32_t; +# endif +# if SIZEOF_INT == 8 +typedef unsigned int uint64_t; +# elif SIZEOF_LONG == 8 +typedef unsigned long uint64_t; +# elif SIZEOF_LONG_LONG == 8 +typedef unsigned long long uint64_t; +# endif +#endif + + +#ifndef HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + + +/* Define if you have POSIX and GNU specifications */ +#define _GNU_SOURCE /**/ + +/* Define if you have POSIX and XPG specifications */ +#define _XOPEN_SOURCE 600 + + +/* name mangling to protect code we share with other libraries */ +#define _mangle(proc) _shout_ ## proc + + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* 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 if va_copy is not available */ +/* #undef va_copy */ + +#endif diff --git a/lib/libshout/configure.ac b/lib/libshout/configure.ac new file mode 100644 index 00000000000..c4d5ad60be0 --- /dev/null +++ b/lib/libshout/configure.ac @@ -0,0 +1,230 @@ +# Process this file with autoconf to produce a configure script. +# $Id$ + +m4_define(libshout_major, 2) +m4_define(libshout_minor, 4) +m4_define(libshout_micro, 1) +m4_define(libshout_version, libshout_major.libshout_minor.libshout_micro) + +AC_INIT([libshout], libshout_version, [icecast-dev@xiph.org]) +AC_PREREQ([2.54]) +AC_CONFIG_SRCDIR([src/shout.c]) +AM_CONFIG_HEADER(config.h) +# config.h guard +AH_TOP([#ifndef __CONFIG_H__ +#define __CONFIG_H__ 1]) +AH_BOTTOM([#endif]) + +AC_DEFINE([LIBSHOUT_MAJOR], libshout_major, [Shout library major version]) +AC_DEFINE([LIBSHOUT_MINOR], libshout_minor, [Shout library minor version]) +AC_DEFINE([LIBSHOUT_MICRO], libshout_micro, [Shout library patch version]) + +VERSION=libshout_version + +AM_INIT_AUTOMAKE([libshout], libshout_version) +AM_MAINTAINER_MODE + +dnl create our name mangling macro +dnl the prefix must be hardwired because of AH limitations +AH_VERBATIM([_mangle], [ +/* name mangling to protect code we share with other libraries */ +#define _mangle(proc) _shout_ ## proc +]) + +AC_PROG_CC +AM_PROG_LIBTOOL + +dnl Set some options based on environment + +dnl openbsd headers break when _XOPEN_SOURCE is defined but without it seems +dnl to be fine +case "$ac_cv_host" in + *openbsd* | *solaris* | *irix*) + ;; + *) AC_DEFINE(_XOPEN_SOURCE, 600, [Define if you have POSIX and XPG specifications]) + ;; +esac +if test -z "$GCC"; then + case $host in + *-*-irix*) + DEBUG="-g -signed" + CFLAGS="-O2 -w -signed" + PROFILE="-p -g3 -O2 -signed" + ;; + sparc-sun-solaris*) + DEBUG="-v -g" + CFLAGS="-xO4 -fast -w -fsimple -native -xcg92" + PROFILE="-v -xpg -g -xO4 -fast -native -fsimple -xcg92 -Dsuncc" + ;; + *) + DEBUG="-g" + CFLAGS="-O" + PROFILE="-g -p" + ;; + esac +else + XIPH_CFLAGS="-Wall -ffast-math -fsigned-char" + AC_DEFINE(_GNU_SOURCE, ,[Define if you have POSIX and GNU specifications]) + DEBUG="-g" + PROFILE="-pg -g" +fi + +dnl Checks for programs. + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_TIME +AC_CHECK_HEADERS([strings.h sys/timeb.h]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +XIPH_C99_INTTYPES + +dnl Checks for library functions. +AC_CHECK_FUNCS([gettimeofday ftime]) +AC_SEARCH_LIBS([nanosleep], [rt], + [AC_DEFINE([HAVE_NANOSLEEP], [1], + [Define if you have the nanosleep function])]) + +dnl Module checks +XIPH_NET + +dnl Extra dependencies +AC_ARG_ENABLE([thread], + AC_HELP_STRING([--disable-thread],[do not build with thread support even if it is available])) + +SHOUT_THREADSAFE="0" +if test "$enable_thread" != "no" +then + ACX_PTHREAD([ + LIBS="$LIBS $PTHREAD_LIBS" + XIPH_CFLAGS="$XIPH_CFLAGS $PTHREAD_CFLAGS $PTHREAD_CPPFLAGS" + CC="$PTHREAD_CC" + SHOUT_THREADSAFE="1" + ]) +fi +AC_SUBST([SHOUT_THREADSAFE]) +AM_CONDITIONAL([HAVE_THREAD], [test "$SHOUT_THREADSAFE" = "1"]) +if test "$SHOUT_THREADSAFE" != "1" +then + AC_DEFINE([NO_THREAD], 1, [Define if you don't want to use the thread library]) +fi + +SHOUT_REQUIRES="ogg" + +PKG_CHECK_MODULES(VORBIS, vorbis, [ + HAVE_VORBIS="yes" + SHOUT_REQUIRES="$SHOUT_REQUIRES, vorbis" + ], [ + XIPH_PATH_VORBIS(, [AC_MSG_ERROR([required Ogg Vorbis library not found])]) + ]) +VORBIS_LIBS="$VORBIS_LDFLAGS $VORBIS_LIBS" +XIPH_CFLAGS="$XIPH_CFLAGS $VORBIS_CFLAGS" + +AC_ARG_ENABLE([theora], + AC_HELP_STRING([--disable-theora],[do not build with Theora support])) + +if test "x$enable_theora" != "xno"; then +PKG_CHECK_MODULES(THEORA, theora, [ + HAVE_THEORA="yes" + SHOUT_REQUIRES="$SHOUT_REQUIRES, theora" + ], [ + XIPH_PATH_THEORA(, [AC_MSG_WARN([Theora library not found, disabling])]) + ]) +fi +XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$THEORA_CFLAGS]) +XIPH_VAR_PREPEND([XIPH_LIBS],[$THEORA LDFLAGS $THEORA_LIBS]) +AM_CONDITIONAL([HAVE_THEORA], [test -n "$THEORA_LIBS"]) +if test -n "$THEORA_LIBS" +then + AC_DEFINE([HAVE_THEORA], 1, [Define if you want theora streams supported]) +fi + +AC_ARG_ENABLE([speex], + AC_HELP_STRING([--disable-speex],[do not build with Speex support])) + +if test "x$enable_speex" != "xno"; then +PKG_CHECK_MODULES(SPEEX, speex, [ + HAVE_SPEEX="yes" + SHOUT_REQUIRES="$SHOUT_REQUIRES, speex" + ], [ + XIPH_PATH_SPEEX(, [AC_MSG_WARN([Speex library not found, disabling])]) + ]) +fi +XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$SPEEX_CFLAGS]) +XIPH_VAR_PREPEND([XIPH_LIBS],[$SPEEX LDFLAGS $SPEEX_LIBS]) +AM_CONDITIONAL([HAVE_SPEEX], [test -n "$SPEEX_LIBS"]) +if test -n "$SPEEX_LIBS" +then + AC_DEFINE([HAVE_SPEEX], 1, [Define if you want speex streams supported]) +fi + +dnl If pkgconfig is found, install a shout.pc file. + +AC_ARG_ENABLE([pkgconfig], + AC_HELP_STRING([--disable-pkgconfig],[disable pkgconfig data files (auto)]), + [dopkgconfig="$enableval"], [dopkgconfig="maybe"]) +if test "$dopkgconfig" = "maybe" +then + AC_CHECK_PROG([PKGCONFIG], [pkg-config], [yes], [no]) +else + AC_MSG_CHECKING([whether pkgconfig should be used]) + PKGCONFIG="$dopkgconfig" + AC_MSG_RESULT([$PKGCONFIG]) +fi +AM_CONDITIONAL([HAVE_PKGCONFIG], [test "$PKGCONFIG" != "no"]) + +# Collect flags for shout.pc + +# I hate myself for doing this. +save_prefix="$prefix" +if test "$prefix" = "NONE" +then + prefix="$ac_default_prefix" +fi +eval shout_includedir="$includedir" +prefix="$save_prefix" + +XIPH_PATH_OPENSSL([ + XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$OPENSSL_CFLAGS]) + XIPH_VAR_APPEND([XIPH_LDFLAGS],[$OPENSSL_LDFLAGS]) + XIPH_VAR_PREPEND([XIPH_LIBS],[$OPENSSL_LIBS]) + SHOUT_TLS="1" + ], + [ AC_MSG_NOTICE([SSL disabled!]) + SHOUT_TLS="0" + ]) +AC_SUBST([SHOUT_TLS]) +AM_CONDITIONAL([HAVE_TLS], [test -n "$OPENSSL_LIBS"]) + +SHOUT_VERSION="$VERSION" +SHOUT_CPPFLAGS="-I$shout_includedir $VORBIS_CFLAGS $PTHREAD_CPPFLAGS" +SHOUT_CFLAGS="$PTHREAD_CFLAGS" +SHOUT_LIBS="-lshout" + +XIPH_CLEAN_CCFLAGS([$SHOUT_CPPFLAGS], [SHOUT_CPPFLAGS]) +XIPH_CLEAN_CCFLAGS([$SHOUT_CFLAGS], [SHOUT_CFLAGS]) +XIPH_CLEAN_CCFLAGS([$VORBIS_LIBS $THEORA_LIBS $SPEEX_LIBS $PTHREAD_LIBS $OPENSSL_LIBS $OPENSSL_LIBS $LIBS], [SHOUT_LIBDEPS]) +AC_SUBST(PTHREAD_CPPFLAGS) +AC_SUBST(SHOUT_LIBDEPS) +AC_SUBST(SHOUT_REQUIRES) +AC_SUBST(SHOUT_CPPFLAGS) +AC_SUBST(SHOUT_CFLAGS) + +dnl Make substitutions + +AC_SUBST(LIBTOOL_DEPS) +AC_SUBST(OPT) +AC_SUBST(LIBS) +AC_SUBST(DEBUG) +AC_SUBST(CFLAGS) +AC_SUBST(PROFILE) +AC_SUBST(XIPH_CFLAGS) +AC_SUBST(XIPH_CPPFLAGS) +AC_SUBST(XIPH_LIBS) + +AC_OUTPUT([Makefile include/Makefile include/shout/Makefile + include/shout/shout.h src/Makefile src/common/net/Makefile src/common/timing/Makefile + src/common/thread/Makefile src/common/avl/Makefile src/common/httpp/Makefile doc/Makefile + examples/Makefile win32/Makefile shout.pc]) diff --git a/lib/libshout/doc/Makefile.am b/lib/libshout/doc/Makefile.am new file mode 100644 index 00000000000..9595cef297d --- /dev/null +++ b/lib/libshout/doc/Makefile.am @@ -0,0 +1,3 @@ +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = spec-html.xsl libshout.xml diff --git a/lib/libshout/doc/libshout.xml b/lib/libshout/doc/libshout.xml new file mode 100644 index 00000000000..62f9da3d7d3 --- /dev/null +++ b/lib/libshout/doc/libshout.xml @@ -0,0 +1,1307 @@ + + + +Programming With Libshout 2 + + + Xiph.org + $Id: libshout.xml,v 1.5 2003/07/10 01:46:24 brendan Exp $ + 09 September 2015 + + +Overview + + +libshout is a library for streaming audio to icecast or shoutcast-compatible +servers. Currently it supports three formats and three protocols. + + +Audio Formats + Ogg (audio any video with different codecs) + WebM (audio and video) + MP3 + + +Protocols + HTTP + RoarAudio + Audiocast + ShoutCast + + + + +Reference + +
Functions + +
Global functions + + + + void shout_init + + + + +Initializes the shout library. Currently this initializes the networking +mutexes when the library is built with thread safety. This function must +always be called before any other libshout function. + + + + + void shout_shutdown + + + + +Releases any resources which may have been allocated by a call to +shout_init. An +application should call this function after it has finished using libshout. + + + + + const char *shout_version + int *major + int *minor + int *patch + + + +Returns the version of the libshout library, both as a string via the +return value, and as a set of integers corresponding to the major, +minor and patch levels of the library. The application must allocate +the integer parameters. If any parameter is NULL, libshout will not +attempt to set it. + + +
+ +
Managing connections + + + + shout_t *shout_new + + + + +Allocates a new shout_t structure. May return NULL if no memory +is available. The result should be disposed of with +shout_free when you are +finished with it. + + + + + void shout_free + shout_t *self + + + +Frees a shout_t allocated by +shout_new. + + + + + int shout_open + shout_t *self + + + +Opens a connection to a server. All connection parameters must have been +set prior to this call. + +Return Values + + SHOUTERR_SUCCESS + The connection was successfully opened. + + + + SHOUTERR_INSANE + self is corrupt or incorrect. Possible reasons + include an unset host, port, or password. + + + + SHOUTERR_CONNECTED + The connection has already been opened. + + + + SHOUTERR_UNSUPPORTED + The protocol/format combination is unsupported. For instance, + Ogg Vorbis may only be sent via the HTTP protocol. + + + + SHOUTERR_NOCONNECT + A connection to the server could not be established. + + + + SHOUTERR_SOCKET + An error occured while talking to the server. + + + + SHOUTERR_NOLOGIN + The server refused login, probably because authentication + failed. + + + + SHOUTERR_MALLOC + There wasn't enough memory to complete the operation. + + + + + + int shout_close + shout_t *self + + + +Closes a connection to the server. + + +Return Values + + SHOUTERR_SUCCESS + The connection was successfully closed. + + + + SHOUTERR_INSANE + self is not a valid shout_t + object. + + + + SHOUTERR_UNCONNECTED + self is not currently connected. + + + + + + int shout_get_connected + shout_t *self + + + +Returns the connection status of the given shout_t object. + + +Return Values + + SHOUTERR_INSANE + self is not a valid shout_t + object. + + + + SHOUTERR_UNCONNECTED + self is not currently connected. + + + + SHOUTERR_CONNECTED + self is currently connected. + + + + + + const char *shout_get_error + shout_t *self + + + +Returns a statically allocated string describing the last shout error +that occured in this connection. Only valid until the next call affecting +this connection. + + + + + int shout_get_errno + shout_t *self + + + +Returns the shout error code of the last error that occured in this connection. + + +
+ +
Sending data + + + + int shout_send + shout_t *self + const unsigned char *data> + size_t len + + + +Sends len bytes of audio data from the buffer pointed to by +data to the server. The connection must already have been +established by a successful call to +shout_open. + + +Return Values + + SHOUTERR_SUCCESS + The audio data was sent successfully. + + + + SHOUTERR_INSANE + self is not a valid shout_t + object. + + + + SHOUTERR_UNCONNECTED + self is not currently connected. + + + + SHOUTERR_MALLOC + There wasn't enough memory to complete the operation. + + + + SHOUTERR_SOCKET + An error occured while talking to the server. + + + + + + ssize_t shout_send_raw + shout_t *self + const unsigned char *data> + size_t len + + + +Sends len bytes of audio data from the buffer pointed to by +data to the server. The data is not parsed for timing +or validity, but sent raw over the connection. The connection must already have been +established by a successful call to +shout_open. + +This function should not be used unless you know exactly what you +are doing. Its use is deprecated and it may be removed in a future version of +the library. + +Return Values + + >= 0 + The number of bytes written. + + + + SHOUTERR_INSANE + self is not a valid shout_t + object. + + + + SHOUTERR_UNCONNECTED + self is not currently connected. + + + + SHOUTERR_SOCKET + An error occured while talking to the server. + + + + + + void shout_sync + shout_t *self + + + +Causes the caller to sleep for the amount of time necessary to play back +audio sent since the last call to shout_sync. Should +be called before every call to +shout_send to +ensure that audio data is sent to the server at the correct speed. +Alternatively, the caller may use +shout_delay to +determine the number of milliseconds to wait and delay itself. + + + + + int shout_delay + shout_t *self + + + +Returns the number of milliseconds the caller should wait before calling +shout_send again. +This function is provided as an alternative to +shout_sync for +applications that may wish to do other processing in the meantime. + + + + + ssize_t shout_queuelen + shout_t *self + + + +Returns the number of bytes currently on the write queue. + +This is only useful in non-blocking mode. + +
+ +
Connection parameters + + +The following functions are used to get or set attributes of the +shout_t object before calling +shout_open. They all +work the same way: they operate on one attribute of a +shout_t*. The shout_get_* functions +return the value of their associated parameter, or 0 on error (that's +NULL for those functions that return strings). The +shout_set_* functions will return either +SHOUTERR_SUCCESS on success, or one of: + + + + SHOUTERR_INSANE - shout_t + is invalid. + SHOUTERR_MALLOC - libshout could not + allocate enough memory to assign the parameter. + SHOUTERR_CONNECTED - you are attempting + to change a connection attribute while the connection is open. Since these + parameters are only used when first opening the connection, this operation + would be useless. + + + + + int shout_set_nonblocking + shout_t *self + unsigned int nonblocking + + + +Sets non-blocking mode. The default is 0. + + + + + unsigned int shout_get_nonblocking + shout_t *self + + + +Returns non-blocking mode or 0 in case of error. + + + + + int shout_set_host + shout_t *self + const char *host + + + +Sets the server hostname or IP address. The default is localhost. + + + + + const char *shout_get_host + shout_t *self + + + +Returns the server hostname or IP address. + + + + + int shout_set_port + shout_t *self + unsigned short port + + + +Sets the server port. The default is 8000. + + + + + unsigned short shout_get_port + shout_t *self + + + +Returns the server port. + + + + + int shout_set_user + shout_t *self + const char *user + + + +Sets the user to authenticate as, for protocols that can use this parameter. +The default is source. + + + + + const char *shout_get_user + shout_t *self + + + +Returns the user name. + + + + + int shout_set_password + shout_t *self + const char *pass + + + +Sets the password to authenticate to the server with. This parameter +must be set. There is no default. + + + + + const char *shout_get_password + shout_t *self + + + +Returns the password. + + + + + int shout_set_protocol + shout_t *self + int protocol + + + +Set the protocol with which to connect to the server. Supported protocols +are listed in Protocol Constants. +The default is SHOUT_PROTOCOL_HTTP (compatible with +Icecast 2). + + + + + int shout_get_protocol + shout_t *self + + + +Returns the protocol used to connect to the server. + + + + + int shout_set_format + shout_t *self + int format + + + +Sets the audio format of this stream. The currently supported formats +are listed in Format Constants. +The default is SHOUT_FORMAT_OGG. + + + + + int shout_get_format + shout_t *self + + + +Returns the audio format used by this stream. + + + + + int shout_set_mount + shout_t *self + const char *mount + + + +Sets the mount point for this stream, for protocols that support this option +(SHOUT_PROTOCOL_ICY doesn't). + + + + + const char *shout_get_mount + shout_t *self + + + +Returns the stream mount point. + + + + + int shout_set_dumpfile + shout_t *self + const char *dumpfile + + + +If the server supports it, you can request that your stream be archived +on the server under the name dumpfile. This can quickly +eat a lot of disk space, so think twice before setting it. + + + + + const char *shout_get_dumpfile + shout_t *self + + + +Returns the dump file, if specified. + + + + + int shout_set_agent + shout_t *self + const char *agent + + + +Sets the user agent header. This is libshout/VERSION +by default. If you don't know what this function is for, don't use it. + + + + + const char *shout_get_agent + shout_t *self + + + +Returns the user agent. + + + + + int shout_set_tls + shout_t *self + int mode + + + +This function sets the TLS (Transport Layer Security) mode to use. +mode is a TLS mode. +This is SHOUT_TLS_AUTO by default. + +To force TLS on you should use SHOUT_TLS_AUTO_NO_PLAIN and +SHOUT_TLS_DISABLED to force TLS off. +While SHOUT_TLS_AUTO may connect via TLS this is not a +secure mode as everybody can do a man in the middle kind of attack and downgrade the +connection to plain. + + + + int shout_get_tls + shout_t *self + + + +Returns the currently used TLS mode. + + + + + int shout_set_ca_directory + shout_t *self + const char *directory + + + +This sets the CA directory used by libshout to verify server certificates. +Defaults to system defaults. + + + + + const char *shout_get_ca_directory + shout_t *self + + + +Returns the currently used CA directory. + + + + + int shout_set_ca_file + shout_t *self + const char *file + + + +Sets a file with CA certificates used to verify server certificates. +Defaults to system defaults. The file must be in PEM format. + +You can use this for self signed server certificates. +In this case you point this to the server certificate in PEM format. +Keep in mind that this will allow self-signed certificates but other +checks such as hostname still needs to verify correctly. + + + + const char *shout_get_ca_file + shout_t *self + + + +Returns the currently used CA file. + + + + + int shout_set_allowed_ciphers + shout_t *self + const char *ciphers + + + +This sets the list of currently allowed ciphers in OpenSSL format. +Defaults to a list of ciphers considerd secure as of day of release. + +Setting this to a insecure list may render encryption and authentication useless. +Any application using this call must expose this list to the user. +If the user can not alter this list your application will harm security badly by +preventing the user to get to a save value by setting it manually or upgrading +libshout. +Do not use this call if you don't know what you are doing. + + + + const char *shout_get_allowed_ciphers + shout_t *self + + + +Returns the currently used list of allowed ciphers. + + + + + int shout_set_client_certificate + shout_t *self + const char *certificate + + + +This sets the client certificate to be used. Defaults to none. +The file must be in PEM format and must contain both the certificate as well as the +private key for that certificate. + + + + + const char *shout_get_client_certificate + shout_t *self + + + +Returns the currently used client certificate. + + +
+ +
Directory parameters + + +The following parameters are optional. They are used to control whether +and how your stream will be listed in the server's stream directory (if available). + + + + + int shout_set_public + shout_t *self + int makepublic + + + +Setting this to 1 asks the server to list the stream in +any directories it knows about. To suppress listing, set this to +0. The default is 0. + + + + + int shout_get_public + shout_t *self + + + +Returns whether or not this stream is public. + + + + + int shout_set_meta + shout_t *self + const char *name + const char *value + + + +This function sets the meta data for the stream. + + + + + const char *shout_get_meta + shout_t *self + const char *name + + + +This function gets the meta data for the stream. + + + + + int shout_set_audio_info + shout_t *self + const char *name + const char *value + + + +Sets a stream audio parameter (eg bitrate, samplerate, channels or quality). +The currently defined parameters are listed in the +Audio Info Constants section, but +you are free to add additional fields if your directory server understands them. + + + + + const char *shout_get_audio_info + shout_t *self + const char *name + + + +Returns the value of the audio info field name, if defined. + + +
+ +
Metadata + +These functions currently only make sense for MP3 streams. Vorbis streams are expected +to embed metadata as vorbis comments in the audio stream. + + + + + shout_metadata_t *shout_metadata_new + + + + +Allocates a new metadata structure, or returns NULL if no memory is available. The +returned structure should be freed with +shout_metadata_free when you are done with +it. + + + + + void shout_metadata_free + shout_metadata_t *self + + + +Frees any resources associated with self. + + + + + int shout_metadata_add + shout_metadata_t *self + const char *name + const char *value + + + +Add metadata value value to self, under the +key name. You'll probably want to set name +to "song", though "url" may also be +useful. + + +Return Values + + SHOUTERR_SUCCESS + The metadata was copied into self. + + + + SHOUTERR_INSANE + self is not a valid shout_metadata_t object. + + + + SHOUTERR_MALLOC + Couldn't allocate enough memory to copy the metadata. + + + + + + int shout_set_metadata + shout_t *self + shout_metadata_t *metadata + + + +Sets metadata on the connection self to metadata. +Only MP3 streams support this type of metadata update. You may use this function +on defined but closed connections (this is useful if you simply want to set the +metadata for a stream provided by another process). + + +Return Values + + SHOUTERR_SUCCESS + Metadata was updated successfully. + + + + SHOUTERR_INSANE + self and/or metadata is invalid. + + + + SHOUTERR_MALLOC + Couldn't allocate enough memory to complete the operation. + + + + SHOUTERR_NOCONNECT + The server refused the connection attempt. + + + + SHOUTERR_NOLOGIN + The server did not accept your authorization credentials. + + + + SHOUTERR_SOCKET + An error occured talking to the server. + + + + SHOUTERR_METADATA + The server returned any other error (eg bad mount point). + + + +
+ +
Obsolate metadata Interface + +All those functions have been replaced by shout_set_meta and +shout_get_meta. They may be removed by newer versions of this library. + + + + + int shout_set_name + shout_t *self + const char *name + + + +Sets the name of the stream. + + + + + const char *shout_get_name + shout_t *self + + + +Returns the stream name. + + + + + int shout_set_url + shout_t *self + const char *url + + + +Sets the URL of a site about this stream. + + + + + const char *shout_get_url + shout_t *self + + + +Returns the stream URL. + + + + + int shout_set_genre + shout_t *self + const char *genre + + + +Sets the genre (or genres) of the stream. This is usually a keyword list, +eg "pop rock rap". + + + + + const char *shout_get_genre + shout_t *self + + + +Returns the stream genre. + + + + + int shout_set_description + shout_t *self + const char *description + + + +Sets the description of this stream. + + + + + const char *shout_get_description + shout_t *self + + + +Returns the stream description. + + +
+ +
+ +
Data Types + + + + shout_t + Opaque data type that refers to a single server connection. + + + + shout_metadata_t + Opaque data type that refers to a set of metadata attributes. Currently + the only defined attribute is song. + + + +
+ +
Constants + +Error Codes + + SHOUTERR_SUCCESS + Indicates success. + + + + SHOUTERR_INSANE + Indicates bad parameters, either nonsense or not applicable due to the current + state of the connection. + + + + SHOUTERR_MALLOC + Indicates the function could not allocate the memory it required. + + + + SHOUTERR_NOCONNECT + Indicates a connection with the server could not be established. + + + + SHOUTERR_NOLOGIN + Indicates the server refused to accept a login attempt. This could be caused + by a bad user name or password. + + + + SHOUTERR_SOCKET + Indicates an error sending or receiving data. + + + + SHOUTERR_METADATA + Indicates an error updating metadata on the server. + + + + SHOUTERR_CONNECTED + Indicates that, while connected, you attempted to call a function which only makes + sense before connection (eg you attempted to set the user name or stream name). + + + + SHOUTERR_UNCONNECTED + Indicates that you attempted to use a function that requires an open connection + (for example, shout_send) while you were not connected. + + + + SHOUTERR_UNSUPPORTED + Indicates that you attempted to use a function which is unsupported in the + state of your connection. For example, attempting to set metadata while using the + Ogg Vorbis format is unsupported. + + + + SHOUTERR_BUSY + Indicates that the socket is busy. The funtion returning this should be + called again later. This is likely to happen in non-blocking mode but may also happen + in blocking mode. + + + + SHOUTERR_NOTLS + TLS (Transport Layer Security) was requested via shout_set_tls + but is not supported by the server. + + + + SHOUTERR_TLSBADCERT + A TLS (Transport Layer Security) connection has been established but the server + returned a certificate which failed the check. The certificate may be invalid or + is not signed by a trusted CA. See shout_set_tls. + + + + SHOUTERR_RETRY + The caller should retry this call later. + + + +Formats + + SHOUT_FORMAT_OGG + The Ogg Format. Vorbis or any codec may be used. This is the default format. + + + + SHOUT_FORMAT_WEBM + The WebM format. + + + + SHOUT_FORMAT_WEBMAUDIO + The WebM format, audio only streams. + + + + SHOUT_FORMAT_VORBIS + This is deprecated. It is an alias to SHOUT_FORMAT_OGG. + Please migrate your code. + + + + SHOUT_FORMAT_MP3 + The MP3 format. + + + +Protocols + + SHOUT_PROTOCOL_HTTP + The HTTP protocol. This is the native protocol of the + Icecast 2 server, and is the default. + + + + SHOUT_PROTOCOL_ROARAUDIO + The RoarAudio protocol. This is the native protocol for + RoarAudio servers. + + + + SHOUT_PROTOCOL_XAUDIOCAST + The Audiocast format. This is the native protocol of + Icecast 1. + + + + SHOUT_PROTOCOL_ICY + The ShoutCast format. This is the native protocol of + ShoutCast. + + + +Audio Parameters + + SHOUT_AI_BITRATE + Used to specify the nominal bitrate of the stream. + + + + SHOUT_AI_SAMPLERATE + Used to specify the samplerate of the stream. + + + + SHOUT_AI_CHANNELS + Used to specify the number of channels (usually one or two). + + + + SHOUT_AI_QUALITY + Used to specify the Ogg Vorbis encoding quality of the stream. + + + +Stream Metadata Parameters + + SHOUT_META_NAME + Sets stream name. + + + + SHOUT_META_URL + Sets stream URL. + + + + SHOUT_META_GENRE + Sets stream genre. + + + + SHOUT_META_DESCRIPTION + Sets stream description. + + + + SHOUT_META_IRC + Sets IRC contact information for stream. + + + + SHOUT_META_AIM + Sets AIM contact information for stream. + + + + SHOUT_META_ICQ + Sets ICQ contact information for stream. + + + +TLS modes + + SHOUT_TLS_DISABLED + TLS (Transport Layer Security) is disabled. + Passwords and data will be sent unencrypted. + + + + SHOUT_TLS_AUTO + TLS (Transport Layer Security) support by the server will be autodetected. This is the default. + In this mode TLS is used if supported by the server. + Please note that this is not a secure mode as it will + not prevent any downgrade attacks. SHOUT_TLS_AUTO_NO_PLAIN is a more secure version of + this mode. + + + + + SHOUT_TLS_AUTO_NO_PLAIN + TLS (Transport Layer Security) is used. Autodetection is used to find out about which modes + are supported by the server. This mode should be used for secure connections. + + + + SHOUT_TLS_RFC2818 + TLS (Transport Layer Security) is used as defined by RFC2818. + In this mode libshout expects a TLS socket on the server side and will begin with a TLS handshake + prior to any other communication. + + + + + SHOUT_TLS_RFC2817 + TLS (Transport Layer Security) is used as defined by RFC2817. + In this mode libshout will use HTTP/1.1's Upgrade:-process to switch to TLS. + This allows to use TLS on a non-TLS socket of the server. + + + +
+ +
+ +
diff --git a/lib/libshout/doc/spec-html.xsl b/lib/libshout/doc/spec-html.xsl new file mode 100644 index 00000000000..9cbdc1aa8e9 --- /dev/null +++ b/lib/libshout/doc/spec-html.xsl @@ -0,0 +1,4 @@ + + + + diff --git a/lib/libshout/examples/Makefile.am b/lib/libshout/examples/Makefile.am new file mode 100644 index 00000000000..72a1209eaa7 --- /dev/null +++ b/lib/libshout/examples/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign + +noinst_PROGRAMS = example nonblocking + +example_SOURCES = example.c +example_LDADD = $(top_builddir)/src/libshout.la @SHOUT_LIBDEPS@ + +nonblocking_SOURCES = nonblocking.c +nonblocking_LDADD = $(top_builddir)/src/libshout.la @SHOUT_LIBDEPS@ + +AM_CFLAGS = @XIPH_CFLAGS@ +AM_CPPFLAGS = @XIPH_CPPFLAGS@ -I$(top_builddir)/include diff --git a/lib/libshout/examples/example.c b/lib/libshout/examples/example.c new file mode 100644 index 00000000000..e1f6c149a9a --- /dev/null +++ b/lib/libshout/examples/example.c @@ -0,0 +1,86 @@ +/* example.c: Demonstration of the libshout API. + * $Id$ + */ + +#include +#include +#include + +#include + +int main() +{ + shout_t *shout; + unsigned char buff[4096]; + long read, ret, total; + + shout_init(); + + if (!(shout = shout_new())) { + printf("Could not allocate shout_t\n"); + return 1; + } + + if (shout_set_host(shout, "127.0.0.1") != SHOUTERR_SUCCESS) { + printf("Error setting hostname: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { + printf("Error setting protocol: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_port(shout, 8000) != SHOUTERR_SUCCESS) { + printf("Error setting port: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_password(shout, "hackme") != SHOUTERR_SUCCESS) { + printf("Error setting password: %s\n", shout_get_error(shout)); + return 1; + } + if (shout_set_mount(shout, "/example.ogg") != SHOUTERR_SUCCESS) { + printf("Error setting mount: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) { + printf("Error setting user: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { + printf("Error setting user: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_open(shout) == SHOUTERR_SUCCESS) { + printf("Connected to server...\n"); + total = 0; + while (1) { + read = fread(buff, 1, sizeof(buff), stdin); + total = total + read; + + if (read > 0) { + ret = shout_send(shout, buff, read); + if (ret != SHOUTERR_SUCCESS) { + printf("DEBUG: Send error: %s\n", shout_get_error(shout)); + break; + } + } else { + break; + } + + shout_sync(shout); + } + } else { + printf("Error connecting: %s\n", shout_get_error(shout)); + } + + shout_close(shout); + + shout_shutdown(); + + return 0; +} diff --git a/lib/libshout/examples/nonblocking.c b/lib/libshout/examples/nonblocking.c new file mode 100644 index 00000000000..1458cf80a03 --- /dev/null +++ b/lib/libshout/examples/nonblocking.c @@ -0,0 +1,108 @@ +/* -*- c-basic-offset: 8; -*- + * example.c: Demonstration of the libshout API. + * $Id$ + */ + +#include +#include +#include +#include + +#include + +int main() +{ + shout_t *shout; + unsigned char buff[4096]; + long read, ret, total; + + shout_init(); + + if (!(shout = shout_new())) { + printf("Could not allocate shout_t\n"); + return 1; + } + + if (shout_set_host(shout, "127.0.0.1") != SHOUTERR_SUCCESS) { + printf("Error setting hostname: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { + printf("Error setting protocol: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_port(shout, 8000) != SHOUTERR_SUCCESS) { + printf("Error setting port: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_password(shout, "hackme") != SHOUTERR_SUCCESS) { + printf("Error setting password: %s\n", shout_get_error(shout)); + return 1; + } + if (shout_set_mount(shout, "/example.ogg") != SHOUTERR_SUCCESS) { + printf("Error setting mount: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) { + printf("Error setting user: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { + printf("Error setting user: %s\n", shout_get_error(shout)); + return 1; + } + + if (shout_set_nonblocking(shout, 1) != SHOUTERR_SUCCESS) { + printf("Error setting non-blocking mode: %s\n", shout_get_error(shout)); + return 1; + } + + ret = shout_open(shout); + if (ret == SHOUTERR_SUCCESS) + ret = SHOUTERR_CONNECTED; + + if (ret == SHOUTERR_BUSY) + printf("Connection pending...\n"); + + while (ret == SHOUTERR_BUSY) { + usleep(10000); + ret = shout_get_connected(shout); + } + + if (ret == SHOUTERR_CONNECTED) { + printf("Connected to server...\n"); + total = 0; + while (1) { + read = fread(buff, 1, sizeof(buff), stdin); + total = total + read; + + if (read > 0) { + ret = shout_send(shout, buff, read); + if (ret != SHOUTERR_SUCCESS) { + printf("DEBUG: Send error: %s\n", shout_get_error(shout)); + break; + } + } else { + break; + } + if (shout_queuelen(shout) > 0) + printf("DEBUG: queue length: %d\n", + (int)shout_queuelen(shout)); + + shout_sync(shout); + } + } else { + printf("Error connecting: %s\n", shout_get_error(shout)); + } + + shout_close(shout); + + shout_shutdown(); + + return 0; +} diff --git a/lib/libshout/include/Makefile.am b/lib/libshout/include/Makefile.am new file mode 100644 index 00000000000..375abb3a7b9 --- /dev/null +++ b/lib/libshout/include/Makefile.am @@ -0,0 +1,7 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = shout + +EXTRA_DIST = os.h diff --git a/lib/libshout/include/os.h b/lib/libshout/include/os.h new file mode 100755 index 00000000000..8442af44a40 --- /dev/null +++ b/lib/libshout/include/os.h @@ -0,0 +1,7 @@ +#ifdef _MSC_VER +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef unsigned __int32 uint32_t; +typedef __int32 int32_t; +typedef int ssize_t; +#endif diff --git a/lib/libshout/include/shout/Makefile.am b/lib/libshout/include/shout/Makefile.am new file mode 100644 index 00000000000..9b3464beff5 --- /dev/null +++ b/lib/libshout/include/shout/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = foreign + +pkgincludedir = $(includedir)/shout +nodist_pkginclude_HEADERS = shout.h diff --git a/lib/libshout/include/shout/shout.h b/lib/libshout/include/shout/shout.h new file mode 100644 index 00000000000..6f410515c53 --- /dev/null +++ b/lib/libshout/include/shout/shout.h @@ -0,0 +1,265 @@ +/* shout.h + * + * API for libshout, the streaming library for icecast + * + * Copyright (C) 2002-2003 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __LIBSHOUT_SHOUT_H__ +#define __LIBSHOUT_SHOUT_H__ + +#include +#if defined(WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__) +#include +#endif + +#define SHOUTERR_SUCCESS (0) /* No error */ +#define SHOUTERR_INSANE (-1) /* Nonsensical arguments e.g. self being NULL */ +#define SHOUTERR_NOCONNECT (-2) /* Couldn't connect */ +#define SHOUTERR_NOLOGIN (-3) /* Login failed */ +#define SHOUTERR_SOCKET (-4) /* Socket error */ +#define SHOUTERR_MALLOC (-5) /* Out of memory */ +#define SHOUTERR_METADATA (-6) +#define SHOUTERR_CONNECTED (-7) /* Cannot set parameter while connected */ +#define SHOUTERR_UNCONNECTED (-8) /* Not connected */ +#define SHOUTERR_UNSUPPORTED (-9) /* This libshout doesn't support the requested option */ +#define SHOUTERR_BUSY (-10) /* Socket is busy */ +#define SHOUTERR_NOTLS (-11) /* TLS requested but not supported by peer */ +#define SHOUTERR_TLSBADCERT (-12) /* TLS connection can not be established because of bad certificate */ +#define SHOUTERR_RETRY (-13) /* Retry last operation. */ + +#define SHOUT_FORMAT_OGG (0) /* application/ogg */ +#define SHOUT_FORMAT_MP3 (1) /* audio/mpeg */ +#define SHOUT_FORMAT_WEBM (2) /* video/webm */ +#define SHOUT_FORMAT_WEBMAUDIO (3) /* audio/webm audio only */ + +/* backward-compatibility alias */ +#define SHOUT_FORMAT_VORBIS SHOUT_FORMAT_OGG + +#define SHOUT_PROTOCOL_HTTP (0) +#define SHOUT_PROTOCOL_XAUDIOCAST (1) +#define SHOUT_PROTOCOL_ICY (2) +#define SHOUT_PROTOCOL_ROARAUDIO (3) + +/* Possible TLS modes */ +#define SHOUT_TLS_DISABLED (0) /* Do not use TLS at all */ +#define SHOUT_TLS_AUTO (1) /* Autodetect which TLS mode to use if any */ +#define SHOUT_TLS_AUTO_NO_PLAIN (2) /* Like SHOUT_TLS_AUTO_NO_PLAIN but does not allow plain connections */ +#define SHOUT_TLS_RFC2818 (11) /* Use TLS for transport layer like HTTPS [RFC2818] does. */ +#define SHOUT_TLS_RFC2817 (12) /* Use TLS via HTTP Upgrade:-header [RFC2817]. */ + +#define SHOUT_AI_BITRATE "bitrate" +#define SHOUT_AI_SAMPLERATE "samplerate" +#define SHOUT_AI_CHANNELS "channels" +#define SHOUT_AI_QUALITY "quality" + +#define SHOUT_META_NAME "name" +#define SHOUT_META_URL "url" +#define SHOUT_META_GENRE "genre" +#define SHOUT_META_DESCRIPTION "description" +#define SHOUT_META_IRC "irc" +#define SHOUT_META_AIM "aim" +#define SHOUT_META_ICQ "icq" + +typedef struct shout shout_t; +typedef struct _util_dict shout_metadata_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* initializes the shout library. Must be called before anything else */ +void shout_init(void); + +/* shuts down the shout library, deallocating any global storage. Don't call + * anything afterwards */ +void shout_shutdown(void); + +/* returns a static version string. Non-null parameters will be set to the + * value of the library major, minor, and patch levels, respectively */ +const char *shout_version(int *major, int *minor, int *patch); + +/* Allocates and sets up a new shout_t. Returns NULL if it can't get enough + * memory. The returns shout_t must be disposed of with shout_free. */ +shout_t *shout_new(void); + +/* Free all memory allocated by a shout_t */ +void shout_free(shout_t *self); + +/* Returns a statically allocated string describing the last shout error + * to occur. Only valid until the next libshout call on this shout_t */ +const char *shout_get_error(shout_t *self); + +/* Return the error code (e.g. SHOUTERR_SOCKET) for this shout instance */ +int shout_get_errno(shout_t *self); + +/* returns SHOUTERR_CONNECTED or SHOUTERR_UNCONNECTED */ +int shout_get_connected(shout_t *self); + +/* Parameter manipulation functions. libshout makes copies of all parameters, + * the caller may free its copies after giving them to libshout. May return + * SHOUTERR_MALLOC */ + +/* Connection parameters */ +int shout_set_host(shout_t *self, const char *host); +const char *shout_get_host(shout_t *self); + +int shout_set_port(shout_t *self, unsigned short port); +unsigned short shout_get_port(shout_t *self); + +int shout_set_agent(shout_t *self, const char *agent); +const char *shout_get_agent(shout_t *self); + +/* See SHOUT_TLS_* above */ +int shout_set_tls(shout_t *self, int mode); +int shout_get_tls(shout_t *self); + +/* Set the directory for CA certs. Default: operating system's default */ +int shout_set_ca_directory(shout_t *self, const char *directory); +const char *shout_get_ca_directory(shout_t *self); + +/* Set a CA cert file for checking. If you use a self signed server cert + * you can pass this cert using this function for verification. + * Default: operating system's default */ +int shout_set_ca_file(shout_t *self, const char *file); +const char *shout_get_ca_file(shout_t *self); + +/* Set list of allowed ciphers. + * This function should only be used in case of using an old libshout + * after some attacks got known. Watch the icecast mailinglist for + * known problems. + * DO NOT SET THIS TO ANY FIXED VALUE. IF YOU USE THIS FUNCTION + * EXPOSE IT TO THE USER. OTHERWISE YOU WILL HARM SECURITY. + * Default: internal list of secure ciphers. */ +int shout_set_allowed_ciphers(shout_t *self, const char *ciphers); +const char *shout_get_allowed_ciphers(shout_t *self); + +/* Authentication parameters */ +int shout_set_user(shout_t *self, const char *username); +const char *shout_get_user(shout_t *self); + +int shout_set_password(shout_t *, const char *password); +const char *shout_get_password(shout_t *self); + +/* Set a client certificate for TLS connections. + * This must be in PEM format with both cert and private key in the same file. + * Default: none. */ +int shout_set_client_certificate(shout_t *self, const char *certificate); +const char *shout_get_client_certificate(shout_t *self); + +/* Mount parameters */ +int shout_set_mount(shout_t *self, const char *mount); +const char *shout_get_mount(shout_t *self); + +/* Other parameters */ +int shout_set_name(shout_t *self, const char *name); // obsolete +const char *shout_get_name(shout_t *self); // obsolete + +int shout_set_url(shout_t *self, const char *url); // obsolete +const char *shout_get_url(shout_t *self); // obsolete + +int shout_set_genre(shout_t *self, const char *genre); // obsolete +const char *shout_get_genre(shout_t *self); // obsolete + +int shout_set_description(shout_t *self, const char *description); // obsolete +const char *shout_get_description(shout_t *self); // obsolete + +int shout_set_dumpfile(shout_t *self, const char *dumpfile); +const char *shout_get_dumpfile(shout_t *self); + +int shout_set_audio_info(shout_t *self, const char *name, const char *value); +const char *shout_get_audio_info(shout_t *self, const char *name); + +/* takes a SHOUT_META_xxxx argument */ +int shout_set_meta(shout_t *self, const char *name, const char *value); +const char *shout_get_meta(shout_t *self, const char *name); + +int shout_set_public(shout_t *self, unsigned int make_public); +unsigned int shout_get_public(shout_t *self); + +/* takes a SHOUT_FORMAT_xxxx argument */ +int shout_set_format(shout_t *self, unsigned int format); +unsigned int shout_get_format(shout_t *self); + +/* takes a SHOUT_PROTOCOL_xxxxx argument */ +int shout_set_protocol(shout_t *self, unsigned int protocol); +unsigned int shout_get_protocol(shout_t *self); + +/* Instructs libshout to use nonblocking I/O. Must be called before + * shout_open (no switching back and forth midstream at the moment). */ +int shout_set_nonblocking(shout_t* self, unsigned int nonblocking); +unsigned int shout_get_nonblocking(shout_t *self); + +/* Opens a connection to the server. All parameters must already be set */ +int shout_open(shout_t *self); + +/* Closes a connection to the server */ +int shout_close(shout_t *self); + +/* Send data to the server, parsing it for format specific timing info */ +int shout_send(shout_t *self, const unsigned char *data, size_t len); + +/* Send unparsed data to the server. Do not use this unless you know + * what you are doing. + * Returns the number of bytes written, or < 0 on error. + */ +ssize_t shout_send_raw(shout_t *self, const unsigned char *data, size_t len); + +/* return the number of bytes currently on the write queue (only makes sense in + * nonblocking mode). */ +ssize_t shout_queuelen(shout_t *self); + +/* Puts caller to sleep until it is time to send more data to the server */ +void shout_sync(shout_t *self); + +/* Amount of time in ms caller should wait before sending again */ +int shout_delay(shout_t *self); + +/* Sets MP3 metadata. + * Returns: + * SHOUTERR_SUCCESS + * SHOUTERR_UNSUPPORTED if format isn't MP3 + * SHOUTERR_MALLOC + * SHOUTERR_INSANE + * SHOUTERR_NOCONNECT + * SHOUTERR_SOCKET + */ +int shout_set_metadata(shout_t *self, shout_metadata_t *metadata); + +/* Allocates a new metadata structure. Must be freed by shout_metadata_free. */ +shout_metadata_t *shout_metadata_new(void); + +/* Free resources allocated by shout_metadata_t */ +void shout_metadata_free(shout_metadata_t *self); + +/* Add a parameter to the metadata structure. + * Returns: + * SHOUTERR_SUCCESS on success + * SHOUTERR_INSANE if self isn't a valid shout_metadata_t* or name is null + * SHOUTERR_MALLOC if memory can't be allocated */ +int shout_metadata_add(shout_metadata_t *self, const char *name, const char *value); + +#ifdef __cplusplus +} +#endif + +/* --- Compiled features --- */ + +#define SHOUT_THREADSAFE 1 +#define SHOUT_TLS 1 + +#endif /* __LIBSHOUT_SHOUT_H__ */ diff --git a/lib/libshout/include/shout/shout.h.in b/lib/libshout/include/shout/shout.h.in new file mode 100644 index 00000000000..a0179749fc8 --- /dev/null +++ b/lib/libshout/include/shout/shout.h.in @@ -0,0 +1,265 @@ +/* shout.h + * + * API for libshout, the streaming library for icecast + * + * Copyright (C) 2002-2003 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __LIBSHOUT_SHOUT_H__ +#define __LIBSHOUT_SHOUT_H__ + +#include +#if defined(WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__) +#include +#endif + +#define SHOUTERR_SUCCESS (0) /* No error */ +#define SHOUTERR_INSANE (-1) /* Nonsensical arguments e.g. self being NULL */ +#define SHOUTERR_NOCONNECT (-2) /* Couldn't connect */ +#define SHOUTERR_NOLOGIN (-3) /* Login failed */ +#define SHOUTERR_SOCKET (-4) /* Socket error */ +#define SHOUTERR_MALLOC (-5) /* Out of memory */ +#define SHOUTERR_METADATA (-6) +#define SHOUTERR_CONNECTED (-7) /* Cannot set parameter while connected */ +#define SHOUTERR_UNCONNECTED (-8) /* Not connected */ +#define SHOUTERR_UNSUPPORTED (-9) /* This libshout doesn't support the requested option */ +#define SHOUTERR_BUSY (-10) /* Socket is busy */ +#define SHOUTERR_NOTLS (-11) /* TLS requested but not supported by peer */ +#define SHOUTERR_TLSBADCERT (-12) /* TLS connection can not be established because of bad certificate */ +#define SHOUTERR_RETRY (-13) /* Retry last operation. */ + +#define SHOUT_FORMAT_OGG (0) /* application/ogg */ +#define SHOUT_FORMAT_MP3 (1) /* audio/mpeg */ +#define SHOUT_FORMAT_WEBM (2) /* video/webm */ +#define SHOUT_FORMAT_WEBMAUDIO (3) /* audio/webm audio only */ + +/* backward-compatibility alias */ +#define SHOUT_FORMAT_VORBIS SHOUT_FORMAT_OGG + +#define SHOUT_PROTOCOL_HTTP (0) +#define SHOUT_PROTOCOL_XAUDIOCAST (1) +#define SHOUT_PROTOCOL_ICY (2) +#define SHOUT_PROTOCOL_ROARAUDIO (3) + +/* Possible TLS modes */ +#define SHOUT_TLS_DISABLED (0) /* Do not use TLS at all */ +#define SHOUT_TLS_AUTO (1) /* Autodetect which TLS mode to use if any */ +#define SHOUT_TLS_AUTO_NO_PLAIN (2) /* Like SHOUT_TLS_AUTO_NO_PLAIN but does not allow plain connections */ +#define SHOUT_TLS_RFC2818 (11) /* Use TLS for transport layer like HTTPS [RFC2818] does. */ +#define SHOUT_TLS_RFC2817 (12) /* Use TLS via HTTP Upgrade:-header [RFC2817]. */ + +#define SHOUT_AI_BITRATE "bitrate" +#define SHOUT_AI_SAMPLERATE "samplerate" +#define SHOUT_AI_CHANNELS "channels" +#define SHOUT_AI_QUALITY "quality" + +#define SHOUT_META_NAME "name" +#define SHOUT_META_URL "url" +#define SHOUT_META_GENRE "genre" +#define SHOUT_META_DESCRIPTION "description" +#define SHOUT_META_IRC "irc" +#define SHOUT_META_AIM "aim" +#define SHOUT_META_ICQ "icq" + +typedef struct shout shout_t; +typedef struct _util_dict shout_metadata_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* initializes the shout library. Must be called before anything else */ +void shout_init(void); + +/* shuts down the shout library, deallocating any global storage. Don't call + * anything afterwards */ +void shout_shutdown(void); + +/* returns a static version string. Non-null parameters will be set to the + * value of the library major, minor, and patch levels, respectively */ +const char *shout_version(int *major, int *minor, int *patch); + +/* Allocates and sets up a new shout_t. Returns NULL if it can't get enough + * memory. The returns shout_t must be disposed of with shout_free. */ +shout_t *shout_new(void); + +/* Free all memory allocated by a shout_t */ +void shout_free(shout_t *self); + +/* Returns a statically allocated string describing the last shout error + * to occur. Only valid until the next libshout call on this shout_t */ +const char *shout_get_error(shout_t *self); + +/* Return the error code (e.g. SHOUTERR_SOCKET) for this shout instance */ +int shout_get_errno(shout_t *self); + +/* returns SHOUTERR_CONNECTED or SHOUTERR_UNCONNECTED */ +int shout_get_connected(shout_t *self); + +/* Parameter manipulation functions. libshout makes copies of all parameters, + * the caller may free its copies after giving them to libshout. May return + * SHOUTERR_MALLOC */ + +/* Connection parameters */ +int shout_set_host(shout_t *self, const char *host); +const char *shout_get_host(shout_t *self); + +int shout_set_port(shout_t *self, unsigned short port); +unsigned short shout_get_port(shout_t *self); + +int shout_set_agent(shout_t *self, const char *agent); +const char *shout_get_agent(shout_t *self); + +/* See SHOUT_TLS_* above */ +int shout_set_tls(shout_t *self, int mode); +int shout_get_tls(shout_t *self); + +/* Set the directory for CA certs. Default: operating system's default */ +int shout_set_ca_directory(shout_t *self, const char *directory); +const char *shout_get_ca_directory(shout_t *self); + +/* Set a CA cert file for checking. If you use a self signed server cert + * you can pass this cert using this function for verification. + * Default: operating system's default */ +int shout_set_ca_file(shout_t *self, const char *file); +const char *shout_get_ca_file(shout_t *self); + +/* Set list of allowed ciphers. + * This function should only be used in case of using an old libshout + * after some attacks got known. Watch the icecast mailinglist for + * known problems. + * DO NOT SET THIS TO ANY FIXED VALUE. IF YOU USE THIS FUNCTION + * EXPOSE IT TO THE USER. OTHERWISE YOU WILL HARM SECURITY. + * Default: internal list of secure ciphers. */ +int shout_set_allowed_ciphers(shout_t *self, const char *ciphers); +const char *shout_get_allowed_ciphers(shout_t *self); + +/* Authentication parameters */ +int shout_set_user(shout_t *self, const char *username); +const char *shout_get_user(shout_t *self); + +int shout_set_password(shout_t *, const char *password); +const char *shout_get_password(shout_t *self); + +/* Set a client certificate for TLS connections. + * This must be in PEM format with both cert and private key in the same file. + * Default: none. */ +int shout_set_client_certificate(shout_t *self, const char *certificate); +const char *shout_get_client_certificate(shout_t *self); + +/* Mount parameters */ +int shout_set_mount(shout_t *self, const char *mount); +const char *shout_get_mount(shout_t *self); + +/* Other parameters */ +int shout_set_name(shout_t *self, const char *name); // obsolete +const char *shout_get_name(shout_t *self); // obsolete + +int shout_set_url(shout_t *self, const char *url); // obsolete +const char *shout_get_url(shout_t *self); // obsolete + +int shout_set_genre(shout_t *self, const char *genre); // obsolete +const char *shout_get_genre(shout_t *self); // obsolete + +int shout_set_description(shout_t *self, const char *description); // obsolete +const char *shout_get_description(shout_t *self); // obsolete + +int shout_set_dumpfile(shout_t *self, const char *dumpfile); +const char *shout_get_dumpfile(shout_t *self); + +int shout_set_audio_info(shout_t *self, const char *name, const char *value); +const char *shout_get_audio_info(shout_t *self, const char *name); + +/* takes a SHOUT_META_xxxx argument */ +int shout_set_meta(shout_t *self, const char *name, const char *value); +const char *shout_get_meta(shout_t *self, const char *name); + +int shout_set_public(shout_t *self, unsigned int make_public); +unsigned int shout_get_public(shout_t *self); + +/* takes a SHOUT_FORMAT_xxxx argument */ +int shout_set_format(shout_t *self, unsigned int format); +unsigned int shout_get_format(shout_t *self); + +/* takes a SHOUT_PROTOCOL_xxxxx argument */ +int shout_set_protocol(shout_t *self, unsigned int protocol); +unsigned int shout_get_protocol(shout_t *self); + +/* Instructs libshout to use nonblocking I/O. Must be called before + * shout_open (no switching back and forth midstream at the moment). */ +int shout_set_nonblocking(shout_t* self, unsigned int nonblocking); +unsigned int shout_get_nonblocking(shout_t *self); + +/* Opens a connection to the server. All parameters must already be set */ +int shout_open(shout_t *self); + +/* Closes a connection to the server */ +int shout_close(shout_t *self); + +/* Send data to the server, parsing it for format specific timing info */ +int shout_send(shout_t *self, const unsigned char *data, size_t len); + +/* Send unparsed data to the server. Do not use this unless you know + * what you are doing. + * Returns the number of bytes written, or < 0 on error. + */ +ssize_t shout_send_raw(shout_t *self, const unsigned char *data, size_t len); + +/* return the number of bytes currently on the write queue (only makes sense in + * nonblocking mode). */ +ssize_t shout_queuelen(shout_t *self); + +/* Puts caller to sleep until it is time to send more data to the server */ +void shout_sync(shout_t *self); + +/* Amount of time in ms caller should wait before sending again */ +int shout_delay(shout_t *self); + +/* Sets MP3 metadata. + * Returns: + * SHOUTERR_SUCCESS + * SHOUTERR_UNSUPPORTED if format isn't MP3 + * SHOUTERR_MALLOC + * SHOUTERR_INSANE + * SHOUTERR_NOCONNECT + * SHOUTERR_SOCKET + */ +int shout_set_metadata(shout_t *self, shout_metadata_t *metadata); + +/* Allocates a new metadata structure. Must be freed by shout_metadata_free. */ +shout_metadata_t *shout_metadata_new(void); + +/* Free resources allocated by shout_metadata_t */ +void shout_metadata_free(shout_metadata_t *self); + +/* Add a parameter to the metadata structure. + * Returns: + * SHOUTERR_SUCCESS on success + * SHOUTERR_INSANE if self isn't a valid shout_metadata_t* or name is null + * SHOUTERR_MALLOC if memory can't be allocated */ +int shout_metadata_add(shout_metadata_t *self, const char *name, const char *value); + +#ifdef __cplusplus +} +#endif + +/* --- Compiled features --- */ + +#define SHOUT_THREADSAFE @SHOUT_THREADSAFE@ +#define SHOUT_TLS @SHOUT_TLS@ + +#endif /* __LIBSHOUT_SHOUT_H__ */ diff --git a/lib/libshout/libshout.ckport b/lib/libshout/libshout.ckport new file mode 100644 index 00000000000..ff6cf2aac9d --- /dev/null +++ b/lib/libshout/libshout.ckport @@ -0,0 +1,90 @@ +#ckport(1) database for libshout -- A Cross-platform library for media streaming: +!NAME: libshout +!TYPE: func +!TARGET: libshout3 + +# Global libshout management: +shout_init ok +shout_shutdown ok +shout_version ok + +# shout_t* object management: +shout_free ok +shout_new ok +shout_get_error ok +shout_get_errno ok +shout_get_connected ok + +# Connection parameters: +shout_set_host ok +shout_get_host ok +shout_set_port ok +shout_get_port ok +shout_set_agent ok +shout_get_agent ok +shout_set_protocol ok +shout_get_protocol ok +shout_set_nonblocking ok +shout_get_nonblocking ok + +# TLS (Transport Layer Security): +# See also 'Authentication parameters'. +shout_set_tls ok +shout_get_tls ok +shout_set_ca_directory ok +shout_get_ca_directory ok +shout_set_ca_file ok +shout_get_ca_file ok +shout_set_allowed_ciphers maybe This is for advanced applications only. If used this setting MUST be exposed to the user. Otherwise you will harm security. +shout_get_allowed_ciphers ok + +# Authentication parameters: +shout_set_user ok +shout_get_user ok +shout_set_password ok +shout_get_password ok +shout_set_client_certificate ok +shout_get_client_certificate ok + +# Source parameters: +shout_set_format ok +shout_get_format ok +shout_set_mount ok +shout_get_mount ok + +# Other parameters: +shout_set_dumpfile ok +shout_get_dumpfile ok +shout_set_audio_info ok +shout_get_audio_info ok +shout_set_meta ok +shout_get_meta ok +shout_set_public ok +shout_get_public ok + +# Sending data: +shout_open ok +shout_close ok +shout_send ok +shout_send_raw maybe Do not use this unless you know what you are doing. +shout_queuelen likely Only useful in non-blocking mode. +shout_sync ok +shout_delay ok + +# MP3 Metadata: +shout_set_metadata maybe Only useful for MP3 streams. +shout_metadata_new maybe Only useful for MP3 streams. +shout_metadata_free maybe Only useful for MP3 streams. +shout_metadata_add maybe Only useful for MP3 streams. + +# Obsolete functions: +shout_set_name legacy Replaced by shout_set_meta(). +shout_get_name legacy Replaced by shout_get_meta(). +shout_set_url legacy Replaced by shout_set_meta(). +shout_get_url legacy Replaced by shout_get_meta(). +shout_set_genre legacy Replaced by shout_set_meta(). +shout_get_genre legacy Replaced by shout_get_meta(). +shout_set_description legacy Replaced by shout_set_meta(). +shout_get_description legacy Replaced by shout_get_meta(). + +#ll diff --git a/lib/libshout/m4/acx_pthread.m4 b/lib/libshout/m4/acx_pthread.m4 new file mode 100644 index 00000000000..a67ba039629 --- /dev/null +++ b/lib/libshout/m4/acx_pthread.m4 @@ -0,0 +1,199 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html +dnl +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include ], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CPPFLAGS="$flag $PTHREAD_CPPFLAGS" + fi + + AC_CHECK_FUNCS([pthread_spin_lock]) + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CPPFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/lib/libshout/m4/libtool.m4 b/lib/libshout/m4/libtool.m4 new file mode 100644 index 00000000000..d7c043f4f99 --- /dev/null +++ b/lib/libshout/m4/libtool.m4 @@ -0,0 +1,7997 @@ +# 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 + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# 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], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _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*|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*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*) + 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" + ;; + powerpcle-*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*) + 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" && \ + test undefined != "$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 + ;; + +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 | 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 + ;; + +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 | 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 | 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 | 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 + +## 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... +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 + ;; + + 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 | 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 + +## 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... +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 + +## 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... +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 diff --git a/lib/libshout/m4/ltoptions.m4 b/lib/libshout/m4/ltoptions.m4 new file mode 100644 index 00000000000..5d9acd8e23b --- /dev/null +++ b/lib/libshout/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# 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 + + +## --------------------------------- ## +## Macros to handle LT_INIT 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], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +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])]) diff --git a/lib/libshout/m4/ltsugar.m4 b/lib/libshout/m4/ltsugar.m4 new file mode 100644 index 00000000000..9000a057d31 --- /dev/null +++ b/lib/libshout/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# 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 +]) diff --git a/lib/libshout/m4/ltversion.m4 b/lib/libshout/m4/ltversion.m4 new file mode 100644 index 00000000000..07a8602d48d --- /dev/null +++ b/lib/libshout/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# 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) +]) diff --git a/lib/libshout/m4/lt~obsolete.m4 b/lib/libshout/m4/lt~obsolete.m4 new file mode 100644 index 00000000000..c573da90c5c --- /dev/null +++ b/lib/libshout/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# 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])]) diff --git a/lib/libshout/m4/ogg.m4 b/lib/libshout/m4/ogg.m4 new file mode 100644 index 00000000000..4b00f900bfb --- /dev/null +++ b/lib/libshout/m4/ogg.m4 @@ -0,0 +1,65 @@ +# Configure paths for libogg +# updated by Karl Heyes 10-Jun-2003 +# Jack Moffitt 10-21-2000 +# Shamelessly stolen from Owen Taylor and Manish Singh + +dnl XIPH_PATH_OGG([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for libogg, and define OGG_CFLAGS OGG_LDFLAGS and OGG_LIBS +dnl +AC_DEFUN([XIPH_PATH_OGG], +[dnl +AC_ARG_VAR([OGG_PREFIX],[path to ogg installation]) +AC_ARG_WITH(ogg, + [AC_HELP_STRING([--with-ogg=PREFIX], + [Prefix where libogg is installed (optional)])], + ogg_prefix="$withval", + ogg_prefix="$OGG_PREFIX" + ) +if test "x$ogg_prefix" = "x" -o "x$ogg_prefix" = "xyes"; then + if test "x$prefix" = "xNONE"; then + ogg_prefix=/usr/local + else + ogg_prefix="$prefix" + fi +fi + +XIPH_GCC_WARNING([-I$ogg_prefix/include],, + [ OGG_CFLAGS="-I$ogg_prefix/include" + OGG_LDFLAGS="-L$ogg_prefix/lib" + ]) +AC_CACHE_CHECK([for libogg], xt_cv_lib_ogg, +[dnl +OGG_LIBS="-logg" + +# +# check if the installed Ogg is sufficiently new. +# +ac_save_CFLAGS="$CFLAGS" +ac_save_LIBS="$LIBS" +ac_save_LDFLAGS="$LDFLAGS" +CFLAGS="$CFLAGS $OGG_CFLAGS" +LIBS="$LIBS $OGG_LIBS" +LDFLAGS="$LDFLAGS $OGG_LDFLAGS" +AC_TRY_LINK_FUNC(ogg_sync_init, + [ xt_cv_lib_ogg=ok ], + [ AC_TRY_LINK([#include ],, + [ xt_cv_lib_ogg="pre v1.0, needs updating" ], + [ xt_cv_lib_ogg="not found" ]) + ]) +CFLAGS="$ac_save_CFLAGS" +LDFLAGS="$ac_save_LDFLAGS" +LIBS="$ac_save_LIBS" +]) +if test "x$xt_cv_lib_ogg" = "xok"; then + ifelse([$1],,,[$1]) + AC_DEFINE([HAVE_OGG], [1], [Define if you have libogg installed]) +else + OGG_LIBS="" + OGG_CFLAGS="" + OGG_LDFLAGS="" + ifelse([$2],,,[$2]) +fi +AC_SUBST(OGG_LIBS) +AC_SUBST(OGG_CFLAGS) +AC_SUBST(OGG_LDFLAGS) +]) diff --git a/lib/libshout/m4/shout.m4 b/lib/libshout/m4/shout.m4 new file mode 100644 index 00000000000..c1265a04696 --- /dev/null +++ b/lib/libshout/m4/shout.m4 @@ -0,0 +1,79 @@ +dnl XIPH_PATH_SHOUT +dnl Jack Moffitt 08-06-2001 +dnl Rewritten for libshout 2 +dnl Brendan Cully 20030612 +dnl +dnl $Id$ + +# XIPH_PATH_SHOUT([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +# Test for libshout, and define SHOUT_CPPFLAGS SHOUT_CFLAGS SHOUT_LIBS, and +# SHOUT_THREADSAFE +AC_DEFUN([XIPH_PATH_SHOUT], +[dnl +xt_have_shout="no" +SHOUT_THREADSAFE="no" +SHOUT_CPPFLAGS="" +SHOUT_CFLAGS="" +SHOUT_LIBS="" + +# NB: PKG_CHECK_MODULES exits if pkg-config is unavailable on the target +# system, so we can't use it. + +# seed pkg-config with the default libshout location +PKG_CONFIG_PATH=${PKG_CONFIG_PATH:-/usr/local/lib/pkgconfig} +export PKG_CONFIG_PATH + +# Step 1: Use pkg-config if available +AC_PATH_PROG([PKGCONFIG], [pkg-config], [no]) +if test "$PKGCONFIG" != "no" && `$PKGCONFIG --exists shout` +then + SHOUT_CFLAGS=`$PKGCONFIG --variable=cflags_only shout` + SHOUT_CPPFLAGS=`$PKGCONFIG --variable=cppflags shout` + SHOUT_LIBS=`$PKGCONFIG --libs shout` + xt_have_shout="maybe" +else + if test "$PKGCONFIG" != "no" + then + AC_MSG_NOTICE([$PKGCONFIG couldn't find libshout. Try adjusting PKG_CONFIG_PATH.]) + fi + # pkg-config unavailable, try shout-config + AC_PATH_PROG([SHOUTCONFIG], [shout-config], [no]) + if test "$SHOUTCONFIG" != "no" && test `$SHOUTCONFIG --package` = "libshout" + then + SHOUT_CPPFLAGS=`$SHOUTCONFIG --cppflags` + SHOUT_CFLAGS=`$SHOUTCONFIG --cflags-only` + SHOUT_LIBS=`$SHOUTCONFIG --libs` + xt_have_shout="maybe" + fi +fi + +# Now try actually using libshout +if test "$xt_have_shout" != "no" +then + ac_save_CPPFLAGS="$CPPFLAGS" + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $SHOUT_CPPFLAGS" + CFLAGS="$CFLAGS $SHOUT_CFLAGS" + LIBS="$SHOUT_LIBS $LIBS" + AC_CHECK_HEADERS([shout/shout.h], [ + AC_CHECK_FUNC([shout_new], [ + ifelse([$1], , :, [$1]) + xt_have_shout="yes" + ]) + AC_EGREP_CPP([yes], [#include +#if SHOUT_THREADSAFE +yes +#endif +], [SHOUT_THREADSAFE="yes"]) + ]) + CPPFLAGS="$ac_save_CPPFLAGS" + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" +fi + +if test "$xt_have_shout" != "yes" +then + ifelse([$2], , :, [$2]) +fi +])dnl XIPH_PATH_SHOUT diff --git a/lib/libshout/m4/speex.m4 b/lib/libshout/m4/speex.m4 new file mode 100644 index 00000000000..32455d88be4 --- /dev/null +++ b/lib/libshout/m4/speex.m4 @@ -0,0 +1,84 @@ +# Configure paths for libspeex +# updated by Karl Heyes 02-Feb-2004 + +dnl XIPH_PATH_SPEEX([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for libspeex, and define SPEEX_CFLAGS SPEEX_LIBS +dnl SPEEX_SPEEXENC_LIBS SPEEX_SPEEXFILE_LIBS SPEEX_LDFLAGS +dnl + +AC_DEFUN([XIPH_PATH_SPEEX], +[ +AC_REQUIRE([XIPH_PATH_OGG]) + +dnl Get the cflags and libraries for speex +dnl +AC_ARG_VAR([SPEEX],[path to speex installation]) +AC_ARG_WITH(speex, + AC_HELP_STRING([--with-speex=PREFIX], + [Prefix where libspeex is installed (optional)]), + speex_prefix="$withval", + speex_prefix="$SPEEX_PREFIX" + ) +if test "x$with_speex" = "xno" +then + AC_MSG_RESULT([Speex support disabled by request]) +else + if test "x$speex_prefix" = "x" -o "x$speex_prefix" = "xyes"; then + if test "x$prefix" = "xNONE"; then + speex_prefix="/usr/local" + else + speex_prefix="$prefix" + fi + fi + + SPEEX_CFLAGS="$OGG_CFLAGS" + SPEEX_LDFLAGS="$OGG_LDFLAGS" + if test "x$speex_prefix" != "x$ogg_prefix"; then + XIPH_GCC_WARNING(-I"$speex_prefix/include",, + [SPEEX_CFLAGS="$SPEEX_CFLAGS -I$speex_prefix/include" + SPEEX_LDFLAGS="-L$speex_prefix/lib $SPEEX_LDFLAGS" + ]) + fi + + SPEEX_LIBS="-lspeex" + + xt_save_LIBS="$LIBS" + xt_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $SPEEX_LDFLAGS" + LIBS="$LIBS $SPEEX_LIBS" + xt_have_speex="yes" + AC_MSG_CHECKING([for libspeex]) + AC_TRY_LINK_FUNC(ogg_stream_init, [AC_MSG_RESULT([ok])], + [LIBS="$LIBS $OGG_LIBS" + AC_TRY_LINK_FUNC(ogg_stream_init, + [SPEEX_LIBS="$SPEEX_LIBS $OGG_LIBS"], + [xt_have_speex="no"]) + ]) + if test "x$xt_have_speex" = "xyes" + then + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [#include ], + [void *p = speex_packet_to_header;])], + [], + [xt_have_speex="no"]) + fi + + LIBS="$xt_save_LIBS" + LDFLAGS="$xt_save_LDFLAGS" + + if test "x$xt_have_speex" = "xyes" + then + AC_MSG_RESULT([ok]) + AC_DEFINE([HAVE_SPEEX],[1],[Define if Speex support is available]) + $1 + else + ifelse([$2], , AC_MSG_ERROR([Unable to link to libspeex]), [$2]) + SPEEX_CFLAGS="" + SPEEX_LDFLAGS="" + SPEEX_LIBS="" + fi + AC_SUBST(SPEEX_CFLAGS) + AC_SUBST(SPEEX_LDFLAGS) + AC_SUBST(SPEEX_LIBS) +fi +]) diff --git a/lib/libshout/m4/theora.m4 b/lib/libshout/m4/theora.m4 new file mode 100644 index 00000000000..0b2cb964f12 --- /dev/null +++ b/lib/libshout/m4/theora.m4 @@ -0,0 +1,77 @@ +# Configure paths for libtheora +# Karl Heyes 02-Feb-2004 + +dnl XIPH_PATH_THEORA([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for libtheora, and define THEORA_CFLAGS THEORA_LIBS +dnl + +AC_DEFUN([XIPH_PATH_THEORA], +[ +AC_REQUIRE([XIPH_PATH_OGG]) + +dnl Get the cflags and libraries for theora +dnl +AC_ARG_VAR([THEORA],[path to theora installation]) +AC_ARG_WITH(theora, + AC_HELP_STRING([--with-theora=PREFIX], + [Prefix where libtheora is installed (optional)]), + theora_prefix="$withval", + theora_prefix="$THEORA_PREFIX" + ) + +if test "x$with_theora" = "xno" +then + AC_MSG_RESULT([Theora support disabled by request]) +else + if test "x$theora_prefix" = "x" -o "x$theora_prefix" = "xyes"; then + if test "x$prefix" = "xNONE"; then + theora_prefix="/usr/local" + else + theora_prefix="$prefix" + fi + fi + + THEORA_CFLAGS="$OGG_CFLAGS" + THEORA_LDFLAGS="$OGG_LDFLAGS" + if test "x$theora_prefix" != "x$ogg_prefix"; then + XIPH_GCC_WARNING(-I"$theora_prefix/include",, + [THEORA_CFLAGS="$THEORA_CFLAGS -I$theora_prefix/include" + THEORA_LDFLAGS="-L$theora_prefix/lib $THEORA_LDFLAGS" + ]) + fi + + THEORA_LIBS="-ltheora -logg" + + ac_save_LIBS="$LIBS" + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $THEORA_LDFLAGS" + LIBS="$LIBS $THEORA_LIBS" + AC_MSG_CHECKING([for libtheora]) + AC_TRY_LINK_FUNC(theora_decode_header, [xt_have_theora="yes"], + [xt_have_theora="Not found"]) + if test "x$xt_have_theora" = "xyes" + then + AC_TRY_LINK_FUNC(theora_packet_isheader, [xt_have_theora="yes"], + [xt_have_theora="newer version required"]) + fi + + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + + if test "x$xt_have_theora" = "xyes" + then + AC_MSG_RESULT([ok]) + AC_DEFINE([HAVE_THEORA],[1],[Define if Theora support is available]) + $1 + else + THEORA_CFLAGS="" + THEORA_LDFLAGS="" + THEORA_LIBS="" + AC_MSG_RESULT([$xt_have_theora]) + $2 + fi +fi +AC_SUBST(THEORA_CFLAGS) +AC_SUBST(THEORA_LDFLAGS) +AC_SUBST(THEORA_LIBS) +]) diff --git a/lib/libshout/m4/vorbis.m4 b/lib/libshout/m4/vorbis.m4 new file mode 100644 index 00000000000..17add29bb17 --- /dev/null +++ b/lib/libshout/m4/vorbis.m4 @@ -0,0 +1,92 @@ +# Configure paths for libvorbis +# Jack Moffitt 10-21-2000 +# updated by Karl Heyes 31-Mar-2003 +# Shamelessly stolen from Owen Taylor and Manish Singh + +dnl XIPH_PATH_VORBIS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for libvorbis, and define VORBIS_CFLAGS VORBIS_LIBS +dnl VORBIS_VORBISENC_LIBS VORBIS_VORBISFILE_LIBS VORBIS_LDFLAGS +dnl + +AC_DEFUN([XIPH_PATH_VORBIS], +[dnl +AC_REQUIRE([XIPH_PATH_OGG]) + +dnl Get the cflags and libraries for vorbis +dnl +AC_ARG_VAR([VORBIS_PREFIX],[path to vorbis installation]) +AC_ARG_WITH(vorbis, + AC_HELP_STRING([--with-vorbis=PREFIX], + [Prefix where libvorbis is installed (optional)]), + vorbis_prefix="$withval", + vorbis_prefix="$VORBIS_PREFIX" + ) +if test "x$vorbis_prefix" = "x" -o "x$vorbis_prefix" = "xyes"; then + if test "x$prefix" = "xNONE"; then + vorbis_prefix="/usr/local" + else + vorbis_prefix="$prefix" + fi +fi + +VORBIS_CFLAGS="$OGG_CFLAGS" +VORBIS_LDFLAGS="$OGG_LDFLAGS" +if test "x$vorbis_prefix" != "x$ogg_prefix"; then + XIPH_GCC_WARNING(-I"$vorbis_prefix/include",, + [VORBIS_CFLAGS="$VORBIS_CFLAGS -I$vorbis_prefix/include" + VORBIS_LDFLAGS="-L$vorbis_prefix/lib $VORBIS_LDFLAGS" + ]) +fi + +VORBIS_LIBS="-lvorbis" +VORBISFILE_LIBS="-lvorbisfile" +VORBISENC_LIBS="-lvorbisenc" + +xt_save_LIBS="$LIBS" +xt_save_LDFLAGS="$LDFLAGS" +xt_save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $VORBIS_CFLAGS" +LDFLAGS="$LDFLAGS $VORBIS_LDFLAGS" +LIBS="$LIBS $VORBIS_LIBS" +xt_lib_vorbis="not found" +AC_MSG_CHECKING([for libvorbis]) +AC_TRY_LINK_FUNC(ogg_stream_init, [xt_lib_vorbis=ok], + [LIBS="$LIBS $OGG_LIBS -lm" + AC_TRY_LINK_FUNC(vorbis_info_init, + [xt_lib_vorbis=ok + VORBIS_LIBS="$VORBIS_LIBS $OGG_LIBS -lm"], + ) + ]) + +if test "x$xt_lib_vorbis" = "xok"; then +# +# Now check if the installed Vorbis is sufficiently new. +# +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ +#include +#include + ], [ +struct ovectl_ratemanage_arg a; +])],,[xt_lib_vorbis="old version found"]) +AC_MSG_RESULT([$xt_lib_vorbis]) +fi +CPPFLAGS="$xt_save_CPPFLAGS" +LIBS="$xt_save_LIBS" +LDFLAGS="$xt_save_LDFLAGS" + +if test "x$xt_lib_vorbis" = "xok"; then + ifelse([$1], ,[:], [$1]) +else + VORBIS_CFLAGS="" + VORBIS_LDFLAGS="" + VORBIS_LIBS="" + VORBISFILE_LIBS="" + VORBISENC_LIBS="" + ifelse([$2], ,, [$2]) +fi +AC_SUBST(VORBIS_CFLAGS) +AC_SUBST(VORBIS_LDFLAGS) +AC_SUBST(VORBIS_LIBS) +AC_SUBST(VORBISFILE_LIBS) +AC_SUBST(VORBISENC_LIBS) +]) diff --git a/lib/libshout/m4/xiph_compiler.m4 b/lib/libshout/m4/xiph_compiler.m4 new file mode 100644 index 00000000000..e1739c18902 --- /dev/null +++ b/lib/libshout/m4/xiph_compiler.m4 @@ -0,0 +1,187 @@ +dnl xiph_compiler.m4 +dnl $Id$ + +dnl XIPH_FUNC_VA_COPY +dnl Karl Heyes +dnl +# XIPH_FUNC_VA_COPY +# Test for implementation of va_copy, or define appropriately if missing +AC_DEFUN([XIPH_FUNC_VA_COPY], +[dnl +AC_MSG_CHECKING([for va_copy]) +AC_TRY_LINK([#include ], [va_list ap1, ap2; va_copy(ap1, ap2);], + AC_MSG_RESULT([va_copy]), + [dnl + AH_TEMPLATE([va_copy], [define if va_copy is not available]) + AC_TRY_LINK([#include ], [va_list ap1, ap2; __va_copy(ap1, ap2);], + [dnl + AC_DEFINE([va_copy], [__va_copy]) + AC_MSG_RESULT([__va_copy])], + [dnl + AC_DEFINE([va_copy(dest,src)], [memcpy(&dest,&src,sizeof(va_list))]) + AC_MSG_RESULT([memcpy]) + ]) + ]) +]) +])dnl XIPH_FUNC_VA_COPY + +dnl XIPH_C_ATTRIBUTE +dnl Karl Heyes +dnl +# XIPH_C_ATTRIBUTE +# Define __attribute__ to be empty if the compiler does not support it +AC_DEFUN([XIPH_C_ATTRIBUTE], +[dnl +AC_TRY_COMPILE([int func(void) __attribute__((unused));], + [int x __attribute__ ((unused));],,[dnl + AH_TEMPLATE([__attribute__],[Define to empty if __attribute__ is not supported]) + AC_DEFINE([__attribute__(x)],[]) +]) +])dnl XIPH_C_ATTRIBUTE + +dnl XIPH_GCC_WARNING +dnl Karl Heyes +dnl +# XIPH_GCC_WARNING(flag, action-if-warning, action-if-not) +# Tests whether GCC emits a warning if explicitly asked to use flag. +# Useful for eg system default include paths +AC_DEFUN([XIPH_GCC_WARNING], +[AC_REQUIRE([AC_PROG_CC]) +xt_warning=no +if test x"$GCC" = "xyes" +then + save_cflags="$CFLAGS" + CFLAGS="-Werror $1" + AC_TRY_COMPILE(,,,xt_warning=yes) + CFLAGS="$save_cflags" +fi +if test "$xt_warning" = "yes" +then + ifelse([$2],,:,[$2]) +else + ifelse([$3],,:,[$3]) +fi +])dnl XIPH_GCC_WARNING + +dnl XIPH_CLEAN_CCFLAGS +dnl Brendan Cully 20030612 +dnl +# XIPH_CLEAN_CCFLAGS(flag-list, dest-shell-var-name) +# Filters out duplicate compiler flags, and -I flags if XIPH_GCC_WARNING +# complains about them +# Operates right-to-left on -l flags, left-to-right on everything else +# eg XIPH_CLEAN_CCFLAGS([-L/opt/lib -lfoo -lm -L/opt/lib -lbar -lm], [MY_LDFLAGS]) +# => MY_LDFLAGS="-L/opt/lib -lfoo -lbar -lm" +# the cat< /dev/null + then + xt_FLAGS="$flag $xt_FLAGS" + fi + ;; + esac +done + +$2='' +for flag in $xt_FLAGS +do + if { cat < /dev/null + then + $2="$flag $$2" + fi +done + +# Prune -I flags if $CC warns about them +xt_FLAGS='' +for flag in $$2 +do + case "$flag" in + -I*) + XIPH_GCC_WARNING([$flag], [], [xt_FLAGS="$xt_FLAGS $flag"]) + ;; + *) + xt_FLAGS="$xt_FLAGS $flag" + ;; + esac +done +$2="$xt_FLAGS" +])dnl XIPH_CLEAN_CCFLAGS + +dnl XIPH_VAR_APPEND +dnl Karl Heyes +dnl +# XIPH_VAR_APPEND(shell-var, list) +# Append each item in list to shell-var iff shell-var doesn't already have it +# eg XIPH_VAR_APPEND([CFLAGS], [-O2 -I/opt/packages/include]) +AC_DEFUN([XIPH_VAR_APPEND], +[dnl +AC_REQUIRE([AC_PROG_FGREP]) +for arg in $2 +do + if { cat < /dev/null + then + $1="$$1 $arg" + fi +done +])dnl XIPH_VAR_APPEND + +dnl XIPH_VAR_PREPEND +dnl Karl Heyes +dnl +# XIPH_VAR_PREPEND(shell-var, list) +# see XIPH_VAR_APPEND +AC_DEFUN([XIPH_VAR_PREPEND], +[dnl +AC_REQUIRE([AC_PROG_FGREP]) +xt_compare="$$1" +xt_filtered="" +for arg in $2 +do + if { cat < /dev/null + then + xt_compare="$arg $xt_compare" + xt_filtered="$xt_filtered $arg" + fi +done +$1="$xt_filtered $$1" +])dnl XIPH_VAR_PREPEND + +dnl XIPH_C__FUNC__ +dnl Karl Heyes 07/2004 +AC_DEFUN([XIPH_C__FUNC__], +[dnl +AC_MSG_CHECKING([for __func__]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[const char *x = __func__;])], + [ AC_MSG_RESULT([yes])], + [ AH_TEMPLATE([__func__], [Replace __func__ if not supported]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[const char *x = __FUNCTION__;])], + [ AC_DEFINE([__func__],[__FUNCTION__]) + AC_MSG_RESULT([Using __FUNCTION__])], + [ AC_DEFINE([__func__],["__FILE__"]) + AC_MSG_RESULT([using __FILE__]) + ]) + ]) +])dnl XIPH_C__FUNC__ + diff --git a/lib/libshout/m4/xiph_net.m4 b/lib/libshout/m4/xiph_net.m4 new file mode 100644 index 00000000000..db63963ccda --- /dev/null +++ b/lib/libshout/m4/xiph_net.m4 @@ -0,0 +1,26 @@ +# XIPH_NET +# Perform tests required by the net module +AC_DEFUN([XIPH_NET], +[dnl +AC_REQUIRE([XIPH_TYPE_SOCKLEN_T]) +AC_REQUIRE([XIPH_FUNC_VA_COPY]) +AC_CHECK_HEADERS([sys/select.h sys/uio.h]) +AC_CHECK_HEADER([winsock2.h], + [AC_DEFINE([HAVE_WINSOCK2_H], [1], [Define if you have winsock2.h on MINGW]) + LIBS="$LIBS -lwsock32"]) + +# These tests are ordered based on solaris 8 tests +AC_SEARCH_LIBS([sethostent], [nsl], + [AC_DEFINE([HAVE_SETHOSTENT], [1], + [Define if you have the sethostent function])]) +AC_SEARCH_LIBS([getnameinfo], [socket], + [AC_DEFINE([HAVE_GETNAMEINFO], [1], + [Define if you have the getnameinfo function])]) +AC_CHECK_FUNCS([endhostent getaddrinfo inet_aton writev]) + +# Irix defines INET_PTON but not sockaddr_storage! +AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], + [AC_CHECK_FUNCS([inet_pton])],, + [#include +#include ]) +]) diff --git a/lib/libshout/m4/xiph_openssl.m4 b/lib/libshout/m4/xiph_openssl.m4 new file mode 100644 index 00000000000..f62a52449ae --- /dev/null +++ b/lib/libshout/m4/xiph_openssl.m4 @@ -0,0 +1,49 @@ +dnl XIPH_PATH_OPENSSL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Karl Heyes +dnl Test for openssl, and define OPENSSL_CFLAGS and OPENSSL_LIBS +dnl +AC_DEFUN([XIPH_PATH_OPENSSL], +[dnl +dnl Get the cflags and libraries +dnl +AC_ARG_WITH(openssl, + AC_HELP_STRING([--with-openssl=PFX],[Prefix where openssl is installed (optional)]), + openssl_prefix="$withval", openssl_prefix="") + +if test "x$openssl_prefix" != "x" -a "x$openssl_prefix" != "xyes"; then + OPENSSL_LIBS="-L$openssl_prefix/lib -lssl" + OPENSSL_CFLAGS="-I$openssl_prefix/include" +else + AC_PATH_PROG([PKGCONFIG], [pkg-config], [no]) + if test "$PKGCONFIG" != "no" && `$PKGCONFIG --exists openssl`; then + OPENSSL_CFLAGS=`$PKGCONFIG --cflags openssl` + OPENSSL_LIBS=`$PKGCONFIG --libs openssl` + else + if test "x$prefix" = "xNONE"; then + openssl_prefix="/usr/local" + else + openssl_prefix="$prefix" + fi + OPENSSL_LIBS="-L$openssl_prefix/lib -lssl" + OPENSSL_CFLAGS="-I$openssl_prefix/include" + fi +fi + +# Now try linking to openssl +xt_save_CFLAGS="$CFLAGS" +xt_save_LIBS="$LIBS" +CFLAGS="$CFLAGS $OPENSSL_CFLAGS" +LIBS="$OPENSSL_LIBS $LIBS" +AC_TRY_LINK([#include ], [void *a = SSL_new], [openssl_ok='yes']) +CFLAGS="$xt_save_CFLAGS" +LIBS="$xt_save_LIBS" + +if test "$openssl_ok" = "yes"; then + AC_DEFINE(HAVE_OPENSSL, 1, [Define if you have libopenssl.]) + ifelse([$1], , :, [$1]) +else + OPENSSL_LIBS="" + OPENSSL_CFLAGS="" + ifelse([$2], , :, [$2]) +fi +]) diff --git a/lib/libshout/m4/xiph_types.m4 b/lib/libshout/m4/xiph_types.m4 new file mode 100644 index 00000000000..718bd9a2d4e --- /dev/null +++ b/lib/libshout/m4/xiph_types.m4 @@ -0,0 +1,59 @@ +dnl xiph_types.m4 +dnl macros for type checks not covered by autoconf + +dnl XIPH_C99_INTTYPES +dnl Brendan Cully +dnl +# XIPH_C99_INTTYPES +# Check for C99 integer type definitions, or define if missing +AC_DEFUN([XIPH_C99_INTTYPES], +[dnl +AC_CHECK_HEADERS([inttypes.h]) +AC_CHECK_TYPE([uint32_t], + [AC_DEFINE(HAVE_C99_INTTYPES, 1, [Define if you have the C99 integer types])], + [AC_CHECK_SIZEOF(short) + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(long long)]) +AH_VERBATIM([X_HAVE_C99_INTTYPES], + [#ifndef HAVE_C99_INTTYPES +# if SIZEOF_SHORT == 4 +typedef unsigned short uint32_t; +# elif SIZEOF_INT == 4 +typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 +typedef unsigned long uint32_t; +# endif +# if SIZEOF_INT == 8 +typedef unsigned int uint64_t; +# elif SIZEOF_LONG == 8 +typedef unsigned long uint64_t; +# elif SIZEOF_LONG_LONG == 8 +typedef unsigned long long uint64_t; +# endif +#endif + ]) +]) + +dnl XIPH_TYPE_SOCKLEN_T +dnl Brendan Cully +dnl +# XIPH_TYPE_SOCKLEN_T +# Check for socklen_t, or define as int if missing +AC_DEFUN([XIPH_TYPE_SOCKLEN_T], +[dnl +AC_CHECK_HEADERS([sys/socket.h]) +AC_CHECK_TYPES([socklen_t],,, + [#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_SOCKET_H +# include +#endif + ]) +AH_VERBATIM([X_HAVE_SOCKLEN_T], + [#ifndef HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + ]) +]) diff --git a/lib/libshout/patches/01-libshout-tls-compile-with-OpenSSL-1.1.0.patch b/lib/libshout/patches/01-libshout-tls-compile-with-OpenSSL-1.1.0.patch new file mode 100644 index 00000000000..befd16e3846 --- /dev/null +++ b/lib/libshout/patches/01-libshout-tls-compile-with-OpenSSL-1.1.0.patch @@ -0,0 +1,58 @@ +From 01fafc449f0de56743d08e7976933c49e2915bfa Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Wed, 15 Nov 2017 12:46:25 +0000 +Subject: [PATCH] tls: compile with OpenSSL 1.1.0 + +The init functions are not longer required in OpenSSL 1.1 so I dropped +them. + +TLSv1_client_method() should not be used because it enables only the +TLSv1.0 protocol. Better is to use SSLv23_client_method() which enable +all the protocols including TLSv1.2. With this functions SSLv2 and SSLv3 +is theoretically possible but as of today those protocols are usually +build-time disabled. +To avoid all this OpenSSL 1.1 provides TLS_client_method() which is aim +to provide to highest TLS protocol version (same as +SSLv23_client_method() but it is deprecated in 1.1). + +Signed-off-by: Sebastian Andrzej Siewior +--- + src/tls.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/tls.c b/src/tls.c +index 4562c7327077..e0e5c1a5f079 100644 +--- a/src/tls.c ++++ b/src/tls.c +@@ -24,6 +24,7 @@ + #endif + + #include ++#include + #include "shout_private.h" + + #ifndef XXX_HAVE_X509_check_host +@@ -61,14 +62,17 @@ shout_tls_t *shout_tls_new(shout_t *self, sock_t socket) + + static inline int tls_setup(shout_tls_t *tls) + { +- SSL_METHOD *meth; +- ++ const SSL_METHOD *meth; ++#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) + SSL_library_init(); + SSL_load_error_strings(); + SSLeay_add_all_algorithms(); +- SSLeay_add_ssl_algorithms(); ++ SSLeay_add_ssl_algorithms(); + +- meth = TLSv1_client_method(); ++ meth = SSLv23_client_method(); ++#else ++ meth = TLS_client_method(); ++#endif + if (!meth) + goto error; + +-- +2.15.0 diff --git a/lib/libshout/shout.pc.in b/lib/libshout/shout.pc.in new file mode 100644 index 00000000000..867a0be60fc --- /dev/null +++ b/lib/libshout/shout.pc.in @@ -0,0 +1,15 @@ +# libshout pkg-config source file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +cppflags=@SHOUT_CPPFLAGS@ +cflags_only=@SHOUT_CFLAGS@ + +Name: Shout +Description: Audio streaming library for icecast encoders +Version: @VERSION@ +Requires.private: @SHOUT_REQUIRES@ +Libs: -L${libdir} -lshout +Cflags: -I${includedir} @PTHREAD_CPPFLAGS@ @SHOUT_CFLAGS@ diff --git a/lib/libshout/src/Makefile.am b/lib/libshout/src/Makefile.am new file mode 100644 index 00000000000..af1dab33889 --- /dev/null +++ b/lib/libshout/src/Makefile.am @@ -0,0 +1,44 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign 1.6 + +if HAVE_THREAD + MAYBE_THREAD = common/thread + MAYBE_THREAD_LIB = common/thread/libicethread.la +endif + +if HAVE_THEORA + MAYBE_THEORA = codec_theora.c +endif + +if HAVE_SPEEX + MAYBE_SPEEX = codec_speex.c +endif + +if HAVE_TLS + MAYBE_TLS = tls.c +endif + +SUBDIRS = common/avl common/net common/timing common/httpp $(MAYBE_THREAD) + +lib_LTLIBRARIES = libshout.la +libshout_la_LDFLAGS = -version-info 5:0:2 + +EXTRA_DIST = codec_theora.c codec_speex.c tls.c +noinst_HEADERS = format_ogg.h shout_private.h util.h +PROTOCOLS=proto_http.c proto_xaudiocast.c proto_icy.c proto_roaraudio.c +FORMATS=format_ogg.c format_webm.c format_mp3.c +CODECS=codec_vorbis.c codec_opus.c $(MAYBE_THEORA) $(MAYBE_SPEEX) +libshout_la_SOURCES = shout.c util.c queue.c $(PROTOCOLS) $(FORMATS) $(CODECS) $(MAYBE_TLS) +AM_CFLAGS = @XIPH_CFLAGS@ + +libshout_la_LIBADD = common/net/libicenet.la common/timing/libicetiming.la common/avl/libiceavl.la\ + common/httpp/libicehttpp.la $(MAYBE_THREAD_LIB) $(THEORA_LIBS) $(VORBIS_LIBS) $(SPEEX_LIBS) @XIPH_LIBS@ + +INCLUDES = -I$(top_builddir)/include -I./common/ + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" diff --git a/lib/libshout/src/codec_opus.c b/lib/libshout/src/codec_opus.c new file mode 100644 index 00000000000..45b0ee8eb72 --- /dev/null +++ b/lib/libshout/src/codec_opus.c @@ -0,0 +1,284 @@ +/* -*- c-basic-offset: 8; -*- */ +/* opus.c: Ogg Opus data handlers for libshout + * + * Copyright (C) 2005 the Icecast team + * Copyright (C) 2011,2012 Xiph.Org Foundation + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif +#include + +#include + +#include "shout_private.h" +#include "format_ogg.h" + +/* -- local data structures -- */ +typedef struct { + int version; + int channels; /* Number of channels: 1..255 */ + int preskip; + uint32_t input_sample_rate; + int gain; /* in dB S7.8 should be zero whenever possible */ + int channel_mapping; + /* The rest is only used if channel_mapping != 0 */ + int nb_streams; + int nb_coupled; + unsigned char stream_map[255]; +} OpusHeader; + +typedef struct { + OpusHeader oh; + int skipped; +} opus_data_t; + +typedef struct { + const unsigned char *data; + int maxlen; + int pos; +} ROPacket; + +/* -- local prototypes -- */ +static int read_opus_page(ogg_codec_t *codec, ogg_page *page); +static void free_opus_data(void *codec_data); +static int opus_header_parse(const unsigned char *header, int len, OpusHeader *h); + +/* -- header functions -- */ + +static int read_uint32(ROPacket *p, uint32_t *val) +{ + if (p->pos>p->maxlen-4) + return 0; + *val = (uint32_t)p->data[p->pos ]; + *val |= (uint32_t)p->data[p->pos+1]<< 8; + *val |= (uint32_t)p->data[p->pos+2]<<16; + *val |= (uint32_t)p->data[p->pos+3]<<24; + p->pos += 4; + return 1; +} + +static int read_uint16(ROPacket *p, uint16_t *val) +{ + if (p->pos>p->maxlen-2) + return 0; + *val = (uint16_t)p->data[p->pos ]; + *val |= (uint16_t)p->data[p->pos+1]<<8; + p->pos += 2; + return 1; +} + +static int read_chars(ROPacket *p, unsigned char *str, int nb_chars) +{ + int i; + if (p->pos>p->maxlen-nb_chars) + return 0; + for (i=0;idata[p->pos++]; + return 1; +} + +static int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h) +{ + int i; + char str[9]; + ROPacket p; + unsigned char ch; + uint16_t shortval; + + p.data = packet; + p.maxlen = len; + p.pos = 0; + str[8] = 0; + if(len<19)return 0; + read_chars(&p, (unsigned char*)str, 8); + if (strcmp(str, "OpusHead")!=0) + return 0; + + if (!read_chars(&p, &ch, 1)) + return 0; + h->version = ch; + if((h->version&240) != 0) /* Only major version 0 supported. */ + return 0; + + if (!read_chars(&p, &ch, 1)) + return 0; + h->channels = ch; + if (h->channels == 0) + return 0; + + if (!read_uint16(&p, &shortval)) + return 0; + h->preskip = shortval; + + if (!read_uint32(&p, &h->input_sample_rate)) + return 0; + + if (!read_uint16(&p, &shortval)) + return 0; + h->gain = (short)shortval; + + if (!read_chars(&p, &ch, 1)) + return 0; + h->channel_mapping = ch; + + if (h->channel_mapping != 0) + { + if (!read_chars(&p, &ch, 1)) + return 0; + h->nb_streams = ch; + + if (!read_chars(&p, &ch, 1)) + return 0; + h->nb_coupled = ch; + + /* Multi-stream support */ + for (i=0;ichannels;i++) + { + if (!read_chars(&p, &h->stream_map[i], 1)) + return 0; + } + } else { + h->nb_streams = 1; + h->nb_coupled = h->channels>1; + h->stream_map[0]=0; + h->stream_map[1]=1; + } + /*For version 0/1 we know there won't be any more data + so reject any that have data past the end.*/ + if ((h->version==0 || h->version==1) && p.pos != len) + return 0; + return 1; +} + +/* From libopus, src/opus_decode.c */ +static int packet_get_samples_per_frame(const unsigned char *data, int32_t Fs) +{ + int audiosize; + if (data[0]&0x80) + { + audiosize = ((data[0]>>3)&0x3); + audiosize = (Fs<>3)&0x3); + if (audiosize == 3) + audiosize = Fs*60/1000; + else + audiosize = (Fs<os, &packet); + + if (!opus_header_parse(packet.packet,packet.bytes,&opus_data->oh)) { + free_opus_data(opus_data); + return SHOUTERR_UNSUPPORTED; + } + opus_data->skipped = 0; + + codec->codec_data = opus_data; + codec->read_page = read_opus_page; + codec->free_data = free_opus_data; + + return SHOUTERR_SUCCESS; +} + +static int read_opus_page(ogg_codec_t *codec, ogg_page *page) +{ + ogg_packet packet; + opus_data_t *opus_data = codec->codec_data; + + (void)page; + + /* We use the strategy of counting the packet times and ignoring + the granpos. This has the advantage of needing less code to + sanely handle non-zero starttimes and slightly saner behavior + on files with holes. */ + while (ogg_stream_packetout (&codec->os, &packet) > 0){ + if(packet.bytes>0 && (packet.bytes<2 || memcmp(packet.packet, "Op",2)!=0)){ + int32_t spf; + spf = packet_get_samples_per_frame(packet.packet,48000); + if(spf>0){ + int32_t spp; + spp=packet_get_nb_frames(packet.packet,packet.bytes); + if(spp>0){ + int needskip; + needskip=opus_data->oh.preskip-opus_data->skipped; + spp*=spf; + /*Opus files can begin with some frames which are + just there to prime the decoder and are not played + these should just be sent as fast as we get them.*/ + if(needskip>0){ + int skip; + skip = sppskipped+=skip; + } + codec->senttime += ((spp * 1000000ULL) / 48000ULL); + } + }else if (packet.bytes>=19 && memcmp(packet.packet, "OpusHead",8)==0){ + /* We appear to be chaining, reset skip to burst the pregap. */ + if(opus_header_parse(packet.packet,packet.bytes,&opus_data->oh)) + opus_data->skipped=0; + } + } + } + + return SHOUTERR_SUCCESS; +} + +static void free_opus_data(void *codec_data) +{ + free(codec_data); +} diff --git a/lib/libshout/src/codec_speex.c b/lib/libshout/src/codec_speex.c new file mode 100644 index 00000000000..65e9a208309 --- /dev/null +++ b/lib/libshout/src/codec_speex.c @@ -0,0 +1,90 @@ +/* -*- c-basic-offset: 8; -*- */ +/* speex.c: Ogg Speex data handlers for libshout + * + * Copyright (C) 2005 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "shout_private.h" +#include "format_ogg.h" + +/* -- local data structures -- */ +typedef struct { + SpeexHeader *sh; +} speex_data_t; + +/* -- local prototypes -- */ +static int read_speex_page(ogg_codec_t *codec, ogg_page *page); +static void free_speex_data(void *codec_data); + +/* -- speex functions -- */ +int _shout_open_speex(ogg_codec_t *codec, ogg_page *page) +{ + speex_data_t *speex_data = calloc(1, sizeof(speex_data_t)); + ogg_packet packet; + + (void)page; + + if (!speex_data) + return SHOUTERR_MALLOC; + + ogg_stream_packetout(&codec->os, &packet); + + if (!(speex_data->sh = speex_packet_to_header((char*)packet.packet,packet.bytes))) { + free_speex_data(speex_data); + + return SHOUTERR_UNSUPPORTED; + } + + codec->codec_data = speex_data; + codec->read_page = read_speex_page; + codec->free_data = free_speex_data; + + return SHOUTERR_SUCCESS; +} + +static int read_speex_page(ogg_codec_t *codec, ogg_page *page) +{ + ogg_packet packet; + speex_data_t *speex_data = codec->codec_data; + uint64_t samples = 0; + + (void)page; + + while (ogg_stream_packetout (&codec->os, &packet) > 0) + samples += speex_data->sh->frames_per_packet * speex_data->sh->frame_size; + + codec->senttime += ((samples * 1000000) / speex_data->sh->rate); + + return SHOUTERR_SUCCESS; +} + +static void free_speex_data(void *codec_data) +{ + speex_data_t *speex_data = (speex_data_t *)codec_data; + + if (speex_data->sh) + free(speex_data->sh); + + free(speex_data); +} diff --git a/lib/libshout/src/codec_theora.c b/lib/libshout/src/codec_theora.c new file mode 100644 index 00000000000..fc1819cfc4b --- /dev/null +++ b/lib/libshout/src/codec_theora.c @@ -0,0 +1,154 @@ +/* -*- c-basic-offset: 8; -*- */ +/* theora.c: Ogg Theora data handlers for libshout + * $Id$ + * + * Copyright (C) 2004 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_INTTYPES_H +# include +#endif +#include + +#include + +#include "shout_private.h" +#include "format_ogg.h" + +/* -- local data structures -- */ +typedef struct { + theora_info ti; + theora_comment tc; + uint32_t granule_shift; + double per_frame; + uint64_t start_frame; + int initial_frames; + int get_start_frame; +} theora_data_t; + +/* -- local prototypes -- */ +static int read_theora_page(ogg_codec_t *codec, ogg_page *page); +static void free_theora_data(void *codec_data); +static int theora_ilog(unsigned int v); + +/* -- theora functions -- */ +int _shout_open_theora(ogg_codec_t *codec, ogg_page *page) +{ + ogg_packet packet; + + (void)page; + + theora_data_t *theora_data = calloc(1, sizeof(theora_data_t)); + if (! theora_data) + return SHOUTERR_MALLOC; + + theora_info_init(&theora_data->ti); + theora_comment_init(&theora_data->tc); + + ogg_stream_packetout(&codec->os, &packet); + + if (theora_decode_header(&theora_data->ti, &theora_data->tc, &packet) < 0) { + free_theora_data(theora_data); + + return SHOUTERR_UNSUPPORTED; + } + + codec->codec_data = theora_data; + codec->read_page = read_theora_page; + codec->free_data = free_theora_data; + codec->headers = 1; + theora_data->initial_frames = 0; + + return SHOUTERR_SUCCESS; +} + +static int read_theora_page(ogg_codec_t *codec, ogg_page *page) +{ + theora_data_t *theora_data = codec->codec_data; + ogg_packet packet; + ogg_int64_t granulepos, iframe, pframe; + + granulepos = ogg_page_granulepos(page); + + if (granulepos == 0) + { + while (ogg_stream_packetout(&codec->os, &packet) > 0) { + if (theora_decode_header(&theora_data->ti, &theora_data->tc, &packet) < 0) + return SHOUTERR_INSANE; + codec->headers++; + } + if (codec->headers == 3) + { + theora_data->granule_shift = theora_ilog(theora_data->ti.keyframe_frequency_force - 1); + theora_data->per_frame = (double)theora_data->ti.fps_denominator / theora_data->ti.fps_numerator * 1000000; + theora_data->get_start_frame = 1; + } + + return SHOUTERR_SUCCESS; + } + + while (ogg_stream_packetout(&codec->os, &packet) > 0) + { + if (theora_data->get_start_frame) + theora_data->initial_frames++; + } + if (granulepos > 0 && codec->headers >= 3) + { + iframe = granulepos >> theora_data->granule_shift; + pframe = granulepos - (iframe << theora_data->granule_shift); + + if (theora_data->get_start_frame) + { + /* work out the real start frame, which may not be 0 */ + theora_data->start_frame = iframe + pframe - theora_data->initial_frames; + codec->senttime = 0; + theora_data->get_start_frame = 0; + } + else + { + uint64_t frames = ((iframe + pframe) - theora_data->start_frame); + codec->senttime = (uint64_t)(frames * theora_data->per_frame); + } + } + + return SHOUTERR_SUCCESS; +} + +static void free_theora_data(void *codec_data) +{ + theora_data_t *theora_data = (theora_data_t *)codec_data; + + theora_info_clear(&theora_data->ti); + theora_comment_clear(&theora_data->tc); + free(theora_data); +} + +static int theora_ilog(unsigned int v) +{ + int ret = 0; + + while (v) { + ret++; + v >>= 1; + } + + return ret; +} diff --git a/lib/libshout/src/codec_vorbis.c b/lib/libshout/src/codec_vorbis.c new file mode 100644 index 00000000000..7917f239455 --- /dev/null +++ b/lib/libshout/src/codec_vorbis.c @@ -0,0 +1,124 @@ +/* -*- c-basic-offset: 8; -*- */ +/* vorbis.c: Ogg Vorbis data handlers for libshout + * $Id$ + * + * Copyright (C) 2002-2004 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif +#include + +#include + +#include "shout_private.h" +#include "format_ogg.h" + +/* -- local data structures -- */ +typedef struct { + vorbis_info vi; + vorbis_comment vc; + int prevW; +} vorbis_data_t; + +/* -- local prototypes -- */ +static int read_vorbis_page(ogg_codec_t *codec, ogg_page *page); +static void free_vorbis_data(void *codec_data); +static int vorbis_blocksize(vorbis_data_t *vd, ogg_packet *p); + +/* -- vorbis functions -- */ +int _shout_open_vorbis(ogg_codec_t *codec, ogg_page *page) +{ + vorbis_data_t *vorbis_data = calloc(1, sizeof(vorbis_data_t)); + ogg_packet packet; + + (void)page; + + if (!vorbis_data) + return SHOUTERR_MALLOC; + + vorbis_info_init(&vorbis_data->vi); + vorbis_comment_init(&vorbis_data->vc); + + ogg_stream_packetout(&codec->os, &packet); + + if (vorbis_synthesis_headerin(&vorbis_data->vi, &vorbis_data->vc, &packet) < 0) { + free_vorbis_data(vorbis_data); + + return SHOUTERR_UNSUPPORTED; + } + + codec->codec_data = vorbis_data; + codec->read_page = read_vorbis_page; + codec->free_data = free_vorbis_data; + + return SHOUTERR_SUCCESS; +} + +static int read_vorbis_page(ogg_codec_t *codec, ogg_page *page) +{ + ogg_packet packet; + vorbis_data_t *vorbis_data = codec->codec_data; + uint64_t samples = 0; + + (void)page; + + if (codec->headers < 3) { + while (ogg_stream_packetout (&codec->os, &packet) > 0) { + if (vorbis_synthesis_headerin(&vorbis_data->vi, &vorbis_data->vc, &packet) < 0) + return SHOUTERR_INSANE; + codec->headers++; + } + + return SHOUTERR_SUCCESS; + } + + while (ogg_stream_packetout (&codec->os, &packet) > 0) + samples += vorbis_blocksize(vorbis_data, &packet); + + codec->senttime += ((samples * 1000000) / vorbis_data->vi.rate); + + return SHOUTERR_SUCCESS; +} + +static void free_vorbis_data(void *codec_data) +{ + vorbis_data_t *vorbis_data = (vorbis_data_t *)codec_data; + + vorbis_info_clear(&vorbis_data->vi); + vorbis_comment_clear(&vorbis_data->vc); + free(vorbis_data); +} + +static int vorbis_blocksize(vorbis_data_t *vd, ogg_packet *p) +{ + int this = vorbis_packet_blocksize(&vd->vi, p); + int ret = (this + vd->prevW)/4; + + if(!vd->prevW) { + vd->prevW = this; + return 0; + } + + vd->prevW = this; + return ret; +} diff --git a/lib/libshout/src/common/avl/BUILDING b/lib/libshout/src/common/avl/BUILDING new file mode 100644 index 00000000000..0aa7006f570 --- /dev/null +++ b/lib/libshout/src/common/avl/BUILDING @@ -0,0 +1,7 @@ +defines that affect compilation + +none + +library dependencies + +none diff --git a/lib/libshout/src/common/avl/COPYING b/lib/libshout/src/common/avl/COPYING new file mode 100644 index 00000000000..92b8903ff3f --- /dev/null +++ b/lib/libshout/src/common/avl/COPYING @@ -0,0 +1,481 @@ + 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 + + 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 + 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! diff --git a/lib/libshout/src/common/avl/Makefile.am b/lib/libshout/src/common/avl/Makefile.am new file mode 100644 index 00000000000..2e935a463f1 --- /dev/null +++ b/lib/libshout/src/common/avl/Makefile.am @@ -0,0 +1,20 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = BUILDING COPYING README TODO avl.dsp test.c + +noinst_LTLIBRARIES = libiceavl.la +noinst_HEADERS = avl.h + +libiceavl_la_SOURCES = avl.c +libiceavl_la_CFLAGS = @XIPH_CFLAGS@ + +INCLUDES = -I$(srcdir)/.. + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" + diff --git a/lib/libshout/src/common/avl/README b/lib/libshout/src/common/avl/README new file mode 100644 index 00000000000..6b9d490fc00 --- /dev/null +++ b/lib/libshout/src/common/avl/README @@ -0,0 +1,6 @@ +this is the avl tree library. + +lgpl + +by sam rushing +modified by jack moffitt diff --git a/lib/libshout/src/common/avl/TODO b/lib/libshout/src/common/avl/TODO new file mode 100644 index 00000000000..4648207136f --- /dev/null +++ b/lib/libshout/src/common/avl/TODO @@ -0,0 +1,2 @@ +- avl_get_last() +- a little more cleanup probably diff --git a/lib/libshout/src/common/avl/avl.c b/lib/libshout/src/common/avl/avl.c new file mode 100644 index 00000000000..5653440e014 --- /dev/null +++ b/lib/libshout/src/common/avl/avl.c @@ -0,0 +1,1194 @@ +/* + * Copyright (C) 1995-1997 by Sam Rushing + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of Sam + * Rushing not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. + * + * SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* $Id: avl.c,v 1.11 2004/01/27 02:16:25 karl Exp $ */ + +/* + * This is a fairly straightfoward translation of a prototype + * written in python, 'avl_tree.py'. Read that file first. + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#include "avl.h" + +avl_node * +avl_node_new (void * key, + avl_node * parent) +{ + avl_node * node = (avl_node *) malloc (sizeof (avl_node)); + + if (!node) { + return NULL; + } else { + node->parent = parent; + node->key = key; + node->left = NULL; + node->right = NULL; + node->rank_and_balance = 0; + AVL_SET_BALANCE (node, 0); + AVL_SET_RANK (node, 1); +#ifdef HAVE_AVL_NODE_LOCK + thread_rwlock_create(&node->rwlock); +#endif + return node; + } +} + +avl_tree * +avl_tree_new (avl_key_compare_fun_type compare_fun, + void * compare_arg) +{ + avl_tree * t = (avl_tree *) malloc (sizeof (avl_tree)); + + if (!t) { + return NULL; + } else { + avl_node * root = avl_node_new((void *)NULL, (avl_node *) NULL); + if (!root) { + free (t); + return NULL; + } else { + t->root = root; + t->height = 0; + t->length = 0; + t->compare_fun = compare_fun; + t->compare_arg = compare_arg; + thread_rwlock_create(&t->rwlock); + return t; + } + } +} + +static void +avl_tree_free_helper (avl_node * node, avl_free_key_fun_type free_key_fun) +{ + if (node->left) { + avl_tree_free_helper (node->left, free_key_fun); + } + if (free_key_fun) + free_key_fun (node->key); + if (node->right) { + avl_tree_free_helper (node->right, free_key_fun); + } +#ifdef HAVE_AVL_NODE_LOCK + thread_rwlock_destroy (&node->rwlock); +#endif + free (node); +} + +void +avl_tree_free (avl_tree * tree, avl_free_key_fun_type free_key_fun) +{ + if (tree->length) { + avl_tree_free_helper (tree->root->right, free_key_fun); + } + if (tree->root) { +#ifdef HAVE_AVL_NODE_LOCK + thread_rwlock_destroy(&tree->root->rwlock); +#endif + free (tree->root); + } + thread_rwlock_destroy(&tree->rwlock); + free (tree); +} + +int +avl_insert (avl_tree * ob, + void * key) +{ + if (!(ob->root->right)) { + avl_node * node = avl_node_new (key, ob->root); + if (!node) { + return -1; + } else { + ob->root->right = node; + ob->length = ob->length + 1; + return 0; + } + } else { /* not self.right == None */ + avl_node *t, *p, *s, *q, *r; + int a; + + t = ob->root; + s = p = t->right; + + while (1) { + if (ob->compare_fun (ob->compare_arg, key, p->key) < 1) { + /* move left */ + AVL_SET_RANK (p, (AVL_GET_RANK (p) + 1)); + q = p->left; + if (!q) { + /* insert */ + avl_node * q_node = avl_node_new (key, p); + if (!q_node) { + return (-1); + } else { + q = q_node; + p->left = q; + break; + } + } else if (AVL_GET_BALANCE(q)) { + t = p; + s = q; + } + p = q; + } else { + /* move right */ + q = p->right; + if (!q) { + /* insert */ + avl_node * q_node = avl_node_new (key, p); + if (!q_node) { + return -1; + } else { + q = q_node; + p->right = q; + break; + } + } else if (AVL_GET_BALANCE(q)) { + t = p; + s = q; + } + p = q; + } + } + + ob->length = ob->length + 1; + + /* adjust balance factors */ + if (ob->compare_fun (ob->compare_arg, key, s->key) < 1) { + r = p = s->left; + } else { + r = p = s->right; + } + while (p != q) { + if (ob->compare_fun (ob->compare_arg, key, p->key) < 1) { + AVL_SET_BALANCE (p, -1); + p = p->left; + } else { + AVL_SET_BALANCE (p, +1); + p = p->right; + } + } + + /* balancing act */ + + if (ob->compare_fun (ob->compare_arg, key, s->key) < 1) { + a = -1; + } else { + a = +1; + } + + if (AVL_GET_BALANCE (s) == 0) { + AVL_SET_BALANCE (s, a); + ob->height = ob->height + 1; + return 0; + } else if (AVL_GET_BALANCE (s) == -a) { + AVL_SET_BALANCE (s, 0); + return 0; + } else if (AVL_GET_BALANCE(s) == a) { + if (AVL_GET_BALANCE (r) == a) { + /* single rotation */ + p = r; + if (a == -1) { + s->left = r->right; + if (r->right) { + r->right->parent = s; + } + r->right = s; + s->parent = r; + AVL_SET_RANK (s, (AVL_GET_RANK (s) - AVL_GET_RANK (r))); + } else { + s->right = r->left; + if (r->left) { + r->left->parent = s; + } + r->left = s; + s->parent = r; + AVL_SET_RANK (r, (AVL_GET_RANK (r) + AVL_GET_RANK (s))); + } + AVL_SET_BALANCE (s, 0); + AVL_SET_BALANCE (r, 0); + } else if (AVL_GET_BALANCE (r) == -a) { + /* double rotation */ + if (a == -1) { + p = r->right; + r->right = p->left; + if (p->left) { + p->left->parent = r; + } + p->left = r; + r->parent = p; + s->left = p->right; + if (p->right) { + p->right->parent = s; + } + p->right = s; + s->parent = p; + AVL_SET_RANK (p, (AVL_GET_RANK (p) + AVL_GET_RANK (r))); + AVL_SET_RANK (s, (AVL_GET_RANK (s) - AVL_GET_RANK (p))); + } else { + p = r->left; + r->left = p->right; + if (p->right) { + p->right->parent = r; + } + p->right = r; + r->parent = p; + s->right = p->left; + if (p->left) { + p->left->parent = s; + } + p->left = s; + s->parent = p; + AVL_SET_RANK (r, (AVL_GET_RANK (r) - AVL_GET_RANK (p))); + AVL_SET_RANK (p, (AVL_GET_RANK (p) + AVL_GET_RANK (s))); + } + if (AVL_GET_BALANCE (p) == a) { + AVL_SET_BALANCE (s, -a); + AVL_SET_BALANCE (r, 0); + } else if (AVL_GET_BALANCE (p) == -a) { + AVL_SET_BALANCE (s, 0); + AVL_SET_BALANCE (r, a); + } else { + AVL_SET_BALANCE (s, 0); + AVL_SET_BALANCE (r, 0); + } + AVL_SET_BALANCE (p, 0); + } + /* finishing touch */ + if (s == t->right) { + t->right = p; + } else { + t->left = p; + } + p->parent = t; + } + } + return 0; +} + +int +avl_get_by_index (avl_tree * tree, + unsigned long index, + void ** value_address) +{ + avl_node * p = tree->root->right; + unsigned long m = index + 1; + while (1) { + if (!p) { + return -1; + } + if (m < AVL_GET_RANK(p)) { + p = p->left; + } else if (m > AVL_GET_RANK(p)) { + m = m - AVL_GET_RANK(p); + p = p->right; + } else { + *value_address = p->key; + return 0; + } + } +} + +int +avl_get_by_key (avl_tree * tree, + void * key, + void **value_address) +{ + avl_node * x = tree->root->right; + if (!x) { + return -1; + } + while (1) { + int compare_result = tree->compare_fun (tree->compare_arg, key, x->key); + if (compare_result < 0) { + if (x->left) { + x = x->left; + } else { + return -1; + } + } else if (compare_result > 0) { + if (x->right) { + x = x->right; + } else { + return -1; + } + } else { + *value_address = x->key; + return 0; + } + } +} + +int avl_delete(avl_tree *tree, void *key, avl_free_key_fun_type free_key_fun) +{ + avl_node *x, *y, *p, *q, *r, *top, *x_child; + int shortened_side, shorter; + + x = tree->root->right; + if (!x) { + return -1; + } + while (1) { + int compare_result = tree->compare_fun (tree->compare_arg, key, x->key); + if (compare_result < 0) { + /* move left + * We will be deleting from the left, adjust this node's + * rank accordingly + */ + AVL_SET_RANK (x, (AVL_GET_RANK(x) - 1)); + if (x->left) { + x = x->left; + } else { + /* Oops! now we have to undo the rank changes + * all the way up the tree + */ + AVL_SET_RANK(x, (AVL_GET_RANK (x) + 1)); + while (x != tree->root->right) { + if (x->parent->left == x) { + AVL_SET_RANK(x->parent, (AVL_GET_RANK (x->parent) + 1)); + } + x = x->parent; + } + return -1; /* key not in tree */ + } + } else if (compare_result > 0) { + /* move right */ + if (x->right) { + x = x->right; + } else { + AVL_SET_RANK(x, (AVL_GET_RANK (x) + 1)); + while (x != tree->root->right) { + if (x->parent->left == x) { + AVL_SET_RANK(x->parent, (AVL_GET_RANK (x->parent) + 1)); + } + x = x->parent; + } + return -1; /* key not in tree */ + } + } else { + break; + } + } + + if (x->left && x->right) { + void * temp_key; + + /* The complicated case. + * reduce this to the simple case where we are deleting + * a node with at most one child. + */ + + /* find the immediate predecessor */ + y = x->left; + while (y->right) { + y = y->right; + } + /* swap with */ + temp_key = x->key; + x->key = y->key; + y->key = temp_key; + /* we know 's left subtree lost a node because that's + * where we took it from + */ + AVL_SET_RANK (x, (AVL_GET_RANK (x) - 1)); + x = y; + } + /* now has at most one child + * scoot this child into the place of + */ + if (x->left) { + x_child = x->left; + x_child->parent = x->parent; + } else if (x->right) { + x_child = x->right; + x_child->parent = x->parent; + } else { + x_child = NULL; + } + + /* now tell 's parent that a grandchild became a child */ + if (x == x->parent->left) { + x->parent->left = x_child; + shortened_side = -1; + } else { + x->parent->right = x_child; + shortened_side = +1; + } + + /* + * the height of the subtree + * has now been shortened. climb back up + * the tree, rotating when necessary to adjust + * for the change. + */ + shorter = 1; + p = x->parent; + + /* return the key and node to storage */ + if (free_key_fun) + free_key_fun (x->key); +#ifdef HAVE_AVL_NODE_LOCK + thread_rwlock_destroy (&x->rwlock); +#endif + free (x); + + while (shorter && p->parent) { + + /* case 1: height unchanged */ + if (AVL_GET_BALANCE(p) == 0) { + if (shortened_side == -1) { + /* we removed a left child, the tree is now heavier + * on the right + */ + AVL_SET_BALANCE (p, +1); + } else { + /* we removed a right child, the tree is now heavier + * on the left + */ + AVL_SET_BALANCE (p, -1); + } + shorter = 0; + + } else if (AVL_GET_BALANCE (p) == shortened_side) { + /* case 2: taller subtree shortened, height reduced */ + AVL_SET_BALANCE (p, 0); + } else { + /* case 3: shorter subtree shortened */ + top = p->parent; + /* set to the taller of the two subtrees of

*/ + if (shortened_side == 1) { + q = p->left; + } else { + q = p->right; + } + if (AVL_GET_BALANCE (q) == 0) { + /* case 3a: height unchanged */ + if (shortened_side == -1) { + /* single rotate left */ + q->parent = p->parent; + p->right = q->left; + if (q->left) { + q->left->parent = p; + } + q->left = p; + p->parent = q; + AVL_SET_RANK (q, (AVL_GET_RANK (q) + AVL_GET_RANK (p))); + } else { + /* single rotate right */ + q->parent = p->parent; + p->left = q->right; + if (q->right) { + q->right->parent = p; + } + q->right = p; + p->parent = q; + AVL_SET_RANK (p, (AVL_GET_RANK (p) - AVL_GET_RANK (q))); + } + shorter = 0; + AVL_SET_BALANCE (q, shortened_side); + AVL_SET_BALANCE (p, (- shortened_side)); + } else if (AVL_GET_BALANCE (q) == AVL_GET_BALANCE (p)) { + /* case 3b: height reduced */ + if (shortened_side == -1) { + /* single rotate left */ + q->parent = p->parent; + p->right = q->left; + if (q->left) { + q->left->parent = p; + } + q->left = p; + p->parent = q; + AVL_SET_RANK (q, (AVL_GET_RANK (q) + AVL_GET_RANK (p))); + } else { + /* single rotate right */ + q->parent = p->parent; + p->left = q->right; + if (q->right) { + q->right->parent = p; + } + q->right = p; + p->parent = q; + AVL_SET_RANK (p, (AVL_GET_RANK (p) - AVL_GET_RANK (q))); + } + shorter = 1; + AVL_SET_BALANCE (q, 0); + AVL_SET_BALANCE (p, 0); + } else { + /* case 3c: height reduced, balance factors opposite */ + if (shortened_side == 1) { + /* double rotate right */ + /* first, a left rotation around q */ + r = q->right; + r->parent = p->parent; + q->right = r->left; + if (r->left) { + r->left->parent = q; + } + r->left = q; + q->parent = r; + /* now, a right rotation around p */ + p->left = r->right; + if (r->right) { + r->right->parent = p; + } + r->right = p; + p->parent = r; + AVL_SET_RANK (r, (AVL_GET_RANK (r) + AVL_GET_RANK (q))); + AVL_SET_RANK (p, (AVL_GET_RANK (p) - AVL_GET_RANK (r))); + } else { + /* double rotate left */ + /* first, a right rotation around q */ + r = q->left; + r->parent = p->parent; + q->left = r->right; + if (r->right) { + r->right->parent = q; + } + r->right = q; + q->parent = r; + /* now a left rotation around p */ + p->right = r->left; + if (r->left) { + r->left->parent = p; + } + r->left = p; + p->parent = r; + AVL_SET_RANK (q, (AVL_GET_RANK (q) - AVL_GET_RANK (r))); + AVL_SET_RANK (r, (AVL_GET_RANK (r) + AVL_GET_RANK (p))); + } + if (AVL_GET_BALANCE (r) == shortened_side) { + AVL_SET_BALANCE (q, (- shortened_side)); + AVL_SET_BALANCE (p, 0); + } else if (AVL_GET_BALANCE (r) == (- shortened_side)) { + AVL_SET_BALANCE (q, 0); + AVL_SET_BALANCE (p, shortened_side); + } else { + AVL_SET_BALANCE (q, 0); + AVL_SET_BALANCE (p, 0); + } + AVL_SET_BALANCE (r, 0); + q = r; + } + /* a rotation has caused (or in case 3c) to become + * the root. let

's former parent know this. + */ + if (top->left == p) { + top->left = q; + } else { + top->right = q; + } + /* end case 3 */ + p = q; + } + x = p; + p = x->parent; + /* shortened_side tells us which side we came up from */ + if (x == p->left) { + shortened_side = -1; + } else { + shortened_side = +1; + } + } /* end while(shorter) */ + /* when we're all done, we're one shorter */ + tree->length = tree->length - 1; + return (0); +} + +static int +avl_iterate_inorder_helper (avl_node * node, + avl_iter_fun_type iter_fun, + void * iter_arg) +{ + int result; + if (node->left) { + result = avl_iterate_inorder_helper (node->left, iter_fun, iter_arg); + if (result != 0) { + return result; + } + } + result = (iter_fun (node->key, iter_arg)); + if (result != 0) { + return result; + } + if (node->right) { + result = avl_iterate_inorder_helper (node->right, iter_fun, iter_arg); + if (result != 0) { + return result; + } + } + return 0; +} + +int +avl_iterate_inorder (avl_tree * tree, + avl_iter_fun_type iter_fun, + void * iter_arg) +{ + int result; + + if (tree->length) { + result = avl_iterate_inorder_helper (tree->root->right, iter_fun, iter_arg); + return (result); + } else { + return 0; + } +} + +avl_node *avl_get_first(avl_tree *tree) +{ + avl_node *node; + + node = tree->root->right; + if (node == NULL || node->key == NULL) return NULL; + + while (node->left) + node = node->left; + + return node; +} + +avl_node *avl_get_prev(avl_node *node) +{ + if (node->left) { + node = node->left; + while (node->right) { + node = node->right; + } + + return node; + } else { + avl_node *child = node; + while (node->parent && node->parent->key) { + node = node->parent; + if (child == node->right) { + return node; + } + child = node; + } + + return NULL; + } +} + +avl_node *avl_get_next(avl_node *node) +{ + if (node->right) { + node = node->right; + while (node->left) { + node = node->left; + } + + return node; + } else { + avl_node *child = node; + while (node->parent && node->parent->key) { + node = node->parent; + if (child == node->left) { + return node; + } + child = node; + } + + return NULL; + } +} + +/* iterate a function over a range of indices, using get_predecessor */ + +int +avl_iterate_index_range (avl_tree * tree, + avl_iter_index_fun_type iter_fun, + unsigned long low, + unsigned long high, + void * iter_arg) +{ + unsigned long m; + unsigned long num_left; + avl_node * node; + + if (high > tree->length) { + return -1; + } + num_left = (high - low); + /* find the th node */ + m = high; + node = tree->root->right; + while (1) { + if (m < AVL_GET_RANK (node)) { + node = node->left; + } else if (m > AVL_GET_RANK (node)) { + m = m - AVL_GET_RANK (node); + node = node->right; + } else { + break; + } + } + /* call on , , ... */ + while (num_left) { + num_left = num_left - 1; + if (iter_fun (num_left, node->key, iter_arg) != 0) { + return -1; + } + node = avl_get_prev (node); + } + return 0; +} + +/* If is present in the tree, return that key's node, and set <*index> + * appropriately. If not, return NULL, and set <*index> to the position + * representing the closest preceding value. + */ + +static avl_node * +avl_get_index_by_key (avl_tree * tree, + void * key, + unsigned long * index) +{ + avl_node * x = tree->root->right; + unsigned long m; + + if (!x) { + return NULL; + } + m = AVL_GET_RANK (x); + + while (1) { + int compare_result = tree->compare_fun (tree->compare_arg, key, x->key); + if (compare_result < 0) { + if (x->left) { + m = m - AVL_GET_RANK(x); + x = x->left; + m = m + AVL_GET_RANK(x); + } else { + *index = m - 2; + return NULL; + } + } else if (compare_result > 0) { + if (x->right) { + x = x->right; + m = m + AVL_GET_RANK(x); + } else { + *index = m - 1; + return NULL; + } + } else { + *index = m - 1; + return x; + } + } +} + +/* return the (low index, high index) pair that spans the given key */ + +int +avl_get_span_by_key (avl_tree * tree, + void * key, + unsigned long * low, + unsigned long * high) +{ + unsigned long m, i, j; + avl_node * node; + + node = avl_get_index_by_key (tree, key, &m); + + /* did we find an exact match? + * if so, we have to search left and right + * to find the span, since we know nothing about + * the arrangement of like keys. + */ + if (node) { + avl_node * left, * right; + /* search left */ + left = avl_get_prev (node); + i = m; + while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, key, left->key) == 0)) { + left = avl_get_prev (left); + i = i - 1; + } + /* search right */ + right = avl_get_next (node); + j = m; + while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, key, right->key) == 0)) { + right = avl_get_next (right); + j = j + 1; + } + *low = i; + *high = j + 1; + return 0; + } else { + *low = *high = m; + } + return 0; +} + +/* return the (low index, high index) pair that spans the given key */ + +int +avl_get_span_by_two_keys (avl_tree * tree, + void * low_key, + void * high_key, + unsigned long * low, + unsigned long * high) +{ + unsigned long i, j; + avl_node * low_node, * high_node; + int order; + + /* we may need to swap them */ + order = tree->compare_fun (tree->compare_arg, low_key, high_key); + if (order > 0) { + void * temp = low_key; + low_key = high_key; + high_key = temp; + } + + low_node = avl_get_index_by_key (tree, low_key, &i); + high_node = avl_get_index_by_key (tree, high_key, &j); + + if (low_node) { + avl_node * left; + /* search left */ + left = avl_get_prev (low_node); + while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, low_key, left->key) == 0)) { + left = avl_get_prev (left); + i = i - 1; + } + } else { + i = i + 1; + } + if (high_node) { + avl_node * right; + /* search right */ + right = avl_get_next (high_node); + while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, high_key, right->key) == 0)) { + right = avl_get_next (right); + j = j + 1; + } + } else { + j = j + 1; + } + + *low = i; + *high = j; + return 0; +} + + +int +avl_get_item_by_key_most (avl_tree * tree, + void * key, + void **value_address) +{ + avl_node * x = tree->root->right; + *value_address = NULL; + + if (!x) { + return -1; + } + while (1) { + int compare_result = tree->compare_fun (tree->compare_arg, key, x->key); + + if (compare_result == 0) { + *value_address = x->key; + return 0; + } else if (compare_result < 0) { + /* the given key is less than the current key */ + if (x->left) { + x = x->left; + } else { + if (*value_address) + return 0; + else + return -1; + } + } else { + /* the given key is more than the current key */ + /* save this value, it might end up being the right one! */ + *value_address = x->key; + if (x->right) { + /* there is a bigger entry */ + x = x->right; + } else { + if (*value_address) + return 0; + else + return -1; + } + } + } +} + +int +avl_get_item_by_key_least (avl_tree * tree, + void * key, + void **value_address) +{ + avl_node * x = tree->root->right; + *value_address = NULL; + + if (!x) { + return -1; + } + while (1) { + int compare_result = tree->compare_fun (tree->compare_arg, key, x->key); + if (compare_result == 0) { + *value_address = x->key; + return 0; /* exact match */ + } else if (compare_result < 0) { + /* the given key is less than the current key */ + /* save this value, it might end up being the right one! */ + *value_address = x->key; + if (x->left) { + x = x->left; + } else { + if (*value_address) /* we have found a valid entry */ + return 0; + else + return -1; + } + } else { + if (x->right) { + /* there is a bigger entry */ + x = x->right; + } else { + if (*value_address) /* we have found a valid entry */ + return 0; + else + return -1; + } + } + } +} + +#define AVL_MAX(X, Y) ((X) > (Y) ? (X) : (Y)) + +static long +avl_verify_balance (avl_node * node) +{ + if (!node) { + return 0; + } else { + long lh = avl_verify_balance (node->left); + long rh = avl_verify_balance (node->right); + if ((rh - lh) != AVL_GET_BALANCE(node)) { + return 0; + } + if (((lh - rh) > 1) || ((lh - rh) < -1)) { + return 0; + } + return (1 + AVL_MAX (lh, rh)); + } +} + +static void +avl_verify_parent (avl_node * node, avl_node * parent) +{ + if (node->parent != parent) { + return; + } + if (node->left) { + avl_verify_parent (node->left, node); + } + if (node->right) { + avl_verify_parent (node->right, node); + } +} + +static long +avl_verify_rank (avl_node * node) +{ + if (!node) { + return 0; + } else { + unsigned long num_left=0, num_right=0; + if (node->left) { + num_left = avl_verify_rank (node->left); + } + if (node->right) { + num_right = avl_verify_rank (node->right); + } + if (AVL_GET_RANK (node) != num_left + 1) { + fprintf (stderr, "invalid rank at node %ld\n", (long) node->key); + exit (1); + } + return (num_left + num_right + 1); + } +} + +/* sanity-check the tree */ + +int +avl_verify (avl_tree * tree) +{ + if (tree->length) { + avl_verify_balance (tree->root->right); + avl_verify_parent (tree->root->right, tree->root); + avl_verify_rank (tree->root->right); + } + return (0); +} + +/* + * These structures are accumulated on the stack during print_tree + * and are used to keep track of the width and direction of each + * branch in the history of a particular line . + */ + +typedef struct _link_node { + struct _link_node * parent; + char direction; + int width; +} link_node; + +static char balance_chars[3] = {'\\', '-', '/'}; + +static int +default_key_printer (char * buffer, void * key) +{ + return snprintf (buffer, AVL_KEY_PRINTER_BUFLEN, "%p", key); +} + +/* + * When traveling the family tree, a change in direction + * indicates when to print a connector. This is kinda crazy, + * we use the stack to build a linked list, and then travel + * it backwards using recursion. + */ + +static void +print_connectors (link_node * link) +{ + if (link->parent) { + print_connectors (link->parent); + } + if (link->parent && (link->parent->direction != link->direction) && (link->parent->parent)) { + int i; + fprintf (stdout, "|"); + for (i=0; i < (link->width - 1); i++) { + fprintf (stdout, " "); + } + } else { + int i; + for (i=0; i < (link->width); i++) { + fprintf (stdout, " "); + } + } +} + +/* + * The function writes a representation of the + * key into (which is conveniently fixed in size to add + * the spice of danger). It should return the size of the + * representation. + */ + +static void +print_node (avl_key_printer_fun_type key_printer, + avl_node * node, + link_node * link) +{ + char buffer[AVL_KEY_PRINTER_BUFLEN]; + unsigned int width; + width = key_printer (buffer, node->key); + + if (node->right) { + link_node here; + here.parent = link; + here.direction = 1; + here.width = width + 11; + print_node (key_printer, node->right, &here); + } + print_connectors (link); + fprintf (stdout, "+-[%c %s %03d]", + balance_chars[AVL_GET_BALANCE(node)+1], + buffer, + (int)AVL_GET_RANK(node)); + if (node->left || node->right) { + fprintf (stdout, "-|\n"); + } else { + fprintf (stdout, "\n"); + } + if (node->left) { + link_node here; + here.parent = link; + here.direction = -1; + here.width = width + 11; + print_node (key_printer, node->left, &here); + } +} + +void +avl_print_tree (avl_tree * tree, avl_key_printer_fun_type key_printer) +{ + link_node top = {NULL, 0, 0}; + if (!key_printer) { + key_printer = default_key_printer; + } + if (tree->length) { + print_node (key_printer, tree->root->right, &top); + } else { + fprintf (stdout, "\n"); + } +} + + +void avl_tree_rlock(avl_tree *tree) +{ + thread_rwlock_rlock(&tree->rwlock); +} + +void avl_tree_wlock(avl_tree *tree) +{ + thread_rwlock_wlock(&tree->rwlock); +} + +void avl_tree_unlock(avl_tree *tree) +{ + thread_rwlock_unlock(&tree->rwlock); +} + +#ifdef HAVE_AVL_NODE_LOCK +void avl_node_rlock(avl_node *node) +{ + thread_rwlock_rlock(&node->rwlock); +} + +void avl_node_wlock(avl_node *node) +{ + thread_rwlock_wlock(&node->rwlock); +} + +void avl_node_unlock(avl_node *node) +{ + thread_rwlock_unlock(&node->rwlock); +} +#endif diff --git a/lib/libshout/src/common/avl/avl.dsp b/lib/libshout/src/common/avl/avl.dsp new file mode 100644 index 00000000000..10fabf3e87e --- /dev/null +++ b/lib/libshout/src/common/avl/avl.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="avl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=avl - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "avl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "avl.mak" CFG="avl - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "avl - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "avl - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "avl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "avl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "avl - Win32 Release" +# Name "avl - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\avl.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\avl.h +# End Source File +# End Group +# End Target +# End Project diff --git a/lib/libshout/src/common/avl/avl.h b/lib/libshout/src/common/avl/avl.h new file mode 100644 index 00000000000..3e02ce42c43 --- /dev/null +++ b/lib/libshout/src/common/avl/avl.h @@ -0,0 +1,205 @@ +/* + * Copyright (C) 1995 by Sam Rushing + */ + +/* $Id: avl.h,v 1.7 2003/07/07 01:10:14 brendan Exp $ */ + +#ifndef __AVL_H +#define __AVL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define AVL_KEY_PRINTER_BUFLEN (256) + +#ifndef NO_THREAD +#include "thread/thread.h" +#else +#define thread_rwlock_create(x) do{}while(0) +#define thread_rwlock_destroy(x) do{}while(0) +#define thread_rwlock_rlock(x) do{}while(0) +#define thread_rwlock_wlock(x) do{}while(0) +#define thread_rwlock_unlock(x) do{}while(0) +#endif + +typedef struct avl_node_tag { + void * key; + struct avl_node_tag * left; + struct avl_node_tag * right; + struct avl_node_tag * parent; + /* + * The lower 2 bits of specify the balance + * factor: 00==-1, 01==0, 10==+1. + * The rest of the bits are used for + */ + unsigned int rank_and_balance; +#if !defined(NO_THREAD) && defined(HAVE_AVL_NODE_LOCK) + rwlock_t rwlock; +#endif +} avl_node; + +#define AVL_GET_BALANCE(n) ((int)(((n)->rank_and_balance & 3) - 1)) + +#define AVL_GET_RANK(n) (((n)->rank_and_balance >> 2)) + +#define AVL_SET_BALANCE(n,b) \ + ((n)->rank_and_balance) = \ + (((n)->rank_and_balance & (~3)) | ((int)((b) + 1))) + +#define AVL_SET_RANK(n,r) \ + ((n)->rank_and_balance) = \ + (((n)->rank_and_balance & 3) | (r << 2)) + +struct _avl_tree; + +typedef int (*avl_key_compare_fun_type) (void * compare_arg, void * a, void * b); +typedef int (*avl_iter_fun_type) (void * key, void * iter_arg); +typedef int (*avl_iter_index_fun_type) (unsigned long index, void * key, void * iter_arg); +typedef int (*avl_free_key_fun_type) (void * key); +typedef int (*avl_key_printer_fun_type) (char *, void *); + +/* + * and let us associate a particular compare + * function with each tree, separately. + */ + +#ifdef _mangle +# define avl_tree_new _mangle(avl_tree_new) +# define avl_node_new _mangle(avl_node_new) +# define avl_tree_free _mangle(avl_tree_free) +# define avl_insert _mangle(avl_insert) +# define avl_delete _mangle(avl_delete) +# define avl_get_by_index _mangle(avl_get_by_index) +# define avl_get_by_key _mangle(avl_get_by_key) +# define avl_iterate_inorder _mangle(avl_iterate_inorder) +# define avl_iterate_index_range _mangle(avl_iterate_index_range) +# define avl_tree_rlock _mangle(avl_tree_rlock) +# define avl_tree_wlock _mangle(avl_tree_wlock) +# define avl_tree_wlock _mangle(avl_tree_wlock) +# define avl_tree_unlock _mangle(avl_tree_unlock) +# define avl_node_rlock _mangle(avl_node_rlock) +# define avl_node_wlock _mangle(avl_node_wlock) +# define avl_node_unlock _mangle(avl_node_unlock) +# define avl_get_span_by_key _mangle(avl_get_span_by_key) +# define avl_get_span_by_two_keys _mangle(avl_get_span_by_two_keys) +# define avl_verify _mangle(avl_verify) +# define avl_print_tree _mangle(avl_print_tree) +# define avl_get_first _mangle(avl_get_first) +# define avl_get_prev _mangle(avl_get_prev) +# define avl_get_next _mangle(avl_get_next) +# define avl_get_item_by_key_most _mangle(avl_get_item_by_key_most) +# define avl_get_item_by_key_least _mangle(avl_get_item_by_key_least) +#endif + +typedef struct _avl_tree { + avl_node * root; + unsigned int height; + unsigned int length; + avl_key_compare_fun_type compare_fun; + void * compare_arg; +#ifndef NO_THREAD + rwlock_t rwlock; +#endif +} avl_tree; + +avl_tree * avl_tree_new (avl_key_compare_fun_type compare_fun, void * compare_arg); +avl_node * avl_node_new (void * key, avl_node * parent); + +void avl_tree_free ( + avl_tree * tree, + avl_free_key_fun_type free_key_fun + ); + +int avl_insert ( + avl_tree * ob, + void * key + ); + +int avl_delete ( + avl_tree * tree, + void * key, + avl_free_key_fun_type free_key_fun + ); + +int avl_get_by_index ( + avl_tree * tree, + unsigned long index, + void ** value_address + ); + +int avl_get_by_key ( + avl_tree * tree, + void * key, + void ** value_address + ); + +int avl_iterate_inorder ( + avl_tree * tree, + avl_iter_fun_type iter_fun, + void * iter_arg + ); + +int avl_iterate_index_range ( + avl_tree * tree, + avl_iter_index_fun_type iter_fun, + unsigned long low, + unsigned long high, + void * iter_arg + ); + +int avl_get_span_by_key ( + avl_tree * tree, + void * key, + unsigned long * low, + unsigned long * high + ); + +int avl_get_span_by_two_keys ( + avl_tree * tree, + void * key_a, + void * key_b, + unsigned long * low, + unsigned long * high + ); + +int avl_verify (avl_tree * tree); + +void avl_print_tree ( + avl_tree * tree, + avl_key_printer_fun_type key_printer + ); + +avl_node *avl_get_first(avl_tree *tree); + +avl_node *avl_get_prev(avl_node * node); + +avl_node *avl_get_next(avl_node * node); + +/* These two are from David Ascher */ + +int avl_get_item_by_key_most ( + avl_tree * tree, + void * key, + void ** value_address + ); + +int avl_get_item_by_key_least ( + avl_tree * tree, + void * key, + void ** value_address + ); + +/* optional locking stuff */ +void avl_tree_rlock(avl_tree *tree); +void avl_tree_wlock(avl_tree *tree); +void avl_tree_unlock(avl_tree *tree); +void avl_node_rlock(avl_node *node); +void avl_node_wlock(avl_node *node); +void avl_node_unlock(avl_node *node); + +#ifdef __cplusplus +} +#endif + +#endif /* __AVL_H */ diff --git a/lib/libshout/src/common/avl/test.c b/lib/libshout/src/common/avl/test.c new file mode 100644 index 00000000000..a33c2c16c99 --- /dev/null +++ b/lib/libshout/src/common/avl/test.c @@ -0,0 +1,95 @@ +#include +#include "avl.h" + +#ifdef _WIN32 +#define snprintf _snprintf +#endif + +int _compare(void *compare_arg, void *a, void *b); +int _free(void *key); +int _printer(char *buff, void *key); + +int main(int argc, char **argv) +{ + int i, max_nodes; + avl_tree *tree; + avl_node *node; + + max_nodes = 25; + + if (argc == 2) { + max_nodes = atoi(argv[1]); + if (max_nodes == 0) + max_nodes = 10; + } + + printf("avl test... max_nodes = %d...\n", max_nodes); + + tree = avl_tree_new(_compare, NULL); + + printf("Filling tree...\n"); + for (i = 0; i < max_nodes; i++) { + avl_insert(tree, (void *)rand()); + } + + printf("Traversing tree...\n"); + node = avl_get_first(tree); + while (node) { + i = (int)node->key; + + printf("...%5d\n", i); + + node = avl_get_next(node); + } + + printf("Trying to go backwards...\n"); + node = tree->root->right; + while (node) { + i = (int)node->key; + printf("...%5d\n", i); + node = avl_get_prev(node); + } + + printf("Printing tree...\n"); + avl_print_tree(tree, _printer); + + avl_tree_free(tree, _free); + + return 0; +} + +int _compare(void *compare_arg, void *a, void *b) +{ + int i, j; + + i = (int)a; + j = (int)b; + + if (i > j) + return 1; + if (j > i) + return -1; + return 0; +} + +int _free(void *key) +{ + return 1; +} + +int _printer(char *buff, void *key) +{ + return snprintf(buff, 25, "%d", (int)key); +} + + + + + + + + + + + + diff --git a/lib/libshout/src/common/httpp/COPYING b/lib/libshout/src/common/httpp/COPYING new file mode 100644 index 00000000000..92b8903ff3f --- /dev/null +++ b/lib/libshout/src/common/httpp/COPYING @@ -0,0 +1,481 @@ + 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 + + 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 + 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! diff --git a/lib/libshout/src/common/httpp/Makefile.am b/lib/libshout/src/common/httpp/Makefile.am new file mode 100644 index 00000000000..11989e005e3 --- /dev/null +++ b/lib/libshout/src/common/httpp/Makefile.am @@ -0,0 +1,22 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign + +noinst_LTLIBRARIES = libicehttpp.la +noinst_HEADERS = httpp.h encoding.h + +libicehttpp_la_SOURCES = httpp.c encoding.c +libicehttpp_la_CFLAGS = @XIPH_CFLAGS@ +AM_CPPFLAGS = @XIPH_CPPFLAGS@ + +INCLUDES = -I$(srcdir)/.. + +# SCCS stuff (for BitKeeper) +GET = true + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" + diff --git a/lib/libshout/src/common/httpp/README b/lib/libshout/src/common/httpp/README new file mode 100644 index 00000000000..e4001d569be --- /dev/null +++ b/lib/libshout/src/common/httpp/README @@ -0,0 +1,5 @@ +httpp is a simple http parser + +licensed under the lgpl + +created by jack moffitt diff --git a/lib/libshout/src/common/httpp/TODO b/lib/libshout/src/common/httpp/TODO new file mode 100644 index 00000000000..04e2c790d83 --- /dev/null +++ b/lib/libshout/src/common/httpp/TODO @@ -0,0 +1 @@ +- nothing i can think of diff --git a/lib/libshout/src/common/httpp/encoding.c b/lib/libshout/src/common/httpp/encoding.c new file mode 100644 index 00000000000..4a4dd4e3232 --- /dev/null +++ b/lib/libshout/src/common/httpp/encoding.c @@ -0,0 +1,787 @@ +/* encoding.c +** +** http transfer encoding library +** See RFC2616 section 3.6 for more details. +** +** Copyright (C) 2015 Philipp "ph3-der-loewe" Schafft +** +** 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., 51 Franklin St, Fifth Floor, +** Boston, MA 02110-1301, USA. +** +*/ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include + +#include "encoding.h" + +struct httpp_encoding_tag { + size_t refc; + + ssize_t (*process_read)(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata); + ssize_t (*process_write)(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata); + + httpp_meta_t *meta_read; + httpp_meta_t *meta_write; + + void *buf_read_raw; /* input buffer */ + size_t buf_read_raw_offset, buf_read_raw_len; + + void *buf_read_decoded; /* decoded stuff */ + size_t buf_read_decoded_offset, buf_read_decoded_len; + + void *buf_write_raw; /* input buffer */ + size_t buf_write_raw_offset, buf_write_raw_len; + + void *buf_write_encoded; /* encoded output */ + size_t buf_write_encoded_offset, buf_write_encoded_len; + + /* backend specific stuff */ + size_t read_bytes_till_header; +}; + + +/* Handlers, at end of file */ +static ssize_t __enc_identity_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata); +static ssize_t __enc_identity_write(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata); +static ssize_t __enc_chunked_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata); +static ssize_t __enc_chunked_write(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata); + +/* function to move some data out of our buffers */ +ssize_t __copy_buffer(void *dst, void **src, size_t *boffset, size_t *blen, size_t len) +{ + void *p; + size_t have_len; + size_t todo; + + if (!len) + return 0; + + if (!dst || !src || !*src || !boffset || !blen) + return -1; + + have_len = *blen - *boffset; + p = *src + *boffset; + + todo = len < have_len ? len : have_len; + + memcpy(dst, p, todo); + + *boffset += todo; + + if (*boffset == *blen) { + free(*src); + *src = NULL; + *boffset = 0; + *blen = 0; + } + + return todo; +} + +/* try to flush output buffers */ +static inline void __flush_output(httpp_encoding_t *self, ssize_t (*cb)(void*, const void*, size_t), void *userdata) +{ + if (cb && self->buf_write_encoded) { + ssize_t ret = cb(userdata, + self->buf_write_encoded + self->buf_write_encoded_offset, + self->buf_write_encoded_len - self->buf_write_encoded_offset); + if (ret > 0) { + self->buf_write_encoded_offset += ret; + if (self->buf_write_encoded_offset == self->buf_write_encoded_len) { + free(self->buf_write_encoded); + self->buf_write_encoded = NULL; + self->buf_write_encoded_offset = 0; + self->buf_write_encoded_len = 0; + } + } + } +} + +/* meta data functions */ +/* meta data is to be used in a encoding-specific way */ +httpp_meta_t *httpp_encoding_meta_new(const char *key, const char *value) +{ + httpp_meta_t *ret = calloc(1, sizeof(httpp_meta_t)); + if (!ret) + return ret; + + if (key) + if ((ret->key = strdup(key)) == NULL) + goto fail; + + if (value) { + if ((ret->value = strdup(value)) == NULL) + goto fail; + ret->value_len = strlen(ret->value); + } + + return ret; +fail: + httpp_encoding_meta_free(ret); + return NULL; +} + +int httpp_encoding_meta_free(httpp_meta_t *self) +{ + while (self) { + httpp_meta_t *cur = self; + self = self->next; + + if (cur->key) + free(cur->key); + if (cur->value) + free(cur->value); + free(cur); + } + + return 0; +} + +int httpp_encoding_meta_append(httpp_meta_t **dst, httpp_meta_t *next) +{ + httpp_meta_t **cur; + + if (!dst) + return -1; + if (!next) + return 0; + + cur = dst; + while (*cur) + cur = &((*cur)->next); + + *cur = next; + + return 0; +} + +/* General setup */ +httpp_encoding_t *httpp_encoding_new(const char *encoding) { + httpp_encoding_t *ret = calloc(1, sizeof(httpp_encoding_t)); + if (!ret) + return NULL; + + ret->refc = 1; + + if (strcasecmp(encoding, HTTPP_ENCODING_IDENTITY) == 0) { + ret->process_read = __enc_identity_read; + ret->process_write = __enc_identity_write; + } else if (strcasecmp(encoding, HTTPP_ENCODING_CHUNKED) == 0) { + ret->process_read = __enc_chunked_read; + ret->process_write = __enc_chunked_write; + } else { + goto fail; + } + + return ret; + +fail: + httpp_encoding_release(ret); + return NULL; +} + +int httpp_encoding_addref(httpp_encoding_t *self) +{ + if (!self) + return -1; + self->refc++; + return 0; +} + +int httpp_encoding_release(httpp_encoding_t *self) +{ + if (!self) + return -1; + + self->refc--; + if (self->refc) + return 0; + + httpp_encoding_meta_free(self->meta_read); + httpp_encoding_meta_free(self->meta_write); + + if (self->buf_read_raw) + free(self->buf_read_raw); + if (self->buf_read_decoded) + free(self->buf_read_decoded); + if (self->buf_write_raw) + free(self->buf_write_raw); + if (self->buf_write_encoded) + free(self->buf_write_encoded); + free(self); + return 0; +} + +/* Read data from backend. + * if cb is NULL this will read from the internal buffer. + */ +ssize_t httpp_encoding_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata) +{ + ssize_t done = 0; + ssize_t ret; + + if (!self || !buf) + return -1; + + if (!len) + return 0; + + ret = __copy_buffer(buf, &(self->buf_read_decoded), &(self->buf_read_decoded_offset), &(self->buf_read_decoded_len), len); + + if (ret == (ssize_t)len) + return ret; + + if (ret > 0) { + done += ret; + buf += ret; + len -= ret; + } + + ret = self->process_read(self, buf, len, cb, userdata); + if (ret == -1 && done) + return done; + if (ret == -1) + return -1; + + done += ret; + buf += ret; + len -= ret; + + if (len) { + ret = __copy_buffer(buf, &(self->buf_read_decoded), &(self->buf_read_decoded_offset), &(self->buf_read_decoded_len), len); + if (ret > 0) { + done += ret; + buf += ret; + len -= ret; + } + } + + return done; +} + +/* Read any meta data that is in buffer. + * After a call to this function the meta data is released from the + * encoding object and the caller is responsible to free it. + */ +httpp_meta_t *httpp_encoding_get_meta(httpp_encoding_t *self) +{ + httpp_meta_t *ret; + + if (!self) + return NULL; + + ret = self->meta_read; + self->meta_read = NULL; + return ret; +} + +/* Write data to backend. + * If buf is NULL this will flush buffers. + * Depending on encoding flushing buffers may not be safe if not + * at end of stream. + */ +ssize_t httpp_encoding_write(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata) +{ + ssize_t ret; + + if (!self || !cb) + return -1; + + /* first try to flush buffers */ + __flush_output(self, cb, userdata); + + /* now run the processor */ + ret = self->process_write(self, buf, len, cb, userdata); + + /* try to flush buffers again, maybe they are filled now! */ + __flush_output(self, cb, userdata); + + return ret; +} + +/* Check if we have something to flush. */ +ssize_t httpp_encoding_pending(httpp_encoding_t *self) +{ + if (!self) + return -1; + if (!self->buf_write_encoded) + return 0; + return self->buf_write_encoded_len - self->buf_write_encoded_offset; +} + +/* Attach meta data to the stream. + * this is to be written out as soon as the encoding supports. + */ +int httpp_encoding_append_meta(httpp_encoding_t *self, httpp_meta_t *meta) +{ + if (!self) + return -1; + return httpp_encoding_meta_append(&(self->meta_write), meta); +} + +/* handlers for encodings */ +static ssize_t __enc_identity_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata) +{ + (void)self; + if (!cb) + return -1; + return cb(userdata, buf, len); +} + +static ssize_t __enc_identity_write(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata) +{ + (void)self; + if (!cb) + return -1; + return cb(userdata, buf, len); +} + +/* Here is what chunked encoding looks like: + * + * You have any number of chunks. They are just chained. + * The last chunk has a length of zero set. + * After the last chunk there are tailing headers and a final "\r\n". + * + * Each chunk looks like this: + * LENGTH as hex [";" extension [";" extention [...]]] "\r\n" BODY "\r\n". + * extension is: TOKEN ["=" data]; + * data is: TOKEN | STRING as quoted. + * + */ + +static void __enc_chunked_read_extentions(httpp_encoding_t *self, char *p, size_t len) +{ + /* ok. If you want to ruin your day... go ahead and try to understand this. */ + httpp_meta_t **parent; + httpp_meta_t *meta; + size_t value_len; + size_t value_decoded_len; + size_t key_len; + char *value; + char *c; + int in_quote; + + if (self->meta_read) { + parent = &(self->meta_read); + while (*parent) + parent = &((*parent)->next); + } else { + parent = &(self->meta_read); + } + + while (len) { + if (*p != ';') /* not a valid extension */ + break; + p++; + len--; + + *parent = meta = httpp_encoding_meta_new(NULL, NULL); + parent = &(meta->next); + + for (key_len = 0; key_len < len && p[key_len] != '='; key_len++); + meta->key = malloc(key_len + 1); + if (!meta->key) + return; + memcpy(meta->key, p, key_len); + meta->key[key_len] = 0; + p += key_len; + len -= key_len; + if (!len) + break; + + if (*p != '=') /* check if we have a value */ + continue; + + p++; + len--; + + if (!len) + break; + + in_quote = 0; + for (value_len = 0; value_len < len; value_len++) { + if (in_quote) { + if (p[value_len] == '\\') in_quote = 2; + else if (p[value_len] == '"') in_quote--; + if (in_quote) + continue; + value_len++; + break; + } + if (p[value_len] == '"') { + in_quote = 1; + } else if (p[value_len] == ';') + break; + } + + value = meta->value = malloc(value_len + 1); + if (!meta->value) + return; + in_quote = 0; + for (c = p, p += value_len, len -= value_len, value_decoded_len = 0; value_len; value_len--, c++) { + if (in_quote) { + if (*c == '\\') in_quote = 2; + else if (*c == '"') { + in_quote--; + if (in_quote) + value[value_decoded_len++] = '"'; + } else + value[value_decoded_len++] = *c; + if (in_quote) + continue; + break; + } + if (*c == '"') { + in_quote = 1; + } else if (p[value_len] == ';') + break; + else + value[value_decoded_len++] = *c; + } + value[value_decoded_len] = 0; + meta->value_len = value_decoded_len; + } +} + +static ssize_t __enc_chunked_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata) +{ + ssize_t ret; + size_t buflen; + void *bufptr; + size_t i; + char *c; + int in_quote; + ssize_t offset_extentions; + ssize_t offset_CR; + ssize_t offset_LF; + long long unsigned int bodylen; + + if (!cb) + return -1; + + /* see if we have still a few bytes to go till the next header + * The 2 is the end of chunk mark that is not part of the body! */ + if (self->read_bytes_till_header > 2) { + size_t todo = len > (self->read_bytes_till_header - 2) ? (self->read_bytes_till_header - 2) : len; + ret = cb(userdata, buf, todo); + if (ret < 1) + return ret; + self->read_bytes_till_header -= ret; + return ret; + } + + /* ok. now we should have 2 or less bytes till next header. + * We just read a few bytes into our decoding buffer and see what we got. + */ + buflen = 1024; + + if (self->buf_read_raw) { + bufptr = realloc(self->buf_read_raw, self->buf_read_raw_len + buflen); + } else { + bufptr = malloc(buflen); + self->buf_read_raw_offset = 0; + self->buf_read_raw_len = 0; + } + if (!bufptr) + return -1; + + self->buf_read_raw = bufptr; + + ret = cb(userdata, self->buf_read_raw + self->buf_read_raw_len, buflen); + if (ret < 1) { + if (!self->buf_read_raw_len) { + free(self->buf_read_raw); + self->buf_read_raw = NULL; + } + return ret; + } + + self->buf_read_raw_len += ret; + + /* now we should have some bytes in our buffer. + * Now skip the "\r\n" that may be left to do from self->read_bytes_till_header. + */ + + if ((self->buf_read_raw_len - self->buf_read_raw_offset) == self->read_bytes_till_header) { + /* ok, that wasn't super big step forward. At least we got rid of self->read_bytes_till_header. + * now freeing buffers again... + */ + free(self->buf_read_raw); + self->buf_read_raw = NULL; + self->buf_read_raw_offset = 0; + self->buf_read_raw_len = 0; + self->read_bytes_till_header = 0; + return 0; + } else if ((self->buf_read_raw_len - self->buf_read_raw_offset) > self->read_bytes_till_header) { + /* ship the tailing "\r\n". + * We should check we really got that and not some other stuff, eh? Yes, I'm sure we should... + */ + self->buf_read_raw_offset += self->read_bytes_till_header; + self->read_bytes_till_header = 0; + } + + /* ok. next we have at least a little bit if a header. + * Now we need to find out of the header is complet. + * If it is we will process it. If it isn't we will + * just return a short read and try again later! + * + * Hint: A complet header ends with "\r\n". + * But be aware! That is valid in any quoted string + * that is part of the header as well! + */ + + in_quote = 0; + offset_extentions = -1; + offset_CR = -1; + offset_LF = -1; + for (i = self->buf_read_raw_offset, c = self->buf_read_raw + self->buf_read_raw_offset; + i < self->buf_read_raw_len; + i++, c++) { + if (in_quote) { + if (*c == '\\') in_quote = 2; + else if (*c == '"') in_quote--; + continue; + } + if (*c == '"') { + in_quote = 1; + } else if (*c == ';' && offset_extentions == -1) { + offset_extentions = i; + } else if (*c == '\r') { + offset_CR = i; + } else if (*c == '\n' && offset_CR == (ssize_t)(i - 1)) { + offset_LF = i; + break; + } + } + + /* ok, now we know a lot more!: + * offset_extentions is the offset to the extentions if any. + * offset_LF is the offset to the byte before the body if any. + * if offset_LF is > -1 we know we have a complet header. + * if we don't just return a short read and try again later. + */ + + if (offset_LF == -1) + return 0; + + /* ok. Now we have a complet header. + * First pass the extentions to extention parser if any. + */ + if (offset_extentions != -1) + __enc_chunked_read_extentions(self, self->buf_read_raw + offset_extentions, offset_CR - offset_extentions); + + /* ok. Next we parse the body length. + * We just replace whatever comes after the length by \0 + * and try to parse the hex value. + */ + if (offset_extentions != -1) { + c = self->buf_read_raw + offset_extentions; + } else { + c = self->buf_read_raw + offset_CR; + } + *c = 0; + + /* we hope that will work... */ + if (sscanf(self->buf_read_raw + self->buf_read_raw_offset, "%llx", &bodylen) != 1) + return -1; + + /* ok, Now we move the offset forward to the body. */ + self->buf_read_raw_offset = offset_LF + 1; + + /* Do we still have some data in buffer? + * If not free the buffer and set the counters + * to point to the next header. + */ + if (self->buf_read_raw_offset == self->buf_read_raw_len) { + free(self->buf_read_raw); + self->buf_read_raw = NULL; + self->buf_read_raw_offset = 0; + self->buf_read_raw_len = 0; + self->read_bytes_till_header = bodylen + 2; /* 2 = tailing "\r\n" */ + return 0; + } + + /* ok, now we check if what we have in the buffer is less or equal than our bodylen. */ + if ((self->buf_read_raw_len - self->buf_read_raw_offset) <= bodylen) { + /* ok, this is fantastic. The framework can do the rest for us! */ + self->buf_read_decoded = self->buf_read_raw; + self->buf_read_decoded_offset = self->buf_read_raw_offset; + self->buf_read_decoded_len = self->buf_read_raw_len; + self->buf_read_raw = NULL; + self->buf_read_raw_offset = 0; + self->buf_read_raw_len = 0; + self->read_bytes_till_header = bodylen + 2 - (self->buf_read_decoded_len - self->buf_read_decoded_offset); + return 0; + } + + /* ok, final case left: + * we have more than just the body in our buffer. + * What we do now is to allocate buffer, move the body over + * and let our internal structures point to the next header. + */ + + self->buf_read_decoded = malloc(bodylen); + if (!self->buf_read_decoded) /* just retry later if we can not allocate a buffer */ + return -1; + self->buf_read_decoded_offset = 0; + self->buf_read_decoded_len = bodylen; + memcpy(self->buf_read_decoded, self->buf_read_raw + self->buf_read_raw_offset, bodylen); + self->buf_read_raw_offset += bodylen; + self->read_bytes_till_header = 2; /* tailing "\r\n" */ + + return 0; +} + +static size_t __enc_chunked_write_extensions_valuelen(httpp_meta_t *cur) +{ + size_t ret = cur->value_len; + size_t i; + char *p = cur->value; + + if (!cur->value || !cur->value_len) + return 0; + + for (i = 0; i < cur->value_len; i++, p++) + if (*p == '"') + ret++; + + return ret; +} + +static char *__enc_chunked_write_extensions(httpp_encoding_t *self) +{ + size_t buflen; + void *buf; + char *p; + size_t len; + httpp_meta_t *cur; + + if (!self->meta_write) + return NULL; + + /* first find out how long the buffer must be. */ + buflen = 1; /* tailing \0 */ + + cur = self->meta_write; + while (cur) { + if (!cur->key || (cur->value_len && !cur->value)) { + cur = cur->next; + continue; + } + + buflen += 4; /* ; and = and two " */ + buflen += strlen(cur->key); + buflen += __enc_chunked_write_extensions_valuelen(cur); + cur = cur->next; + } + + p = buf = malloc(buflen); + if (!buf) + return NULL; + + cur = self->meta_write; + while (cur) { + if (!cur->key || (cur->value_len && !cur->value)) { + cur = cur->next; + continue; + } + + *(p++) = ';'; + len = strlen(cur->key); + memcpy(p, cur->key, len); + p += len; + + if (cur->value_len) { + const char *c; + size_t i; + + *(p++) = '='; + *(p++) = '"'; + for (i = 0, c = cur->value; i < cur->value_len; i++, c++) { + if (*c == '"') + *(p++) = '\\'; + *(p++) = *c; + } + *(p++) = '"'; + } + + cur = cur->next; + } + + *p = 0; /* terminate the string */ + + httpp_encoding_meta_free(self->meta_write); + self->meta_write = NULL; + + return buf; +} +static ssize_t __enc_chunked_write(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata) +{ + char encoded_length[32]; + char *extensions = NULL; + ssize_t total_chunk_size; + ssize_t header_length; + + (void)cb, (void)userdata; + + if (!buf) + len = 0; + + /* refuse to write if we still have stuff to flush. */ + if (httpp_encoding_pending(self) > 0) + return 0; + + /* limit length to a bit more sane value */ + if (len > 1048576) + len = 1048576; + + snprintf(encoded_length, sizeof(encoded_length), "%lx", (long int)len); + + extensions = __enc_chunked_write_extensions(self); + + /* 2 = end of header and tailing "\r\n" */ + header_length = strlen(encoded_length) + (extensions ? strlen(extensions) : 0) + 2; + total_chunk_size = header_length + len + 2; + if (!buf) + total_chunk_size += 2; + + /* ok, we now allocate a huge buffer. We do it as if we would do it only when needed + * and it would fail we would end in bad state that can not be recovered */ + self->buf_write_encoded = malloc(total_chunk_size); + if (!self->buf_write_encoded) { + if (extensions) + free(extensions); + return -1; + } + + self->buf_write_encoded_offset = 0; + self->buf_write_encoded_len = total_chunk_size; + snprintf(self->buf_write_encoded, total_chunk_size, "%s%s\r\n", encoded_length, extensions ? extensions : ""); + memcpy(self->buf_write_encoded + header_length, buf, len); + memcpy(self->buf_write_encoded + header_length + len, "\r\n\r\n", buf ? 2 : 4); + + if (extensions) + free(extensions); + + return len; +} diff --git a/lib/libshout/src/common/httpp/encoding.h b/lib/libshout/src/common/httpp/encoding.h new file mode 100644 index 00000000000..64c654d9759 --- /dev/null +++ b/lib/libshout/src/common/httpp/encoding.h @@ -0,0 +1,84 @@ +/* encoding.h +** +** http transfer encoding library +** See RFC2616 section 3.6 for more details. +** +** Copyright (C) 2015 Philipp "ph3-der-loewe" Schafft +** +** 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., 51 Franklin St, Fifth Floor, +** Boston, MA 02110-1301, USA. +** +*/ + +#ifndef __ENCODING_H +#define __ENCODING_H + +#include + +/* known encodings */ +#define HTTPP_ENCODING_IDENTITY "identity" /* RFC2616 */ +#define HTTPP_ENCODING_CHUNKED "chunked" /* RFC2616 */ +#define HTTPP_ENCODING_GZIP "gzip" /* RFC1952 */ +#define HTTPP_ENCODING_COMPRESS "compress" /* ??? */ +#define HTTPP_ENCODING_DEFLATE "deflate" /* RFC1950, RFC1951 */ + +typedef struct httpp_encoding_tag httpp_encoding_t; + +typedef struct httpp_meta_tag httpp_meta_t; +struct httpp_meta_tag { + char *key; + void *value; + size_t value_len; + httpp_meta_t *next; +}; + +/* meta data functions */ +/* meta data is to be used in a encoding-specific way */ +httpp_meta_t *httpp_encoding_meta_new(const char *key, const char *value); +int httpp_encoding_meta_free(httpp_meta_t *self); +int httpp_encoding_meta_append(httpp_meta_t **dst, httpp_meta_t *next); + +/* General setup */ +httpp_encoding_t *httpp_encoding_new(const char *encoding); +int httpp_encoding_addref(httpp_encoding_t *self); +int httpp_encoding_release(httpp_encoding_t *self); + +/* Read data from backend. + * if cb is NULL this will read from the internal buffer. + */ +ssize_t httpp_encoding_read(httpp_encoding_t *self, void *buf, size_t len, ssize_t (*cb)(void*, void*, size_t), void *userdata); + +/* Read any meta data that is in buffer. + * After a call to this function the meta data is released from the + * encoding object and the caller is responsible to free it. + */ +httpp_meta_t *httpp_encoding_get_meta(httpp_encoding_t *self); + +/* Write data to backend. + * If buf is NULL this will flush buffers. + * Depending on encoding flushing buffers may not be safe if not + * at end of stream. + */ +ssize_t httpp_encoding_write(httpp_encoding_t *self, const void *buf, size_t len, ssize_t (*cb)(void*, const void*, size_t), void *userdata); + +/* Check if we have something to flush. */ +ssize_t httpp_encoding_pending(httpp_encoding_t *self); + +/* Attach meta data to the stream. + * this is to be written out as soon as the encoding supports. + */ +int httpp_encoding_append_meta(httpp_encoding_t *self, httpp_meta_t *meta); + +#endif diff --git a/lib/libshout/src/common/httpp/httpp.c b/lib/libshout/src/common/httpp/httpp.c new file mode 100644 index 00000000000..5e23a3ae0a2 --- /dev/null +++ b/lib/libshout/src/common/httpp/httpp.c @@ -0,0 +1,610 @@ +/* Httpp.c +** +** http parsing engine +** +** Copyright (C) 2014 Michael Smith , +** Ralph Giles , +** Ed "oddsock" Zaleski , +** Karl Heyes , +** Philipp "ph3-der-loewe" Schafft +** +** 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., 51 Franklin St, Fifth Floor, +** Boston, MA 02110-1301, USA. +** +*/ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include +#include +#include +#ifdef HAVE_STRINGS_H +#include +#endif + +#include +#include "httpp.h" + +#define MAX_HEADERS 32 + +/* internal functions */ + +/* misc */ +static char *_lowercase(char *str); + +/* for avl trees */ +static int _compare_vars(void *compare_arg, void *a, void *b); +static int _free_vars(void *key); + +http_parser_t *httpp_create_parser(void) +{ + return (http_parser_t *)malloc(sizeof(http_parser_t)); +} + +void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults) +{ + http_varlist_t *list; + + parser->req_type = httpp_req_none; + parser->uri = NULL; + parser->vars = avl_tree_new(_compare_vars, NULL); + parser->queryvars = avl_tree_new(_compare_vars, NULL); + + /* now insert the default variables */ + list = defaults; + while (list != NULL) { + httpp_setvar(parser, list->var.name, list->var.value); + list = list->next; + } +} + +static int split_headers(char *data, unsigned long len, char **line) +{ + /* first we count how many lines there are + ** and set up the line[] array + */ + int lines = 0; + unsigned long i; + line[lines] = data; + for (i = 0; i < len && lines < MAX_HEADERS; i++) { + if (data[i] == '\r') + data[i] = '\0'; + if (data[i] == '\n') { + lines++; + data[i] = '\0'; + if (lines >= MAX_HEADERS) + return MAX_HEADERS; + if (i + 1 < len) { + if (data[i + 1] == '\n' || data[i + 1] == '\r') + break; + line[lines] = &data[i + 1]; + } + } + } + + i++; + while (i < len && data[i] == '\n') i++; + + return lines; +} + +static void parse_headers(http_parser_t *parser, char **line, int lines) +{ + int i, l; + int whitespace, slen; + char *name = NULL; + char *value = NULL; + + /* parse the name: value lines. */ + for (l = 1; l < lines; l++) { + whitespace = 0; + name = line[l]; + value = NULL; + slen = strlen(line[l]); + for (i = 0; i < slen; i++) { + if (line[l][i] == ':') { + whitespace = 1; + line[l][i] = '\0'; + } else { + if (whitespace) { + whitespace = 0; + while (i < slen && line[l][i] == ' ') + i++; + + if (i < slen) + value = &line[l][i]; + + break; + } + } + } + + if (name != NULL && value != NULL) { + httpp_setvar(parser, _lowercase(name), value); + name = NULL; + value = NULL; + } + } +} + +int httpp_parse_response(http_parser_t *parser, const char *http_data, unsigned long len, const char *uri) +{ + char *data; + char *line[MAX_HEADERS]; + int lines, slen,i, whitespace=0, where=0,code; + char *version=NULL, *resp_code=NULL, *message=NULL; + + if(http_data == NULL) + return 0; + + /* make a local copy of the data, including 0 terminator */ + data = (char *)malloc(len+1); + if (data == NULL) return 0; + memcpy(data, http_data, len); + data[len] = 0; + + lines = split_headers(data, len, line); + + /* In this case, the first line contains: + * VERSION RESPONSE_CODE MESSAGE, such as HTTP/1.0 200 OK + */ + slen = strlen(line[0]); + version = line[0]; + for(i=0; i < slen; i++) { + if(line[0][i] == ' ') { + line[0][i] = 0; + whitespace = 1; + } else if(whitespace) { + whitespace = 0; + where++; + if(where == 1) + resp_code = &line[0][i]; + else { + message = &line[0][i]; + break; + } + } + } + + if(version == NULL || resp_code == NULL || message == NULL) { + free(data); + return 0; + } + + httpp_setvar(parser, HTTPP_VAR_ERROR_CODE, resp_code); + code = atoi(resp_code); + if(code < 200 || code >= 300) { + httpp_setvar(parser, HTTPP_VAR_ERROR_MESSAGE, message); + } + + httpp_setvar(parser, HTTPP_VAR_URI, uri); + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "NONE"); + + parse_headers(parser, line, lines); + + free(data); + + return 1; +} + +static int hex(char c) +{ + if(c >= '0' && c <= '9') + return c - '0'; + else if(c >= 'A' && c <= 'F') + return c - 'A' + 10; + else if(c >= 'a' && c <= 'f') + return c - 'a' + 10; + else + return -1; +} + +static char *url_escape(const char *src) +{ + int len = strlen(src); + unsigned char *decoded; + int i; + char *dst; + int done = 0; + + decoded = calloc(1, len + 1); + + dst = (char *)decoded; + + for(i=0; i < len; i++) { + switch(src[i]) { + case '%': + if(i+2 >= len) { + free(decoded); + return NULL; + } + if(hex(src[i+1]) == -1 || hex(src[i+2]) == -1 ) { + free(decoded); + return NULL; + } + + *dst++ = hex(src[i+1]) * 16 + hex(src[i+2]); + i+= 2; + break; + case '+': + *dst++ = ' '; + break; + case '#': + done = 1; + break; + case 0: + free(decoded); + return NULL; + break; + default: + *dst++ = src[i]; + break; + } + if(done) + break; + } + + *dst = 0; /* null terminator */ + + return (char *)decoded; +} + +/** TODO: This is almost certainly buggy in some cases */ +static void parse_query(http_parser_t *parser, char *query) +{ + int len; + int i=0; + char *key = query; + char *val=NULL; + + if(!query || !*query) + return; + + len = strlen(query); + + while(ireq_type = httpp_str_to_method(req_type); + + if (uri != NULL && strlen(uri) > 0) { + char *query; + if((query = strchr(uri, '?')) != NULL) { + httpp_setvar(parser, HTTPP_VAR_RAWURI, uri); + httpp_setvar(parser, HTTPP_VAR_QUERYARGS, query); + *query = 0; + query++; + parse_query(parser, query); + } + + parser->uri = strdup(uri); + } else { + free(data); + return 0; + } + + if ((version != NULL) && ((tmp = strchr(version, '/')) != NULL)) { + tmp[0] = '\0'; + if ((strlen(version) > 0) && (strlen(&tmp[1]) > 0)) { + httpp_setvar(parser, HTTPP_VAR_PROTOCOL, version); + httpp_setvar(parser, HTTPP_VAR_VERSION, &tmp[1]); + } else { + free(data); + return 0; + } + } else { + free(data); + return 0; + } + + if (parser->req_type != httpp_req_none && parser->req_type != httpp_req_unknown) { + switch (parser->req_type) { + case httpp_req_get: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "GET"); + break; + case httpp_req_post: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "POST"); + break; + case httpp_req_put: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "PUT"); + break; + case httpp_req_head: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "HEAD"); + break; + case httpp_req_options: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "OPTIONS"); + break; + case httpp_req_delete: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "DELETE"); + break; + case httpp_req_trace: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "TRACE"); + break; + case httpp_req_connect: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "CONNECT"); + break; + case httpp_req_source: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "SOURCE"); + break; + case httpp_req_play: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "PLAY"); + break; + case httpp_req_stats: + httpp_setvar(parser, HTTPP_VAR_REQ_TYPE, "STATS"); + break; + default: + break; + } + } else { + free(data); + return 0; + } + + if (parser->uri != NULL) { + httpp_setvar(parser, HTTPP_VAR_URI, parser->uri); + } else { + free(data); + return 0; + } + + parse_headers(parser, line, lines); + + free(data); + + return 1; +} + +void httpp_deletevar(http_parser_t *parser, const char *name) +{ + http_var_t var; + + if (parser == NULL || name == NULL) + return; + var.name = (char*)name; + var.value = NULL; + avl_delete(parser->vars, (void *)&var, _free_vars); +} + +void httpp_setvar(http_parser_t *parser, const char *name, const char *value) +{ + http_var_t *var; + + if (name == NULL || value == NULL) + return; + + var = (http_var_t *)malloc(sizeof(http_var_t)); + if (var == NULL) return; + + var->name = strdup(name); + var->value = strdup(value); + + if (httpp_getvar(parser, name) == NULL) { + avl_insert(parser->vars, (void *)var); + } else { + avl_delete(parser->vars, (void *)var, _free_vars); + avl_insert(parser->vars, (void *)var); + } +} + +const char *httpp_getvar(http_parser_t *parser, const char *name) +{ + http_var_t var; + http_var_t *found; + void *fp; + + if (parser == NULL || name == NULL) + return NULL; + + fp = &found; + var.name = (char*)name; + var.value = NULL; + + if (avl_get_by_key(parser->vars, &var, fp) == 0) + return found->value; + else + return NULL; +} + +void httpp_set_query_param(http_parser_t *parser, const char *name, const char *value) +{ + http_var_t *var; + + if (name == NULL || value == NULL) + return; + + var = (http_var_t *)malloc(sizeof(http_var_t)); + if (var == NULL) return; + + var->name = strdup(name); + var->value = url_escape(value); + + if (httpp_get_query_param(parser, name) == NULL) { + avl_insert(parser->queryvars, (void *)var); + } else { + avl_delete(parser->queryvars, (void *)var, _free_vars); + avl_insert(parser->queryvars, (void *)var); + } +} + +const char *httpp_get_query_param(http_parser_t *parser, const char *name) +{ + http_var_t var; + http_var_t *found; + void *fp; + + fp = &found; + var.name = (char *)name; + var.value = NULL; + + if (avl_get_by_key(parser->queryvars, (void *)&var, fp) == 0) + return found->value; + else + return NULL; +} + +void httpp_clear(http_parser_t *parser) +{ + parser->req_type = httpp_req_none; + if (parser->uri) + free(parser->uri); + parser->uri = NULL; + avl_tree_free(parser->vars, _free_vars); + avl_tree_free(parser->queryvars, _free_vars); + parser->vars = NULL; +} + +void httpp_destroy(http_parser_t *parser) +{ + httpp_clear(parser); + free(parser); +} + +static char *_lowercase(char *str) +{ + char *p = str; + for (; *p != '\0'; p++) + *p = tolower(*p); + + return str; +} + +static int _compare_vars(void *compare_arg, void *a, void *b) +{ + http_var_t *vara, *varb; + + vara = (http_var_t *)a; + varb = (http_var_t *)b; + + return strcmp(vara->name, varb->name); +} + +static int _free_vars(void *key) +{ + http_var_t *var; + + var = (http_var_t *)key; + + if (var->name) + free(var->name); + if (var->value) + free(var->value); + free(var); + + return 1; +} + +httpp_request_type_e httpp_str_to_method(const char * method) { + if (strcasecmp("GET", method) == 0) { + return httpp_req_get; + } else if (strcasecmp("POST", method) == 0) { + return httpp_req_post; + } else if (strcasecmp("PUT", method) == 0) { + return httpp_req_put; + } else if (strcasecmp("HEAD", method) == 0) { + return httpp_req_head; + } else if (strcasecmp("OPTIONS", method) == 0) { + return httpp_req_options; + } else if (strcasecmp("DELETE", method) == 0) { + return httpp_req_delete; + } else if (strcasecmp("TRACE", method) == 0) { + return httpp_req_trace; + } else if (strcasecmp("CONNECT", method) == 0) { + return httpp_req_connect; + } else if (strcasecmp("SOURCE", method) == 0) { + return httpp_req_source; + } else if (strcasecmp("PLAY", method) == 0) { + return httpp_req_play; + } else if (strcasecmp("STATS", method) == 0) { + return httpp_req_stats; + } else { + return httpp_req_unknown; + } +} + diff --git a/lib/libshout/src/common/httpp/httpp.h b/lib/libshout/src/common/httpp/httpp.h new file mode 100644 index 00000000000..226eb99def7 --- /dev/null +++ b/lib/libshout/src/common/httpp/httpp.h @@ -0,0 +1,111 @@ +/* httpp.h +** +** http parsing library +** +** Copyright (C) 2014 Michael Smith , +** Ralph Giles , +** Karl Heyes , +** Philipp "ph3-der-loewe" Schafft +** +** 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., 51 Franklin St, Fifth Floor, +** Boston, MA 02110-1301, USA. +** +*/ + +#ifndef __HTTPP_H +#define __HTTPP_H + +#include + +#define HTTPP_VAR_PROTOCOL "__protocol" +#define HTTPP_VAR_VERSION "__version" +#define HTTPP_VAR_URI "__uri" +#define HTTPP_VAR_RAWURI "__rawuri" +#define HTTPP_VAR_QUERYARGS " __queryargs" +#define HTTPP_VAR_REQ_TYPE "__req_type" +#define HTTPP_VAR_ERROR_MESSAGE "__errormessage" +#define HTTPP_VAR_ERROR_CODE "__errorcode" +#define HTTPP_VAR_ICYPASSWORD "__icy_password" + +typedef enum httpp_request_type_tag { + /* Initial and internally used state of the engine */ + httpp_req_none = 0, + /* Part of HTTP standard: GET, POST, PUT and HEAD */ + httpp_req_get, + httpp_req_post, + httpp_req_put, + httpp_req_head, + httpp_req_options, + httpp_req_delete, + httpp_req_trace, + httpp_req_connect, + /* Icecast SOURCE, to be replaced with PUT some day */ + httpp_req_source, + /* XXX: ??? */ + httpp_req_play, + /* Icecast 2.x STATS, to request a live stream of stats events */ + httpp_req_stats, + /* Used if request method is unknown. MUST BE LAST ONE IN LIST. */ + httpp_req_unknown +} httpp_request_type_e; + +typedef struct http_var_tag { + char *name; + char *value; +} http_var_t; + +typedef struct http_varlist_tag { + http_var_t var; + struct http_varlist_tag *next; +} http_varlist_t; + +typedef struct http_parser_tag { + httpp_request_type_e req_type; + char *uri; + avl_tree *vars; + avl_tree *queryvars; +} http_parser_t; + +#ifdef _mangle +# define httpp_create_parser _mangle(httpp_create_parser) +# define httpp_initialize _mangle(httpp_initialize) +# define httpp_parse _mangle(httpp_parse) +# define httpp_parse_icy _mangle(httpp_parse_icy) +# define httpp_parse_response _mangle(httpp_parse_response) +# define httpp_setvar _mangle(httpp_setvar) +# define httpp_getvar _mangle(httpp_getvar) +# define httpp_set_query_param _mangle(httpp_set_query_param) +# define httpp_get_query_param _mangle(httpp_get_query_param) +# define httpp_destroy _mangle(httpp_destroy) +# define httpp_clear _mangle(httpp_clear) +#endif + +http_parser_t *httpp_create_parser(void); +void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults); +int httpp_parse(http_parser_t *parser, const char *http_data, unsigned long len); +int httpp_parse_icy(http_parser_t *parser, const char *http_data, unsigned long len); +int httpp_parse_response(http_parser_t *parser, const char *http_data, unsigned long len, const char *uri); +void httpp_setvar(http_parser_t *parser, const char *name, const char *value); +void httpp_deletevar(http_parser_t *parser, const char *name); +const char *httpp_getvar(http_parser_t *parser, const char *name); +void httpp_set_query_param(http_parser_t *parser, const char *name, const char *value); +const char *httpp_get_query_param(http_parser_t *parser, const char *name); +void httpp_destroy(http_parser_t *parser); +void httpp_clear(http_parser_t *parser); + +/* util functions */ +httpp_request_type_e httpp_str_to_method(const char * method); + +#endif diff --git a/lib/libshout/src/common/net/BUILDING b/lib/libshout/src/common/net/BUILDING new file mode 100644 index 00000000000..b63563a442e --- /dev/null +++ b/lib/libshout/src/common/net/BUILDING @@ -0,0 +1,3 @@ +defines that affect compilation + +none currently diff --git a/lib/libshout/src/common/net/COPYING b/lib/libshout/src/common/net/COPYING new file mode 100644 index 00000000000..92b8903ff3f --- /dev/null +++ b/lib/libshout/src/common/net/COPYING @@ -0,0 +1,481 @@ + 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 + + 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 + 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! diff --git a/lib/libshout/src/common/net/Makefile.am b/lib/libshout/src/common/net/Makefile.am new file mode 100644 index 00000000000..0747825be85 --- /dev/null +++ b/lib/libshout/src/common/net/Makefile.am @@ -0,0 +1,20 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = BUILDING COPYING README TODO test_resolver.c + +noinst_LTLIBRARIES = libicenet.la +noinst_HEADERS = resolver.h sock.h + +libicenet_la_SOURCES = sock.c resolver.c +libicenet_la_CFLAGS = @XIPH_CFLAGS@ + +INCLUDES = -I$(srcdir)/.. + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@ + diff --git a/lib/libshout/src/common/net/README b/lib/libshout/src/common/net/README new file mode 100644 index 00000000000..d0d2d00a214 --- /dev/null +++ b/lib/libshout/src/common/net/README @@ -0,0 +1,10 @@ +This is a name resolving library that's threadsafe. + +Right now it only implements this with mutexes, but we should extend it to use gethostbyXXXX_r() +if it's available. + +It shoudl work on win32, but i'm probably forgetting a headerfile. + +API is basically not going to change. Please consult with the rest of the team before changing the interface. + +jack. \ No newline at end of file diff --git a/lib/libshout/src/common/net/TODO b/lib/libshout/src/common/net/TODO new file mode 100644 index 00000000000..3357459c9c1 --- /dev/null +++ b/lib/libshout/src/common/net/TODO @@ -0,0 +1 @@ +- add getXbyY_r function support diff --git a/lib/libshout/src/common/net/resolver.c b/lib/libshout/src/common/net/resolver.c new file mode 100644 index 00000000000..f5020822dd0 --- /dev/null +++ b/lib/libshout/src/common/net/resolver.c @@ -0,0 +1,233 @@ +/* + * resolver.c - name resolver library + * + * Copyright (C) 2014 Michael Smith , + * Brendan Cully , + * Karl Heyes , + * Jack Moffitt , + * Philipp "ph3-der-loewe" Schafft + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#else +#include +#endif + +#ifndef NO_THREAD +#include +#else +#define thread_mutex_create(x) do{}while(0) +#define thread_mutex_destroy(x) do{}while(0) +#define thread_mutex_lock(x) do{}while(0) +#define thread_mutex_unlock(x) do{}while(0) +#endif + +#include "resolver.h" +#include "sock.h" + +/* internal function */ + +static int _isip(const char *what); + +/* internal data */ + +#ifndef NO_THREAD +static mutex_t _resolver_mutex; +#endif +static int _initialized = 0; + +#ifdef HAVE_INET_PTON +static int _isip(const char *what) +{ + union { + struct in_addr v4addr; + struct in6_addr v6addr; + } addr_u; + + if (inet_pton(AF_INET, what, &addr_u.v4addr) <= 0) + return inet_pton(AF_INET6, what, &addr_u.v6addr) > 0 ? 1 : 0; + + return 1; +} + +#else +static int _isip(const char *what) +{ + struct in_addr inp; + + return inet_aton(what, &inp); +} +#endif + + +#if defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO) +char *resolver_getname(const char *ip, char *buff, int len) +{ + struct addrinfo *head = NULL, hints; + char *ret = NULL; + + if (!_isip(ip)) { + strncpy(buff, ip, len); + buff [len-1] = '\0'; + return buff; + } + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if (getaddrinfo (ip, NULL, &hints, &head)) + return NULL; + + if (head) + { + if (getnameinfo(head->ai_addr, head->ai_addrlen, buff, len, NULL, + 0, NI_NAMEREQD) == 0) + ret = buff; + + freeaddrinfo (head); + } + + return ret; +} + + +char *resolver_getip(const char *name, char *buff, int len) +{ + struct addrinfo *head, hints; + char *ret = NULL; + + if (_isip(name)) { + strncpy(buff, name, len); + buff [len-1] = '\0'; + return buff; + } + + memset (&hints, 0, sizeof (hints)); + hints . ai_family = AF_UNSPEC; + hints . ai_socktype = SOCK_STREAM; + if (getaddrinfo (name, NULL, &hints, &head)) + return NULL; + + if (head) + { + if (getnameinfo(head->ai_addr, head->ai_addrlen, buff, len, NULL, + 0, NI_NUMERICHOST) == 0) + ret = buff; + freeaddrinfo (head); + } + + return ret; +} + +#else + +char *resolver_getname(const char *ip, char *buff, int len) +{ + struct hostent *host; + char *ret = NULL; + struct in_addr addr; + + if (! _isip(ip)) + { + strncpy(buff, ip, len); + buff [len-1] = '\0'; + return buff; + } + + thread_mutex_lock(&_resolver_mutex); + if (inet_aton (ip, &addr)) { + /* casting &addr to const char* as it is recommended on win* */ + if ((host=gethostbyaddr ((const char *)&addr, sizeof (struct in_addr), AF_INET))) + { + ret = strncpy (buff, host->h_name, len); + buff [len-1] = '\0'; + } + } + + thread_mutex_unlock(&_resolver_mutex); + return ret; +} + +char *resolver_getip(const char *name, char *buff, int len) +{ + struct hostent *host; + char *ret = NULL; + + if (_isip(name)) + { + strncpy(buff, name, len); + buff [len-1] = '\0'; + return buff; + } + thread_mutex_lock(&_resolver_mutex); + host = gethostbyname(name); + if (host) + { + char * temp = inet_ntoa(*(struct in_addr *)host->h_addr); + ret = strncpy(buff, temp, len); + buff [len-1] = '\0'; + } + thread_mutex_unlock(&_resolver_mutex); + + return ret; +} +#endif + + +void resolver_initialize() +{ + /* initialize the lib if we havne't done so already */ + + if (!_initialized) + { + _initialized = 1; + thread_mutex_create (&_resolver_mutex); + + /* keep dns connects (TCP) open */ +#ifdef HAVE_SETHOSTENT + sethostent(1); +#endif + } +} + +void resolver_shutdown(void) +{ + if (_initialized) + { + thread_mutex_destroy(&_resolver_mutex); + _initialized = 0; +#ifdef HAVE_ENDHOSTENT + endhostent(); +#endif + } +} + diff --git a/lib/libshout/src/common/net/resolver.h b/lib/libshout/src/common/net/resolver.h new file mode 100644 index 00000000000..d4529cee606 --- /dev/null +++ b/lib/libshout/src/common/net/resolver.h @@ -0,0 +1,59 @@ +/* + * resolver.h + * + * name resolver library header + * + * Copyright (C) 2014 Brendan Cully , + * Jack Moffitt + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef __RESOLVER_H +#define __RESOLVER_H + + +/* +** resolver_lookup +** +** resolves a hosts name from it's ip address +** or +** resolves an ip address from it's host name +** +** returns a pointer to buff, or NULL if an error occured +** +*/ + +#ifdef _mangle +# define resolver_initialize _mangle(resolver_initialize) +# define resolver_shutdown _mangle(resolver_shutdown) +# define resolver_getname _mangle(resolver_getname) +# define resolver_getip _mangle(resolver_getip) +#endif + +void resolver_initialize(void); +void resolver_shutdown(void); + +char *resolver_getname(const char *ip, char *buff, int len); +char *resolver_getip(const char *name, char *buff, int len); + +#endif + + + + + diff --git a/lib/libshout/src/common/net/sock.c b/lib/libshout/src/common/net/sock.c new file mode 100644 index 00000000000..d82a8a607c6 --- /dev/null +++ b/lib/libshout/src/common/net/sock.c @@ -0,0 +1,962 @@ +/* -*- c-basic-offset: 4; -*- */ +/* sock.c: General Socket Functions + * + * Copyright (C) 2014 Michael Smith , + * Brendan Cully , + * Karl Heyes , + * Jack Moffitt , + * Ed "oddsock" Zaleski + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_POLL +#include +#endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#else +#include +#endif + +#include "sock.h" +#include "resolver.h" + +/* for older C libraries */ +#ifndef AI_NUMERICSERV +# define AI_NUMERICSERV 0 +#endif +#ifndef AI_ADDRCONFIG +# define AI_ADDRCONFIG 0 +#endif + +/* sock_initialize +** +** initializes the socket library. you must call this +** before using the library! +*/ +void sock_initialize(void) +{ +#ifdef _WIN32 + WSADATA wsad; + WSAStartup(0x0101, &wsad); +#endif + + resolver_initialize(); +} + +/* sock_shutdown +** +** shutdown the socket library. remember to call this when you're +** through using the lib +*/ +void sock_shutdown(void) +{ +#ifdef _WIN32 + WSACleanup(); +#endif + + resolver_shutdown(); +} + +/* sock_get_localip +** +** gets the local ip address for the machine +** the ip it returns *should* be on the internet. +** in any case, it's as close as we can hope to get +** unless someone has better ideas on how to do this +*/ +char *sock_get_localip(char *buff, int len) +{ + char temp[1024]; + + if (gethostname(temp, sizeof(temp)) != 0) + return NULL; + + if (resolver_getip(temp, buff, len)) + return buff; + + return NULL; +} + +/* sock_error +** +** returns the last socket error +*/ +int sock_error(void) +{ +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + +void sock_set_error(int val) +{ +#ifdef _WIN32 + WSASetLastError (val); +#else + errno = val; +#endif +} + +/* sock_recoverable +** +** determines if the socket error is recoverable +** in terms of non blocking sockets +*/ +int sock_recoverable(int error) +{ + switch (error) + { + case 0: + case EAGAIN: + case EINTR: + case EINPROGRESS: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif +#if defined (WSAEWOULDBLOCK) && WSAEWOULDBLOCK != EWOULDBLOCK + case WSAEWOULDBLOCK: +#endif +#if defined (WSAEINPROGRESS) && WSAEINPROGRESS != EINPROGRESS + case WSAEINPROGRESS: +#endif +#ifdef ERESTART + case ERESTART: +#endif + return 1; + default: + return 0; + } +} + +int sock_stalled (int error) +{ + switch (error) + { + case EAGAIN: + case EINPROGRESS: + case EALREADY: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif +#if defined (WSAEWOULDBLOCK) && WSAEWOULDBLOCK != EWOULDBLOCK + case WSAEWOULDBLOCK: +#endif +#if defined (WSAEINPROGRESS) && WSAEINPROGRESS != EINPROGRESS + case WSAEINPROGRESS: +#endif +#ifdef ERESTART + case ERESTART: +#endif + return 1; + default: + return 0; + } +} + + +static int sock_connect_pending (int error) +{ + return error == EINPROGRESS || error == EALREADY; +} + +/* sock_valid_socket +** +** determines if a sock_t represents a valid socket +*/ +int sock_valid_socket(sock_t sock) +{ + int ret; + int optval; + socklen_t optlen; + + optlen = sizeof(int); + /* apparently on windows getsockopt.optval is a char * */ + ret = getsockopt(sock, SOL_SOCKET, SO_TYPE, (void*) &optval, &optlen); + + return (ret == 0); +} + + +/* determines if the passed socket is still connected */ +int sock_active (sock_t sock) +{ + char c; + int l; + + l = recv (sock, &c, 1, MSG_PEEK); + if (l == 0) + return 0; + if (l == SOCK_ERROR && sock_recoverable (sock_error())) + return 1; + return 0; +} + +/* inet_aton +** +** turns an ascii ip address into a binary representation +*/ +#ifdef _WIN32 +int inet_aton(const char *s, struct in_addr *a) +{ + int lsb, b2, b3, msb; + + if (sscanf(s, "%d.%d.%d.%d", &lsb, &b2, &b3, &msb) < 4) { + return 0; + } + + a->s_addr = inet_addr(s); + + return (a->s_addr != INADDR_NONE); +} +#endif /* _WIN32 */ + +/* sock_set_blocking + * + * set the sock blocking or nonblocking + * 1 for blocking + * 0 for nonblocking + */ +int sock_set_blocking(sock_t sock, int block) +{ +#ifdef _WIN32 +#ifdef __MINGW32__ + u_long varblock = 1; +#else + int varblock = 1; +#endif +#endif + + if ((!sock_valid_socket(sock)) || (block < 0) || (block > 1)) + return SOCK_ERROR; + +#ifdef _WIN32 + if (block) varblock = 0; + return ioctlsocket(sock, FIONBIO, &varblock); +#else + return fcntl(sock, F_SETFL, (block) ? 0 : O_NONBLOCK); +#endif +} + +int sock_set_nolinger(sock_t sock) +{ + struct linger lin = { 0, 0 }; + return setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&lin, + sizeof(struct linger)); +} + +int sock_set_nodelay(sock_t sock) +{ + int nodelay = 1; + + return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, + sizeof(int)); +} + +int sock_set_keepalive(sock_t sock) +{ + int keepalive = 1; + return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, + sizeof(int)); +} + +/* sock_close +** +** close the socket +*/ +int sock_close(sock_t sock) +{ +#ifdef _WIN32 + return closesocket(sock); +#else + return close(sock); +#endif +} + +/* sock_writev + * + * write multiple buffers at once, return bytes actually written + */ +#ifdef HAVE_WRITEV + +ssize_t sock_writev (sock_t sock, const struct iovec *iov, size_t count) +{ + return writev (sock, iov, count); +} + +#else + +ssize_t sock_writev (sock_t sock, const struct iovec *iov, size_t count) +{ + int i = count, accum = 0, ret; + const struct iovec *v = iov; + + while (i) + { + if (v->iov_base && v->iov_len) + { + ret = sock_write_bytes (sock, v->iov_base, v->iov_len); + if (ret == -1 && accum==0) + return -1; + if (ret == -1) + ret = 0; + accum += ret; + if (ret < (int)v->iov_len) + break; + } + v++; + i--; + } + return accum; +} + +#endif + +/* sock_write_bytes +** +** write bytes to the socket +** this function will _NOT_ block +*/ +int sock_write_bytes(sock_t sock, const void *buff, size_t len) +{ + /* sanity check */ + if (!buff) { + return SOCK_ERROR; + } else if (len <= 0) { + return SOCK_ERROR; + } /*else if (!sock_valid_socket(sock)) { + return SOCK_ERROR; + } */ + + return send(sock, buff, len, 0); +} + +/* sock_write_string +** +** writes a string to a socket +** This function must only be called with a blocking socket. +*/ +int sock_write_string(sock_t sock, const char *buff) +{ + return (sock_write_bytes(sock, buff, strlen(buff)) > 0); +} + +/* sock_write +** +** write a formatted string to the socket +** this function must only be called with a blocking socket. +** will truncate the string if it's greater than 1024 chars. +*/ +int sock_write(sock_t sock, const char *fmt, ...) +{ + int rc; + va_list ap; + + va_start (ap, fmt); + rc = sock_write_fmt (sock, fmt, ap); + va_end (ap); + + return rc; +} + +#ifdef HAVE_OLD_VSNPRINTF +int sock_write_fmt(sock_t sock, const char *fmt, va_list ap) +{ + va_list ap_local; + unsigned int len = 1024; + char *buff = NULL; + int ret; + + /* don't go infinite, but stop at some huge limit */ + while (len < 2*1024*1024) + { + char *tmp = realloc (buff, len); + ret = -1; + if (tmp == NULL) + break; + buff = tmp; + va_copy (ap_local, ap); + ret = vsnprintf (buff, len, fmt, ap_local); + if (ret > 0) + { + ret = sock_write_bytes (sock, buff, ret); + break; + } + len += 8192; + } + free (buff); + return ret; +} +#else +int sock_write_fmt(sock_t sock, const char *fmt, va_list ap) +{ + char buffer [1024], *buff = buffer; + int len; + int rc = SOCK_ERROR; + va_list ap_retry; + + va_copy (ap_retry, ap); + + len = vsnprintf (buff, sizeof (buffer), fmt, ap); + + if (len > 0) + { + if ((size_t)len < sizeof (buffer)) /* common case */ + rc = sock_write_bytes(sock, buff, (size_t)len); + else + { + /* truncated */ + buff = malloc (++len); + if (buff) + { + len = vsnprintf (buff, len, fmt, ap_retry); + if (len > 0) + rc = sock_write_bytes (sock, buff, len); + free (buff); + } + } + } + va_end (ap_retry); + + return rc; +} +#endif + + +int sock_read_bytes(sock_t sock, char *buff, size_t len) +{ + + /*if (!sock_valid_socket(sock)) return 0; */ + if (!buff) return 0; + if (len <= 0) return 0; + + return recv(sock, buff, len, 0); +} + +/* sock_read_line +** +** Read one line of at max len bytes from sock into buff. +** If ok, return 1 and nullterminate buff. Otherwize return 0. +** Terminating \n is not put into the buffer. +** +** this function will probably not work on sockets in nonblocking mode +*/ +int sock_read_line(sock_t sock, char *buff, const int len) +{ + char c = '\0'; + int read_bytes, pos; + + /*if (!sock_valid_socket(sock)) { + return 0; + } else*/ if (!buff) { + return 0; + } else if (len <= 0) { + return 0; + } + + pos = 0; + read_bytes = recv(sock, &c, 1, 0); + + if (read_bytes < 0) { + return 0; + } + + while ((c != '\n') && (pos < len) && (read_bytes == 1)) { + if (c != '\r') + buff[pos++] = c; + read_bytes = recv(sock, &c, 1, 0); + } + + if (read_bytes == 1) { + buff[pos] = '\0'; + return 1; + } else { + return 0; + } +} + +/* see if a connection has been established. If timeout is < 0 then wait + * indefinitely, else wait for the stated number of seconds. + * return SOCK_TIMEOUT for timeout + * return SOCK_ERROR for failure + * return 0 for try again, interrupted + * return 1 for ok + */ +#ifdef HAVE_POLL +int sock_connected (sock_t sock, int timeout) +{ + struct pollfd check; + int val = SOCK_ERROR; + socklen_t size = sizeof val; + + check.fd = sock; + check.events = POLLOUT; + switch (poll (&check, 1, timeout*1000)) + { + case 0: return SOCK_TIMEOUT; + default: + /* on windows getsockopt.val is defined as char* */ + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) == 0) + { + if (val == 0) + return 1; + sock_set_error (val); + } + /* fall through */ + case -1: + if (sock_recoverable (sock_error())) + return 0; + return SOCK_ERROR; + } +} + +#else + +int sock_connected (sock_t sock, int timeout) +{ + fd_set wfds; + int val = SOCK_ERROR; + socklen_t size = sizeof val; + struct timeval tv, *timeval = NULL; + + /* make a timeout of <0 be indefinite */ + if (timeout >= 0) + { + tv.tv_sec = timeout; + tv.tv_usec = 0; + timeval = &tv; + } + + FD_ZERO(&wfds); + FD_SET(sock, &wfds); + + switch (select(sock + 1, NULL, &wfds, NULL, timeval)) + { + case 0: + return SOCK_TIMEOUT; + default: + /* on windows getsockopt.val is defined as char* */ + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) == 0) + { + if (val == 0) + return 1; + sock_set_error (val); + } + /* fall through */ + case -1: + if (sock_recoverable (sock_error())) + return 0; + return SOCK_ERROR; + } +} +#endif + +sock_t sock_connect_wto (const char *hostname, int port, int timeout) +{ + return sock_connect_wto_bind(hostname, port, NULL, timeout); +} + +#ifdef HAVE_GETADDRINFO + +sock_t sock_connect_non_blocking (const char *hostname, unsigned port) +{ + int sock = SOCK_ERROR; + struct addrinfo *ai, *head, hints; + char service[8]; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + snprintf (service, sizeof (service), "%u", port); + + if (getaddrinfo (hostname, service, &hints, &head)) + return SOCK_ERROR; + + ai = head; + while (ai) + { + if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) + > -1) + { + sock_set_blocking (sock, 0); + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && + !sock_connect_pending(sock_error())) + { + sock_close (sock); + sock = SOCK_ERROR; + } + else + break; + } + ai = ai->ai_next; + } + if (head) freeaddrinfo (head); + + return sock; +} + +/* issue a connect, but return after the timeout (seconds) is reached. If + * timeout is 0 or less then we will wait until the OS gives up on the connect + * The socket is returned + */ +sock_t sock_connect_wto_bind (const char *hostname, int port, const char *bnd, int timeout) +{ + sock_t sock = SOCK_ERROR; + struct addrinfo *ai, *head, *b_head=NULL, hints; + char service[8]; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + snprintf (service, sizeof (service), "%u", port); + + if (getaddrinfo (hostname, service, &hints, &head)) + return SOCK_ERROR; + + ai = head; + while (ai) + { + if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) >= 0) + { + if (timeout > 0) + sock_set_blocking (sock, 0); + + if (bnd) + { + struct addrinfo b_hints; + memset (&b_hints, 0, sizeof(b_hints)); + b_hints.ai_family = ai->ai_family; + b_hints.ai_socktype = ai->ai_socktype; + b_hints.ai_protocol = ai->ai_protocol; + if (getaddrinfo (bnd, NULL, &b_hints, &b_head) || + bind (sock, b_head->ai_addr, b_head->ai_addrlen) < 0) + { + sock_close (sock); + sock = SOCK_ERROR; + break; + } + } + + if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0) + break; + + /* loop as the connect maybe async */ + while (sock != SOCK_ERROR) + { + if (sock_recoverable (sock_error())) + { + int connected = sock_connected (sock, timeout); + if (connected == 0) /* try again, interrupted */ + continue; + if (connected == 1) /* connected */ + { + if (timeout >= 0) + sock_set_blocking(sock, 1); + break; + } + } + sock_close (sock); + sock = SOCK_ERROR; + } + if (sock != SOCK_ERROR) + break; + } + ai = ai->ai_next; + } + if (b_head) + freeaddrinfo (b_head); + freeaddrinfo (head); + + return sock; +} + + +sock_t sock_get_server_socket (int port, const char *sinterface) +{ + struct sockaddr_storage sa; + struct addrinfo hints, *res, *ai; + char service [10]; + int sock; + + if (port < 0) + return SOCK_ERROR; + + memset (&sa, 0, sizeof(sa)); + memset (&hints, 0, sizeof(hints)); + + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG | AI_NUMERICSERV | AI_NUMERICHOST; + hints.ai_socktype = SOCK_STREAM; + snprintf (service, sizeof (service), "%d", port); + + if (getaddrinfo (sinterface, service, &hints, &res)) + return SOCK_ERROR; + ai = res; + do + { + int on = 1; + sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) + continue; + + setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)); + on = 0; +#ifdef IPV6_V6ONLY + setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on); +#endif + + if (bind (sock, ai->ai_addr, ai->ai_addrlen) < 0) + { + sock_close (sock); + continue; + } + freeaddrinfo (res); + return sock; + + } while ((ai = ai->ai_next)); + + freeaddrinfo (res); + return SOCK_ERROR; +} + + +#else + + +int sock_try_connection (sock_t sock, const char *hostname, unsigned int port) +{ + struct sockaddr_in sin, server; + char ip[MAX_ADDR_LEN]; + + if (!hostname || !hostname[0] || port == 0) + return -1; + + memset(&sin, 0, sizeof(struct sockaddr_in)); + memset(&server, 0, sizeof(struct sockaddr_in)); + + if (!resolver_getip(hostname, ip, MAX_ADDR_LEN)) + { + sock_close (sock); + return -1; + } + + if (inet_aton(ip, (struct in_addr *)&sin.sin_addr) == 0) + { + sock_close(sock); + return -1; + } + + memcpy(&server.sin_addr, &sin.sin_addr, sizeof(struct sockaddr_in)); + + server.sin_family = AF_INET; + server.sin_port = htons((short)port); + + return connect(sock, (struct sockaddr *)&server, sizeof(server)); +} + +sock_t sock_connect_non_blocking (const char *hostname, unsigned port) +{ + sock_t sock; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == SOCK_ERROR) + return SOCK_ERROR; + + sock_set_blocking (sock, 0); + sock_try_connection (sock, hostname, port); + + return sock; +} + +sock_t sock_connect_wto_bind (const char *hostname, int port, const char *bnd, int timeout) +{ + sock_t sock; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == SOCK_ERROR) + return SOCK_ERROR; + + if (bnd) + { + struct sockaddr_in sa; + + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + + if (inet_aton (bnd, &sa.sin_addr) == 0 || + bind (sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) + { + sock_close (sock); + return SOCK_ERROR; + } + } + + if (timeout) + { + sock_set_blocking (sock, 0); + if (sock_try_connection (sock, hostname, port) < 0) + { + int ret = sock_connected (sock, timeout); + if (ret <= 0) + { + sock_close (sock); + return SOCK_ERROR; + } + } + sock_set_blocking(sock, 1); + } + else + { + if (sock_try_connection (sock, hostname, port) < 0) + { + sock_close (sock); + sock = SOCK_ERROR; + } + } + return sock; +} + + +/* sock_get_server_socket +** +** create a socket for incoming requests on a specified port and +** interface. if interface is null, listen on all interfaces. +** returns the socket, or SOCK_ERROR on failure +*/ +sock_t sock_get_server_socket(int port, const char *sinterface) +{ + struct sockaddr_in sa; + int error, opt; + sock_t sock; + char ip[MAX_ADDR_LEN]; + + if (port < 0) + return SOCK_ERROR; + + /* defaults */ + memset(&sa, 0, sizeof(sa)); + + /* set the interface to bind to if specified */ + if (sinterface != NULL) { + if (!resolver_getip(sinterface, ip, sizeof (ip))) + return SOCK_ERROR; + + if (!inet_aton(ip, &sa.sin_addr)) { + return SOCK_ERROR; + } else { + sa.sin_family = AF_INET; + sa.sin_port = htons((short)port); + } + } else { + sa.sin_addr.s_addr = INADDR_ANY; + sa.sin_family = AF_INET; + sa.sin_port = htons((short)port); + } + + /* get a socket */ + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock == -1) + return SOCK_ERROR; + + /* reuse it if we can */ + opt = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(int)); + + /* bind socket to port */ + error = bind(sock, (struct sockaddr *)&sa, sizeof (struct sockaddr_in)); + if (error == -1) + return SOCK_ERROR; + + return sock; +} + +#endif + +void sock_set_send_buffer (sock_t sock, int win_size) +{ + setsockopt (sock, SOL_SOCKET, SO_SNDBUF, (char *) &win_size, sizeof(win_size)); +} + +int sock_listen(sock_t serversock, int backlog) +{ + if (!sock_valid_socket(serversock)) + return 0; + + if (backlog <= 0) + backlog = 10; + + return (listen(serversock, backlog) == 0); +} + +sock_t sock_accept(sock_t serversock, char *ip, size_t len) +{ +#ifdef HAVE_GETNAMEINFO + struct sockaddr_storage sa; +#else + struct sockaddr_in sa; +#endif + sock_t ret; + socklen_t slen; + + if (ip == NULL || len == 0 || !sock_valid_socket(serversock)) + return SOCK_ERROR; + + slen = sizeof(sa); + ret = accept(serversock, (struct sockaddr *)&sa, &slen); + + if (ret != SOCK_ERROR) + { +#ifdef HAVE_GETNAMEINFO + if (getnameinfo ((struct sockaddr *)&sa, slen, ip, len, NULL, 0, NI_NUMERICHOST)) + snprintf (ip, len, "unknown"); +#else + /* inet_ntoa is not reentrant, we should protect this */ + strncpy(ip, inet_ntoa(sa.sin_addr), len); +#endif + sock_set_nolinger(ret); + sock_set_keepalive(ret); + } + + return ret; +} + diff --git a/lib/libshout/src/common/net/sock.h b/lib/libshout/src/common/net/sock.h new file mode 100644 index 00000000000..e0e3d4fcf8e --- /dev/null +++ b/lib/libshout/src/common/net/sock.h @@ -0,0 +1,151 @@ +/* sock.h + * - General Socket Function Headers + * + * Copyright (C) 2014 Michael Smith , + * Brendan Cully , + * Karl Heyes , + * Jack Moffitt , + * Ed "oddsock" Zaleski + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef __SOCK_H +#define __SOCK_H + +#include + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#elif _WIN32 +#include +#endif + +#ifdef HAVE_SYS_UIO_H +#include +#else +#ifndef _SYS_UIO_H +struct iovec +{ + void *iov_base; + size_t iov_len; +}; +#endif +#endif + +#if !defined(HAVE_INET_ATON) && defined(HAVE_INET_PTON) +#define inet_aton(a,b) inet_pton(AF_INET, (a), (b)) +#endif + +#ifdef INET6_ADDRSTRLEN +#define MAX_ADDR_LEN INET6_ADDRSTRLEN +#else +#define MAX_ADDR_LEN 46 +#endif + +#ifndef sock_t +#define sock_t int +#endif + +/* The following values are based on unix avoiding errno value clashes */ +#define SOCK_SUCCESS 0 +#define SOCK_ERROR (sock_t)-1 +#define SOCK_TIMEOUT -2 + +/* sock connect macro */ +#define sock_connect(h, p) sock_connect_wto(h, p, 0) + +#ifdef _mangle +# define sock_initialize _mangle(sock_initialize) +# define sock_shutdown _mangle(sock_shutdown) +# define sock_get_localip _mangle(sock_get_localip) +# define sock_error _mangle(sock_error) +# define sock_set_error _mangle(sock_set_error) +# define sock_recoverable _mangle(sock_recoverable) +# define sock_stalled _mangle(sock_stalled) +# define sock_valid_socket _mangle(sock_valid_socket) +# define sock_set_blocking _mangle(sock_set_blocking) +# define sock_set_nolinger _mangle(sock_set_nolinger) +# define sock_set_nodelay _mangle(sock_set_nodelay) +# define sock_set_keepalive _mangle(sock_set_keepalive) +# define sock_close _mangle(sock_close) +# define sock_connect_wto _mangle(sock_connect_wto) +# define sock_connect_wto_bind _mangle(sock_connect_wto_bind) +# define sock_connect_non_blocking _mangle(sock_connect_non_blocking) +# define sock_connected _mangle(sock_connected) +# define sock_write_bytes _mangle(sock_write_bytes) +# define sock_write _mangle(sock_write) +# define sock_write_fmt _mangle(sock_write_fmt) +# define sock_write_string _mangle(sock_write_string) +# define sock_writev _mangle(sock_writev) +# define sock_read_bytes _mangle(sock_read_bytes) +# define sock_read_line _mangle(sock_read_line) +# define sock_get_server_socket _mangle(sock_get_server_socket) +# define sock_listen _mangle(sock_listen) +# define sock_set_send_buffer _mangle(sock_set_send_buffer) +# define sock_accept _mangle(sock_accept) +#endif + +/* Misc socket functions */ +void sock_initialize(void); +void sock_shutdown(void); +char *sock_get_localip(char *buff, int len); +int sock_error(void); +int sock_recoverable(int error); +int sock_stalled(int error); +int sock_valid_socket(sock_t sock); +int sock_active (sock_t sock); +int sock_set_blocking(sock_t sock, int block); +int sock_set_nolinger(sock_t sock); +int sock_set_keepalive(sock_t sock); +int sock_set_nodelay(sock_t sock); +void sock_set_send_buffer (sock_t sock, int win_size); +void sock_set_error(int val); +int sock_close(sock_t sock); + +/* Connection related socket functions */ +sock_t sock_connect_wto(const char *hostname, int port, int timeout); +sock_t sock_connect_wto_bind(const char *hostname, int port, const char *bnd, int timeout); +sock_t sock_connect_non_blocking(const char *host, unsigned port); +int sock_connected(sock_t sock, int timeout); + +/* Socket write functions */ +int sock_write_bytes(sock_t sock, const void *buff, size_t len); +int sock_write(sock_t sock, const char *fmt, ...); +int sock_write_fmt(sock_t sock, const char *fmt, va_list ap); +int sock_write_string(sock_t sock, const char *buff); +ssize_t sock_writev (sock_t sock, const struct iovec *iov, size_t count); + + +/* Socket read functions */ +int sock_read_bytes(sock_t sock, char *buff, size_t len); +int sock_read_line(sock_t sock, char *string, const int len); + +/* server socket functions */ +sock_t sock_get_server_socket(int port, const char *sinterface); +int sock_listen(sock_t serversock, int backlog); +sock_t sock_accept(sock_t serversock, char *ip, size_t len); + +#ifdef _WIN32 +int inet_aton(const char *s, struct in_addr *a); +#endif + +#endif /* __SOCK_H */ diff --git a/lib/libshout/src/common/net/test_resolver.c b/lib/libshout/src/common/net/test_resolver.c new file mode 100644 index 00000000000..cac1c8e23cb --- /dev/null +++ b/lib/libshout/src/common/net/test_resolver.c @@ -0,0 +1,17 @@ +#include +#include + +#include "resolver.h" + +int main() +{ + char buff[1024]; + + resolver_initialize(); + + printf("I got %s, when looking up %s.\n", resolver_getip("bach.greenwitch.com", buff, 1024), "bach.greenwitch.com"); + printf("I got %s, when looking up %s.\n", resolver_getname("207.181.249.14", buff, 1024), "207.181.249.14"); + + return 0; +} + diff --git a/lib/libshout/src/common/thread/BUILDING b/lib/libshout/src/common/thread/BUILDING new file mode 100644 index 00000000000..ebe84227ec8 --- /dev/null +++ b/lib/libshout/src/common/thread/BUILDING @@ -0,0 +1,20 @@ +defines that affect compilation + +_WIN32 + this should be defined for Win32 platforms + +DEBUG_MUTEXES + define this to turn on mutex debugging. this will log locks/unlocks. + +CHECK_MUTEXES (DEBUG_MUTEXES must also be defined) + checks to make sure mutex operations make sense. ie, multi_mutex is locked + when locking multiple mutexes, etc. + +THREAD_DEBUG (define to 1-4) + turns on the thread.log logging + + + + + + diff --git a/lib/libshout/src/common/thread/COPYING b/lib/libshout/src/common/thread/COPYING new file mode 100644 index 00000000000..92b8903ff3f --- /dev/null +++ b/lib/libshout/src/common/thread/COPYING @@ -0,0 +1,481 @@ + 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 + + 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 + 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! diff --git a/lib/libshout/src/common/thread/Makefile.am b/lib/libshout/src/common/thread/Makefile.am new file mode 100644 index 00000000000..5651a1bcadd --- /dev/null +++ b/lib/libshout/src/common/thread/Makefile.am @@ -0,0 +1,20 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = BUILDING COPYING README TODO + +noinst_LTLIBRARIES = libicethread.la +noinst_HEADERS = thread.h + +libicethread_la_SOURCES = thread.c +libicethread_la_CFLAGS = @XIPH_CFLAGS@ + +INCLUDES = -I$(srcdir)/.. + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" + diff --git a/lib/libshout/src/common/thread/README b/lib/libshout/src/common/thread/README new file mode 100644 index 00000000000..0ccadb07e75 --- /dev/null +++ b/lib/libshout/src/common/thread/README @@ -0,0 +1,9 @@ +This is the cross platform thread and syncronization library. + +It depends on the avl library. + +This is a massively cleaned and picked through version of the code from +the icecast 1.3.x base. It has not been heavily tested *YET*. But since +it's just cleanups, it really shouldn't have that many problems. + +jack. diff --git a/lib/libshout/src/common/thread/TODO b/lib/libshout/src/common/thread/TODO new file mode 100644 index 00000000000..84f20108980 --- /dev/null +++ b/lib/libshout/src/common/thread/TODO @@ -0,0 +1,5 @@ +- make DEBUG_MUTEXES and CHECK_MUTEXES work + +- recursive locking/unlocking (easy) +- reader/writer locking (easy) +- make a mode were _log is disabled (normal mode) (easy) diff --git a/lib/libshout/src/common/thread/thread.c b/lib/libshout/src/common/thread/thread.c new file mode 100644 index 00000000000..e29ea2063fe --- /dev/null +++ b/lib/libshout/src/common/thread/thread.c @@ -0,0 +1,846 @@ +/* threads.c: Thread Abstraction Functions + * + * Copyright (C) 2014 Michael Smith , + * Brendan Cully , + * Karl Heyes , + * Jack Moffitt , + * Ed "oddsock" Zaleski + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#ifndef _WIN32 +#include +#include +#else +#include +#include +#endif + +#include + +#include +#include +#ifdef THREAD_DEBUG +#include +#endif + +#ifdef _WIN32 +#define __FUNCTION__ __FILE__ +#endif + +#ifdef THREAD_DEBUG +#define CATMODULE "thread" +#define LOG_ERROR(y) log_write(_logid, 1, CATMODULE "/", __FUNCTION__, y) +#define LOG_ERROR3(y, z1, z2, z3) log_write(_logid, 1, CATMODULE "/", __FUNCTION__, y, z1, z2, z3) +#define LOG_ERROR7(y, z1, z2, z3, z4, z5, z6, z7) log_write(_logid, 1, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5, z6, z7) + +#define LOG_WARN(y) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y) +#define LOG_WARN3(y, z1, z2, z3) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y, z1, z2, z3) +#define LOG_WARN5(y, z1, z2, z3, z4, z5) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5) +#define LOG_WARN7(y, z1, z2, z3, z4, z5, z6, z7) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5, z6, z7) + +#define LOG_INFO(y) log_write(_logid, 3, CATMODULE "/", __FUNCTION__, y) +#define LOG_INFO4(y, z1, z2, z3, z4) log_write(_logid, 3, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4) +#define LOG_INFO5(y, z1, z2, z3, z4, z5) log_write(_logid, 3, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5) + +#define LOG_DEBUG(y) log_write(_logid, 4, CATMODULE "/", __FUNCTION__, y) +#define LOG_DEBUG2(y, z1, z2) log_write(_logid, 4, CATMODULE "/", __FUNCTION__, y, z1, z2) +#define LOG_DEBUG5(y, z1, z2, z3, z4, z5) log_write(_logid, 4, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5) +#endif + +/* thread starting structure */ +typedef struct thread_start_tag { + /* the real start routine and arg */ + void *(*start_routine)(void *); + void *arg; + + /* the other stuff we need to make sure this thread is inserted into + ** the thread tree + */ + thread_type *thread; + pthread_t sys_thread; +} thread_start_t; + +static long _next_thread_id = 0; +static int _initialized = 0; +static avl_tree *_threadtree = NULL; + +#ifdef DEBUG_MUTEXES +static mutex_t _threadtree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1, + PTHREAD_MUTEX_INITIALIZER}; +#else +static mutex_t _threadtree_mutex = { PTHREAD_MUTEX_INITIALIZER }; +#endif + + + +#ifdef DEBUG_MUTEXES +static int _logid = -1; +static long _next_mutex_id = 0; + +static avl_tree *_mutextree = NULL; +static mutex_t _mutextree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1, + PTHREAD_MUTEX_INITIALIZER}; +#endif + +#ifdef DEBUG_MUTEXES +static mutex_t _library_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1, + PTHREAD_MUTEX_INITIALIZER}; +#else +static mutex_t _library_mutex = { PTHREAD_MUTEX_INITIALIZER }; +#endif + +/* INTERNAL FUNCTIONS */ + +/* avl tree functions */ +#ifdef DEBUG_MUTEXES +static int _compare_mutexes(void *compare_arg, void *a, void *b); +static int _free_mutex(void *key); +#endif + +static int _compare_threads(void *compare_arg, void *a, void *b); +static int _free_thread(void *key); + +/* mutex fuctions */ +static void _mutex_create(mutex_t *mutex); +static void _mutex_lock(mutex_t *mutex); +static void _mutex_unlock(mutex_t *mutex); + +/* misc thread stuff */ +static void *_start_routine(void *arg); +static void _catch_signals(void); +static void _block_signals(void); + +/* LIBRARY INITIALIZATION */ + +void thread_initialize(void) +{ + thread_type *thread; + + /* set up logging */ + +#ifdef THREAD_DEBUG + log_initialize(); + _logid = log_open("thread.log"); + log_set_level(_logid, THREAD_DEBUG); +#endif + +#ifdef DEBUG_MUTEXES + /* create all the internal mutexes, and initialize the mutex tree */ + + _mutextree = avl_tree_new(_compare_mutexes, NULL); + + /* we have to create this one by hand, because there's no + ** mutextree_mutex to lock yet! + */ + _mutex_create(&_mutextree_mutex); + + _mutextree_mutex.mutex_id = _next_mutex_id++; + avl_insert(_mutextree, (void *)&_mutextree_mutex); +#endif + + thread_mutex_create(&_threadtree_mutex); + thread_mutex_create(&_library_mutex); + + /* initialize the thread tree and insert the main thread */ + + _threadtree = avl_tree_new(_compare_threads, NULL); + + thread = (thread_type *)malloc(sizeof(thread_type)); + + thread->thread_id = _next_thread_id++; + thread->line = 0; + thread->file = strdup("main.c"); + thread->sys_thread = pthread_self(); + thread->create_time = time(NULL); + thread->name = strdup("Main Thread"); + + avl_insert(_threadtree, (void *)thread); + + _catch_signals(); + + _initialized = 1; +} + +void thread_shutdown(void) +{ + if (_initialized == 1) { + thread_mutex_destroy(&_library_mutex); + thread_mutex_destroy(&_threadtree_mutex); +#ifdef THREAD_DEBUG + thread_mutex_destroy(&_mutextree_mutex); + + avl_tree_free(_mutextree, _free_mutex); +#endif + avl_tree_free(_threadtree, _free_thread); + _threadtree = NULL; + } + +#ifdef THREAD_DEBUG + log_close(_logid); + log_shutdown(); +#endif + +} + +/* + * Signals should be handled by the main thread, nowhere else. + * I'm using POSIX signal interface here, until someone tells me + * that I should use signal/sigset instead + * + * This function only valid for non-Win32 + */ +static void _block_signals(void) +{ +#ifndef _WIN32 + sigset_t ss; + + sigfillset(&ss); + + /* These ones we want */ + sigdelset(&ss, SIGKILL); + sigdelset(&ss, SIGSTOP); + sigdelset(&ss, SIGSEGV); + sigdelset(&ss, SIGCHLD); + sigdelset(&ss, SIGBUS); + if (pthread_sigmask(SIG_BLOCK, &ss, NULL) != 0) { +#ifdef THREAD_DEBUG + LOG_ERROR("Pthread_sigmask() failed for blocking signals"); +#endif + } +#endif +} + +/* + * Let the calling thread catch all the relevant signals + * + * This function only valid for non-Win32 + */ +static void _catch_signals(void) +{ +#ifndef _WIN32 + sigset_t ss; + + sigemptyset(&ss); + + /* These ones should only be accepted by the signal handling thread (main thread) */ + sigaddset(&ss, SIGHUP); + sigaddset(&ss, SIGCHLD); + sigaddset(&ss, SIGINT); + sigaddset(&ss, SIGPIPE); + sigaddset(&ss, SIGTERM); + + if (pthread_sigmask(SIG_UNBLOCK, &ss, NULL) != 0) { +#ifdef THREAD_DEBUG + LOG_ERROR("pthread_sigmask() failed for catching signals!"); +#endif + } +#endif +} + + +thread_type *thread_create_c(char *name, void *(*start_routine)(void *), + void *arg, int detached, int line, char *file) +{ + thread_type *thread = NULL; + thread_start_t *start = NULL; + pthread_attr_t attr; + + thread = (thread_type *)calloc(1, sizeof(thread_type)); + do { + if (thread == NULL) + break; + start = (thread_start_t *)calloc(1, sizeof(thread_start_t)); + if (start == NULL) + break; + if (pthread_attr_init (&attr) < 0) + break; + + thread->line = line; + thread->file = strdup(file); + + _mutex_lock (&_threadtree_mutex); + thread->thread_id = _next_thread_id++; + _mutex_unlock (&_threadtree_mutex); + + thread->name = strdup(name); + thread->create_time = time(NULL); + + start->start_routine = start_routine; + start->arg = arg; + start->thread = thread; + + pthread_attr_setstacksize (&attr, 512*1024); + pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED); + if (detached) + { + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + thread->detached = 1; + } + + if (pthread_create (&thread->sys_thread, &attr, _start_routine, start) == 0) + { + pthread_attr_destroy (&attr); + return thread; + } + else + pthread_attr_destroy (&attr); + } + while (0); + +#ifdef THREAD_DEBUG + LOG_ERROR("Could not create new thread %s", name); +#endif + if (start) free (start); + if (thread) free (thread); + return NULL; +} + +/* _mutex_create +** +** creates a mutex +*/ +static void _mutex_create(mutex_t *mutex) +{ +#ifdef DEBUG_MUTEXES + mutex->thread_id = MUTEX_STATE_NEVERLOCKED; + mutex->line = -1; +#endif + + pthread_mutex_init(&mutex->sys_mutex, NULL); +} + +void thread_mutex_create_c(mutex_t *mutex, int line, char *file) +{ + _mutex_create(mutex); + +#ifdef DEBUG_MUTEXES + _mutex_lock(&_mutextree_mutex); + mutex->mutex_id = _next_mutex_id++; + avl_insert(_mutextree, (void *)mutex); + _mutex_unlock(&_mutextree_mutex); +#endif +} + +void thread_mutex_destroy (mutex_t *mutex) +{ + pthread_mutex_destroy(&mutex->sys_mutex); + +#ifdef DEBUG_MUTEXES + _mutex_lock(&_mutextree_mutex); + avl_delete(_mutextree, mutex, _free_mutex); + _mutex_unlock(&_mutextree_mutex); +#endif +} + +void thread_mutex_lock_c(mutex_t *mutex, int line, char *file) +{ +#ifdef DEBUG_MUTEXES + thread_type *th = thread_self(); + + if (!th) LOG_WARN("No mt record for %u in lock [%s:%d]", thread_self(), file, line); + + LOG_DEBUG5("Locking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1); + +# ifdef CHECK_MUTEXES + /* Just a little sanity checking to make sure that we're locking + ** mutexes correctly + */ + + if (th) { + int locks = 0; + avl_node *node; + mutex_t *tmutex; + + _mutex_lock(&_mutextree_mutex); + + node = avl_get_first (_mutextree); + + while (node) { + tmutex = (mutex_t *)node->key; + + if (tmutex->mutex_id == mutex->mutex_id) { + if (tmutex->thread_id == th->thread_id) { + /* Deadlock, same thread can't lock the same mutex twice */ + LOG_ERROR7("DEADLOCK AVOIDED (%d == %d) on mutex [%s] in file %s line %d by thread %d [%s]", + tmutex->thread_id, th->thread_id, mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name); + + _mutex_unlock(&_mutextree_mutex); + return; + } + } else if (tmutex->thread_id == th->thread_id) { + /* Mutex locked by this thread (not this mutex) */ + locks++; + } + + node = avl_get_next(node); + } + + if (locks > 0) { + /* Has already got a mutex locked */ + if (_multi_mutex.thread_id != th->thread_id) { + /* Tries to lock two mutexes, but has not got the double mutex, norty boy! */ + LOG_WARN("(%d != %d) Thread %d [%s] tries to lock a second mutex [%s] in file %s line %d, without locking double mutex!", + _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line); + } + } + + _mutex_unlock(&_mutextree_mutex); + } +# endif /* CHECK_MUTEXES */ + + _mutex_lock(mutex); + + _mutex_lock(&_mutextree_mutex); + + LOG_DEBUG2("Locked %p by thread %d", mutex, th ? th->thread_id : -1); + mutex->line = line; + if (th) { + mutex->thread_id = th->thread_id; + } + + _mutex_unlock(&_mutextree_mutex); +#else + _mutex_lock(mutex); +#endif /* DEBUG_MUTEXES */ +} + +void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file) +{ +#ifdef DEBUG_MUTEXES + thread_type *th = thread_self(); + + if (!th) { + LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line); + } + + LOG_DEBUG5("Unlocking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1); + + mutex->line = line; + +# ifdef CHECK_MUTEXES + if (th) { + int locks = 0; + avl_node *node; + mutex_t *tmutex; + + _mutex_lock(&_mutextree_mutex); + + while (node) { + tmutex = (mutex_t *)node->key; + + if (tmutex->mutex_id == mutex->mutex_id) { + if (tmutex->thread_id != th->thread_id) { + LOG_ERROR7("ILLEGAL UNLOCK (%d != %d) on mutex [%s] in file %s line %d by thread %d [%s]", tmutex->thread_id, th->thread_id, + mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name); + _mutex_unlock(&_mutextree_mutex); + return; + } + } else if (tmutex->thread_id == th->thread_id) { + locks++; + } + + node = avl_get_next (node); + } + + if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) { + /* Don't have double mutex, has more than this mutex left */ + + LOG_WARN("(%d != %d) Thread %d [%s] tries to unlock a mutex [%s] in file %s line %d, without owning double mutex!", + _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line); + } + + _mutex_unlock(&_mutextree_mutex); + } +# endif /* CHECK_MUTEXES */ + + _mutex_unlock(mutex); + + _mutex_lock(&_mutextree_mutex); + + LOG_DEBUG2("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1); + mutex->line = -1; + if (mutex->thread_id == th->thread_id) { + mutex->thread_id = MUTEX_STATE_NOTLOCKED; + } + + _mutex_unlock(&_mutextree_mutex); +#else + _mutex_unlock(mutex); +#endif /* DEBUG_MUTEXES */ +} + +void thread_cond_create_c(cond_t *cond, int line, char *file) +{ + pthread_cond_init(&cond->sys_cond, NULL); + pthread_mutex_init(&cond->cond_mutex, NULL); +} + +void thread_cond_destroy(cond_t *cond) +{ + pthread_mutex_destroy(&cond->cond_mutex); + pthread_cond_destroy(&cond->sys_cond); +} + +void thread_cond_signal_c(cond_t *cond, int line, char *file) +{ + pthread_cond_signal(&cond->sys_cond); +} + +void thread_cond_broadcast_c(cond_t *cond, int line, char *file) +{ + pthread_cond_broadcast(&cond->sys_cond); +} + +void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file) +{ + struct timespec time; + + time.tv_sec = millis/1000; + time.tv_nsec = (millis - time.tv_sec*1000)*1000000; + + pthread_mutex_lock(&cond->cond_mutex); + pthread_cond_timedwait(&cond->sys_cond, &cond->cond_mutex, &time); + pthread_mutex_unlock(&cond->cond_mutex); +} + +void thread_cond_wait_c(cond_t *cond, int line, char *file) +{ + pthread_mutex_lock(&cond->cond_mutex); + pthread_cond_wait(&cond->sys_cond, &cond->cond_mutex); + pthread_mutex_unlock(&cond->cond_mutex); +} + +void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file) +{ + pthread_rwlock_init(&rwlock->sys_rwlock, NULL); +} + +void thread_rwlock_destroy(rwlock_t *rwlock) +{ + pthread_rwlock_destroy(&rwlock->sys_rwlock); +} + +void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, char *file) +{ + pthread_rwlock_rdlock(&rwlock->sys_rwlock); +} + +void thread_rwlock_wlock_c(rwlock_t *rwlock, int line, char *file) +{ + pthread_rwlock_wrlock(&rwlock->sys_rwlock); +} + +void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file) +{ + pthread_rwlock_unlock(&rwlock->sys_rwlock); +} + +void thread_exit_c(long val, int line, char *file) +{ + thread_type *th = thread_self(); + +#if defined(DEBUG_MUTEXES) && defined(CHECK_MUTEXES) + if (th) { + avl_node *node; + mutex_t *tmutex; + char name[40]; + + _mutex_lock(&_mutextree_mutex); + + while (node) { + tmutex = (mutex_t *)node->key; + + if (tmutex->thread_id == th->thread_id) { + LOG_WARN("Thread %d [%s] exiting in file %s line %d, without unlocking mutex [%s]", + th->thread_id, th->name, file, line, mutex_to_string(tmutex, name)); + } + + node = avl_get_next (node); + } + + _mutex_unlock(&_mutextree_mutex); + } +#endif + + if (th && th->detached) + { +#ifdef THREAD_DEBUG + LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line); +#endif + + _mutex_lock(&_threadtree_mutex); + avl_delete(_threadtree, th, _free_thread); + _mutex_unlock(&_threadtree_mutex); + } + + pthread_exit ((void*)val); +} + +/* sleep for a number of microseconds */ +void thread_sleep(unsigned long len) +{ +#ifdef _WIN32 + Sleep(len / 1000); +#else +# ifdef HAVE_NANOSLEEP + struct timespec time_sleep; + struct timespec time_remaining; + int ret; + + time_sleep.tv_sec = len / 1000000; + time_sleep.tv_nsec = (len % 1000000) * 1000; + + ret = nanosleep(&time_sleep, &time_remaining); + while (ret != 0 && errno == EINTR) { + time_sleep.tv_sec = time_remaining.tv_sec; + time_sleep.tv_nsec = time_remaining.tv_nsec; + + ret = nanosleep(&time_sleep, &time_remaining); + } +# else + struct timeval tv; + + tv.tv_sec = len / 1000000; + tv.tv_usec = (len % 1000000); + + select(0, NULL, NULL, NULL, &tv); +# endif +#endif +} + +static void *_start_routine(void *arg) +{ + thread_start_t *start = (thread_start_t *)arg; + void *(*start_routine)(void *) = start->start_routine; + void *real_arg = start->arg; + thread_type *thread = start->thread; + + _block_signals(); + + /* insert thread into thread tree here */ + _mutex_lock(&_threadtree_mutex); + thread->sys_thread = pthread_self(); + avl_insert(_threadtree, (void *)thread); + _mutex_unlock(&_threadtree_mutex); + +#ifdef THREAD_DEBUG + LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line); +#endif + + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + free (start); + + (start_routine)(real_arg); + + if (thread->detached) + { + _mutex_lock (&_threadtree_mutex); + avl_delete (_threadtree, thread, _free_thread); + _mutex_unlock (&_threadtree_mutex); + } + + return NULL; +} + +thread_type *thread_self(void) +{ + avl_node *node; + thread_type *th; + pthread_t sys_thread = pthread_self(); + + _mutex_lock(&_threadtree_mutex); + + if (_threadtree == NULL) { +#ifdef THREAD_DEBUG + LOG_WARN("Thread tree is empty, this must be wrong!"); +#endif + _mutex_unlock(&_threadtree_mutex); + return NULL; + } + + node = avl_get_first(_threadtree); + + while (node) { + th = (thread_type *)node->key; + + if (th && pthread_equal(sys_thread, th->sys_thread)) { + _mutex_unlock(&_threadtree_mutex); + return th; + } + + node = avl_get_next(node); + } + _mutex_unlock(&_threadtree_mutex); + + +#ifdef THREAD_DEBUG + LOG_ERROR("Nonexistant thread alive..."); +#endif + + return NULL; +} + +void thread_rename(const char *name) +{ + thread_type *th; + + th = thread_self(); + if (th->name) free(th->name); + + th->name = strdup(name); +} + +static void _mutex_lock(mutex_t *mutex) +{ + pthread_mutex_lock(&mutex->sys_mutex); +} + +static void _mutex_unlock(mutex_t *mutex) +{ + pthread_mutex_unlock(&mutex->sys_mutex); +} + + +void thread_library_lock(void) +{ + _mutex_lock(&_library_mutex); +} + +void thread_library_unlock(void) +{ + _mutex_unlock(&_library_mutex); +} + +void thread_join(thread_type *thread) +{ + void *ret; + int i; + + i = pthread_join(thread->sys_thread, &ret); + _mutex_lock(&_threadtree_mutex); + avl_delete(_threadtree, thread, _free_thread); + _mutex_unlock(&_threadtree_mutex); +} + +/* AVL tree functions */ + +#ifdef DEBUG_MUTEXES +static int _compare_mutexes(void *compare_arg, void *a, void *b) +{ + mutex_t *m1, *m2; + + m1 = (mutex_t *)a; + m2 = (mutex_t *)b; + + if (m1->mutex_id > m2->mutex_id) + return 1; + if (m1->mutex_id < m2->mutex_id) + return -1; + return 0; +} +#endif + +static int _compare_threads(void *compare_arg, void *a, void *b) +{ + thread_type *t1, *t2; + + t1 = (thread_type *)a; + t2 = (thread_type *)b; + + if (t1->thread_id > t2->thread_id) + return 1; + if (t1->thread_id < t2->thread_id) + return -1; + return 0; +} + +#ifdef DEBUG_MUTEXES +static int _free_mutex(void *key) +{ + mutex_t *m; + + m = (mutex_t *)key; + + if (m && m->file) { + free(m->file); + m->file = NULL; + } + + /* all mutexes are static. don't need to free them */ + + return 1; +} +#endif + +static int _free_thread(void *key) +{ + thread_type *t; + + t = (thread_type *)key; + + if (t->file) + free(t->file); + if (t->name) + free(t->name); + + free(t); + + return 1; +} + + +#ifdef HAVE_PTHREAD_SPIN_LOCK +void thread_spin_create (spin_t *spin) +{ + int x = pthread_spin_init (&spin->lock, PTHREAD_PROCESS_PRIVATE); + if (x) + abort(); +} + +void thread_spin_destroy (spin_t *spin) +{ + pthread_spin_destroy (&spin->lock); +} + +void thread_spin_lock (spin_t *spin) +{ + int x = pthread_spin_lock (&spin->lock); + if (x != 0) + abort(); +} + +void thread_spin_unlock (spin_t *spin) +{ + pthread_spin_unlock (&spin->lock); +} +#endif + diff --git a/lib/libshout/src/common/thread/thread.h b/lib/libshout/src/common/thread/thread.h new file mode 100644 index 00000000000..d2c3be3317e --- /dev/null +++ b/lib/libshout/src/common/thread/thread.h @@ -0,0 +1,207 @@ +/* thread.h + * - Thread Abstraction Function Headers + * + * Copyright (C) 2014 Michael Smith , + * Brendan Cully , + * Karl Heyes , + * Jack Moffitt + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef __THREAD_H__ +#define __THREAD_H__ + +#include + +/* renamed from thread_t due to conflict on OS X */ + +typedef struct { + /* the local id for the thread, and it's name */ + long thread_id; + char *name; + + /* the time the thread was created */ + time_t create_time; + + /* the file and line which created this thread */ + char *file; + int line; + + /* is the thread running detached? */ + int detached; + + /* the system specific thread */ + pthread_t sys_thread; +} thread_type; + +typedef struct { +#ifdef DEBUG_MUTEXES + /* the local id and name of the mutex */ + long mutex_id; + char *name; + + /* the thread which is currently locking this mutex */ + long thread_id; + + /* the file and line where the mutex was locked */ + char *file; + int line; + +#endif + + /* the system specific mutex */ + pthread_mutex_t sys_mutex; +} mutex_t; + +typedef struct { +#ifdef THREAD_DEBUG + long cond_id; + char *name; +#endif + + pthread_mutex_t cond_mutex; + pthread_cond_t sys_cond; +} cond_t; + +typedef struct { +#ifdef THREAD_DEBUG + long rwlock_id; + char *name; + + /* information on which thread and where in the code + ** this rwlock was write locked + */ + long thread_id; + char *file; + int line; +#endif + + pthread_rwlock_t sys_rwlock; +} rwlock_t; + +#ifdef HAVE_PTHREAD_SPIN_LOCK +typedef struct +{ + pthread_spinlock_t lock; +} spin_t; + +void thread_spin_create (spin_t *spin); +void thread_spin_destroy (spin_t *spin); +void thread_spin_lock (spin_t *spin); +void thread_spin_unlock (spin_t *spin); +#else +typedef mutex_t spin_t; +#define thread_spin_create(x) thread_mutex_create(x) +#define thread_spin_destroy(x) thread_mutex_destroy(x) +#define thread_spin_lock(x) thread_mutex_lock(x) +#define thread_spin_unlock(x) thread_mutex_unlock(x) +#endif + +#define thread_create(n,x,y,z) thread_create_c(n,x,y,z,__LINE__,__FILE__) +#define thread_mutex_create(x) thread_mutex_create_c(x,__LINE__,__FILE__) +#define thread_mutex_lock(x) thread_mutex_lock_c(x,__LINE__,__FILE__) +#define thread_mutex_unlock(x) thread_mutex_unlock_c(x,__LINE__,__FILE__) +#define thread_cond_create(x) thread_cond_create_c(x,__LINE__,__FILE__) +#define thread_cond_signal(x) thread_cond_signal_c(x,__LINE__,__FILE__) +#define thread_cond_broadcast(x) thread_cond_broadcast_c(x,__LINE__,__FILE__) +#define thread_cond_wait(x) thread_cond_wait_c(x,__LINE__,__FILE__) +#define thread_cond_timedwait(x,t) thread_cond_wait_c(x,t,__LINE__,__FILE__) +#define thread_rwlock_create(x) thread_rwlock_create_c(x,__LINE__,__FILE__) +#define thread_rwlock_rlock(x) thread_rwlock_rlock_c(x,__LINE__,__FILE__) +#define thread_rwlock_wlock(x) thread_rwlock_wlock_c(x,__LINE__,__FILE__) +#define thread_rwlock_unlock(x) thread_rwlock_unlock_c(x,__LINE__,__FILE__) +#define thread_exit(x) thread_exit_c(x,__LINE__,__FILE__) + +#define MUTEX_STATE_NOTLOCKED -1 +#define MUTEX_STATE_NEVERLOCKED -2 +#define MUTEX_STATE_UNINIT -3 +#define THREAD_DETACHED 1 +#define THREAD_ATTACHED 0 + +#ifdef _mangle +# define thread_initialize _mangle(thread_initialize) +# define thread_initialize_with_log_id _mangle(thread_initialize_with_log_id) +# define thread_shutdown _mangle(thread_shutdown) +# define thread_create_c _mangle(thread_create_c) +# define thread_mutex_create_c _mangle(thread_mutex_create) +# define thread_mutex_lock_c _mangle(thread_mutex_lock_c) +# define thread_mutex_unlock_c _mangle(thread_mutex_unlock_c) +# define thread_mutex_destroy _mangle(thread_mutex_destroy) +# define thread_cond_create_c _mangle(thread_cond_create_c) +# define thread_cond_signal_c _mangle(thread_cond_signal_c) +# define thread_cond_broadcast_c _mangle(thread_cond_broadcast_c) +# define thread_cond_wait_c _mangle(thread_cond_wait_c) +# define thread_cond_timedwait_c _mangle(thread_cond_timedwait_c) +# define thread_cond_destroy _mangle(thread_cond_destroy) +# define thread_rwlock_create_c _mangle(thread_rwlock_create_c) +# define thread_rwlock_rlock_c _mangle(thread_rwlock_rlock_c) +# define thread_rwlock_wlock_c _mangle(thread_rwlock_wlock_c) +# define thread_rwlock_unlock_c _mangle(thread_rwlock_unlock_c) +# define thread_rwlock_destroy _mangle(thread_rwlock_destroy) +# define thread_exit_c _mangle(thread_exit_c) +# define thread_sleep _mangle(thread_sleep) +# define thread_library_lock _mangle(thread_library_lock) +# define thread_library_unlock _mangle(thread_library_unlock) +# define thread_self _mangle(thread_self) +# define thread_rename _mangle(thread_rename) +# define thread_join _mangle(thread_join) +#endif + +/* init/shutdown of the library */ +void thread_initialize(void); +void thread_initialize_with_log_id(int log_id); +void thread_shutdown(void); + +/* creation, destruction, locking, unlocking, signalling and waiting */ +thread_type *thread_create_c(char *name, void *(*start_routine)(void *), + void *arg, int detached, int line, char *file); +void thread_mutex_create_c(mutex_t *mutex, int line, char *file); +void thread_mutex_lock_c(mutex_t *mutex, int line, char *file); +void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file); +void thread_mutex_destroy(mutex_t *mutex); +void thread_cond_create_c(cond_t *cond, int line, char *file); +void thread_cond_signal_c(cond_t *cond, int line, char *file); +void thread_cond_broadcast_c(cond_t *cond, int line, char *file); +void thread_cond_wait_c(cond_t *cond, int line, char *file); +void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file); +void thread_cond_destroy(cond_t *cond); +void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file); +void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, char *file); +void thread_rwlock_wlock_c(rwlock_t *rwlock, int line, char *file); +void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file); +void thread_rwlock_destroy(rwlock_t *rwlock); +void thread_exit_c(long val, int line, char *file); + +/* sleeping */ +void thread_sleep(unsigned long len); + +/* for using library functions which aren't threadsafe */ +void thread_library_lock(void); +void thread_library_unlock(void); +#define PROTECT_CODE(code) { thread_library_lock(); code; thread_library_unlock(); } + +/* thread information functions */ +thread_type *thread_self(void); + +/* renames current thread */ +void thread_rename(const char *name); + +/* waits until thread_exit is called for another thread */ +void thread_join(thread_type *thread); + +#endif /* __THREAD_H__ */ diff --git a/lib/libshout/src/common/timing/BUILDING b/lib/libshout/src/common/timing/BUILDING new file mode 100644 index 00000000000..0aa7006f570 --- /dev/null +++ b/lib/libshout/src/common/timing/BUILDING @@ -0,0 +1,7 @@ +defines that affect compilation + +none + +library dependencies + +none diff --git a/lib/libshout/src/common/timing/COPYING b/lib/libshout/src/common/timing/COPYING new file mode 100644 index 00000000000..92b8903ff3f --- /dev/null +++ b/lib/libshout/src/common/timing/COPYING @@ -0,0 +1,481 @@ + 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 + + 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 + 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! diff --git a/lib/libshout/src/common/timing/Makefile.am b/lib/libshout/src/common/timing/Makefile.am new file mode 100644 index 00000000000..493112e0a63 --- /dev/null +++ b/lib/libshout/src/common/timing/Makefile.am @@ -0,0 +1,18 @@ +## Process this with automake to create Makefile.in + +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = BUILDING COPYING README TODO + +noinst_LTLIBRARIES = libicetiming.la +noinst_HEADERS = timing.h + +libicetiming_la_SOURCES = timing.c +libicetiming_la_CFLAGS = @XIPH_CFLAGS@ + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" + diff --git a/lib/libshout/src/common/timing/README b/lib/libshout/src/common/timing/README new file mode 100644 index 00000000000..b43ead9d0ae --- /dev/null +++ b/lib/libshout/src/common/timing/README @@ -0,0 +1,5 @@ +this is the timing library. + +lgpl + +by jack moffitt diff --git a/lib/libshout/src/common/timing/TODO b/lib/libshout/src/common/timing/TODO new file mode 100644 index 00000000000..585db8988c2 --- /dev/null +++ b/lib/libshout/src/common/timing/TODO @@ -0,0 +1,2 @@ + +nothing diff --git a/lib/libshout/src/common/timing/timing.c b/lib/libshout/src/common/timing/timing.c new file mode 100644 index 00000000000..9be67d565a6 --- /dev/null +++ b/lib/libshout/src/common/timing/timing.c @@ -0,0 +1,104 @@ +/* timing.c + * - Timing functions + * + * Copyright (C) 2014 Michael Smith , + * Brendan Cully , + * Karl Heyes , + * Jack Moffitt , + * Ed "oddsock" Zaleski , + * Ralph Giles + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#ifdef _WIN32 +#include +#include +#else +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifdef HAVE_SYS_TIMEB_H +#include +#endif + +#include "timing.h" + +/* see timing.h for an explanation of _mangle() */ + +/* + * Returns milliseconds no matter what. + */ +uint64_t timing_get_time(void) +{ +#ifdef HAVE_GETTIMEOFDAY + struct timeval mtv; + + gettimeofday(&mtv, NULL); + + return (uint64_t)(mtv.tv_sec) * 1000 + (uint64_t)(mtv.tv_usec) / 1000; +#elif HAVE_FTIME + struct timeb t; + + ftime(&t); + return t.time * 1000 + t.millitm; +#else +#error need time query handler +#endif +} + + +void timing_sleep(uint64_t sleeptime) +{ + struct timeval sleeper; + + sleeper.tv_sec = sleeptime / 1000; + sleeper.tv_usec = (sleeptime % 1000) * 1000; + + /* NOTE: + * This should be 0 for the first argument. The linux manpage + * says so. The solaris manpage also says this is a legal + * value. If you think differerntly, please provide references. + */ +#ifdef WIN32 + Sleep(sleeptime); +#else + select(1, NULL, NULL, NULL, &sleeper); +#endif +} diff --git a/lib/libshout/src/common/timing/timing.h b/lib/libshout/src/common/timing/timing.h new file mode 100644 index 00000000000..4ef88a0bb8a --- /dev/null +++ b/lib/libshout/src/common/timing/timing.h @@ -0,0 +1,51 @@ +/* + * Timing functions. + * + * Copyright (C) 2014 Michael Smith , + * Karl Heyes , + * Jack Moffitt , + * Moritz Grimm , + * Ralph Giles + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef __TIMING_H__ +#define __TIMING_H__ + +#include +#ifdef HAVE_INTTYPES_H +#include +#elif defined(HAVE_STDINT_H) +#include +#endif + +#if defined(_WIN32) && !defined(int64_t) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#endif + +/* config.h should be included before we are to define _mangle */ +#ifdef _mangle +# define timing_get_time _mangle(timing_get_time) +# define timing_sleep _mangle(timing_sleep) +#endif + +uint64_t timing_get_time(void); +void timing_sleep(uint64_t sleeptime); + +#endif /* __TIMING_H__ */ diff --git a/lib/libshout/src/format_mp3.c b/lib/libshout/src/format_mp3.c new file mode 100644 index 00000000000..da1d176ff50 --- /dev/null +++ b/lib/libshout/src/format_mp3.c @@ -0,0 +1,319 @@ +/* -*- c-basic-offset: 8; -*- */ +/* mp3.c: libshout MP3 format handler + * $Id$ + * + * Copyright (C) 2002-2003 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include +#include "shout_private.h" + +/* + * MP3 frame handling courtesy of Scott Manley - may he always be Manley. + */ + +#define MPEG_MODE_MONO 3 + +/* -- local datatypes -- */ +typedef struct { + unsigned int frames; + /* the number of samples for the current frame */ + int frame_samples; + /* the samplerate of the current frame */ + int frame_samplerate; + /* how many bytes for the rest of this frame */ + unsigned int frame_left; + /* is the header bridged?? */ + int header_bridges; + /* put part of header here if it spans a boundary */ + unsigned char header_bridge[3]; +} mp3_data_t; + +typedef struct { + int syncword; + int layer; + int version; + int error_protection; + int bitrate_index; + int samplerate_index; + int padding; + int extension; + int mode; + int mode_ext; + int copyright; + int original; + int emphasis; + int stereo; + int bitrate; + unsigned int samplerate; + unsigned int samples; + unsigned int framesize; +} mp3_header_t; + +/* -- const data -- */ +static const unsigned int bitrate[3][3][16] = +{ + { + { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, + { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 } + }, { + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 } + }, { + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 } + } +}; + +static const unsigned int samplerate[3][4] = +{ + { 44100, 48000, 32000, 0 }, + { 22050, 24000, 16000, 0 }, + { 11025, 8000, 8000, 0 } +}; + +/* -- static prototypes -- */ +static int send_mp3(shout_t *self, const unsigned char *data, size_t len); +static void close_mp3(shout_t *self); + +static void parse_header(mp3_header_t *mh, uint32_t header); +static int mp3_header(uint32_t head, mp3_header_t *mh); + +int shout_open_mp3(shout_t *self) +{ + mp3_data_t *mp3_data; + + if (!(mp3_data = (mp3_data_t *)calloc(1, sizeof(mp3_data_t)))) + return SHOUTERR_MALLOC; + self->format_data = mp3_data; + + self->send = send_mp3; + self->close = close_mp3; + + return SHOUTERR_SUCCESS; +} + +static int send_mp3(shout_t* self, const unsigned char* buff, size_t len) +{ + mp3_data_t* mp3_data = (mp3_data_t*) self->format_data; + unsigned long pos; + uint32_t head; + int ret, count; + int start, end, error, i; + unsigned char *bridge_buff; + mp3_header_t mh; + + bridge_buff = NULL; + pos = 0; + start = 0; + error = 0; + end = len - 1; + memset(&mh, 0, sizeof(mh)); + + /* finish the previous frame */ + if (mp3_data->frame_left > 0) { + /* is the rest of the frame here? */ + if (mp3_data->frame_left <= len) { + self->senttime += (int64_t)((double)mp3_data->frame_samples / (double)mp3_data->frame_samplerate * 1000000); + mp3_data->frames++; + pos += mp3_data->frame_left; + mp3_data->frame_left = 0; + } else { + mp3_data->frame_left -= len; + pos = len; + } + } + + /* header was over the boundary, so build a new build a new buffer */ + if (mp3_data->header_bridges) { + bridge_buff = (unsigned char *)malloc(len + mp3_data->header_bridges); + if (bridge_buff == NULL) { + return self->error = SHOUTERR_MALLOC; + } + + bridge_buff[0] = mp3_data->header_bridge[0]; + bridge_buff[1] = mp3_data->header_bridge[1]; + bridge_buff[2] = mp3_data->header_bridge[2]; + + memcpy(&bridge_buff[mp3_data->header_bridges], buff, len); + + buff = bridge_buff; + len += mp3_data->header_bridges; + end = len - 1; + + mp3_data->header_bridges = 0; + } + + /** this is the main loop + *** we handle everything but the last 4 bytes... + **/ + while ((pos + 4) <= len) { + /* find mp3 header */ + head = (buff[pos] << 24) | + (buff[pos + 1] << 16) | + (buff[pos + 2] << 8) | + (buff[pos + 3]); + + /* is this a valid header? */ + if (mp3_header(head, &mh)) { + if (error) { + start = pos; + end = len - 1; + error = 0; + } + + mp3_data->frame_samples = mh.samples; + mp3_data->frame_samplerate = mh.samplerate; + + /* do we have a complete frame in this buffer? */ + if (len - pos >= mh.framesize) { + self->senttime += (int64_t)((double)mp3_data->frame_samples / (double)mp3_data->frame_samplerate * 1000000); + mp3_data->frames++; + pos += mh.framesize; + } else { + mp3_data->frame_left = mh.framesize - (len - pos); + pos = len; + } + } else { + /* there was an error + ** so we send all the valid data up to this point + */ + if (!error) { + error = 1; + end = pos - 1; + count = end - start + 1; + if (count > 0) + ret = shout_send_raw(self, &buff[start], count); + else + ret = 0; + + if (ret != count) { + if (bridge_buff != NULL) + free(bridge_buff); + return self->error = SHOUTERR_SOCKET; + } + } + pos++; + } + } + + /* catch the tail if there is one */ + if ((pos > (len - 4)) && (pos < len)) { + end = pos - 1; + + i = 0; + while (pos < len) { + mp3_data->header_bridge[i] = buff[pos]; + pos++; + i++; + } + mp3_data->header_bridges = i; + } + + if (!error) { + /* if there's no errors, lets send the frames */ + count = end - start + 1; + if (count > 0) + ret = shout_send_raw(self, &buff[start], count); + else + ret = 0; + + if (bridge_buff != NULL) + free(bridge_buff); + + if (ret == count) { + return self->error = SHOUTERR_SUCCESS; + } else { + return self->error = SHOUTERR_SOCKET; + } + } + + if (bridge_buff != NULL) + free(bridge_buff); + + return self->error = SHOUTERR_SUCCESS; +} + +static void parse_header(mp3_header_t *mh, uint32_t header) +{ + mh->syncword = (header >> 20) & 0x0fff; + mh->version = ((header >> 19) & 0x01) ? 0 : 1; + if ((mh->syncword & 0x01) == 0) + mh->version = 2; + mh->layer = 3 - ((header >> 17) & 0x03); + mh->error_protection = ((header >> 16) & 0x01) ? 0 : 1; + mh->bitrate_index = (header >> 12) & 0x0F; + mh->samplerate_index = (header >> 10) & 0x03; + mh->padding = (header >> 9) & 0x01; + mh->extension = (header >> 8) & 0x01; + mh->mode = (header >> 6) & 0x03; + mh->mode_ext = (header >> 4) & 0x03; + mh->copyright = (header >> 3) & 0x01; + mh->original = (header >> 2) & 0x01; + mh->emphasis = header & 0x03; + + mh->stereo = (mh->mode == MPEG_MODE_MONO) ? 1 : 2; + mh->bitrate = bitrate[mh->version][mh->layer][mh->bitrate_index]; + mh->samplerate = samplerate[mh->version][mh->samplerate_index]; + + if (mh->version == 0) + mh->samples = 1152; + else + mh->samples = 576; + + if(mh->samplerate) + mh->framesize = (mh->samples * mh->bitrate * 1000 / mh->samplerate) / 8 + mh->padding; +} + +/* mp3 frame parsing stuff */ +static int mp3_header(uint32_t head, mp3_header_t *mh) +{ + /* fill out the header struct */ + parse_header(mh, head); + + /* check for syncword */ + if ((mh->syncword & 0x0ffe) != 0x0ffe) + return 0; + + /* check that layer is valid */ + if (mh->layer == 0) + return 0; + + /* make sure bitrate is sane */ + if (mh->bitrate == 0) + return 0; + + /* make sure samplerate is sane */ + if (mh->samplerate == 0) + return 0; + + return 1; +} + +static void close_mp3(shout_t *self) +{ + mp3_data_t *mp3_data = (mp3_data_t *)self->format_data; + + free(mp3_data); +} diff --git a/lib/libshout/src/format_ogg.c b/lib/libshout/src/format_ogg.c new file mode 100644 index 00000000000..99751d7db37 --- /dev/null +++ b/lib/libshout/src/format_ogg.c @@ -0,0 +1,205 @@ +/* -*- c-basic-offset: 8; -*- */ +/* ogg.c: Generic ogg data handler + * $Id$ + * + * Copyright (C) 2002-2004 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#ifdef HAVE_INTTYPES_H +#include +#endif + +#include + +#include +#include "shout_private.h" +#include "format_ogg.h" + +/* -- local datatypes -- */ +typedef struct { + ogg_sync_state oy; + ogg_codec_t *codecs; + char bos; +} ogg_data_t; + +/* -- static prototypes -- */ +static int send_ogg(shout_t *self, const unsigned char *data, size_t len); +static void close_ogg(shout_t *self); +static int open_codec(ogg_codec_t *codec, ogg_page *page); +static void free_codec(ogg_codec_t *codec); +static void free_codecs(ogg_data_t *ogg_data); +static int send_page(shout_t *self, ogg_page *page); + +typedef int (*codec_open_t)(ogg_codec_t *codec, ogg_page *page); +static codec_open_t codecs[] = { + _shout_open_vorbis, +#ifdef HAVE_THEORA + _shout_open_theora, +#endif + _shout_open_opus, +#ifdef HAVE_SPEEX + _shout_open_speex, +#endif + NULL +}; + +int shout_open_ogg(shout_t *self) +{ + ogg_data_t *ogg_data; + + if (!(ogg_data = (ogg_data_t *)calloc(1, sizeof(ogg_data_t)))) + return self->error = SHOUTERR_MALLOC; + self->format_data = ogg_data; + + ogg_sync_init(&ogg_data->oy); + ogg_data->bos = 1; + + self->send = send_ogg; + self->close = close_ogg; + + return SHOUTERR_SUCCESS; +} + +static int send_ogg(shout_t *self, const unsigned char *data, size_t len) +{ + ogg_data_t *ogg_data = (ogg_data_t *)self->format_data; + ogg_codec_t *codec; + char *buffer; + ogg_page page; + + buffer = ogg_sync_buffer(&ogg_data->oy, len); + memcpy(buffer, data, len); + ogg_sync_wrote(&ogg_data->oy, len); + + while (ogg_sync_pageout(&ogg_data->oy, &page) == 1) { + if (ogg_page_bos (&page)) { + if (! ogg_data->bos) { + free_codecs(ogg_data); + ogg_data->bos = 1; + } + + codec = calloc(1, sizeof(ogg_codec_t)); + if (! codec) + return self->error = SHOUTERR_MALLOC; + + if ((self->error = open_codec(codec, &page)) != SHOUTERR_SUCCESS) + return self->error; + + codec->headers = 1; + codec->senttime = self->senttime; + codec->next = ogg_data->codecs; + ogg_data->codecs = codec; + } else { + ogg_data->bos = 0; + + codec = ogg_data->codecs; + while (codec) { + if (ogg_page_serialno(&page) == codec->os.serialno) { + if (codec->read_page) { + ogg_stream_pagein(&codec->os, &page); + codec->read_page(codec, &page); + + if (self->senttime < codec->senttime) + self->senttime = codec->senttime; + } + + break; + } + + codec = codec->next; + } + } + + if ((self->error = send_page(self, &page)) != SHOUTERR_SUCCESS) + return self->error; + } + + return self->error = SHOUTERR_SUCCESS; +} + +static void close_ogg(shout_t *self) +{ + ogg_data_t *ogg_data = (ogg_data_t *)self->format_data; + free_codecs(ogg_data); + ogg_sync_clear(&ogg_data->oy); + free(ogg_data); +} + +static int open_codec(ogg_codec_t *codec, ogg_page *page) +{ + codec_open_t this_codec; + int i = 0; + + while ((this_codec = codecs[i])) { + ogg_stream_init(&codec->os, ogg_page_serialno(page)); + ogg_stream_pagein(&codec->os, page); + + if (this_codec(codec, page) == SHOUTERR_SUCCESS) + return SHOUTERR_SUCCESS; + + ogg_stream_clear(&codec->os); + i++; + } + + /* if no handler is found, we currently just fall back to untimed send_raw */ + return SHOUTERR_SUCCESS; +} + +static void free_codecs(ogg_data_t *ogg_data) +{ + ogg_codec_t *codec, *next; + + if (ogg_data == NULL) + return; + + codec = ogg_data->codecs; + while (codec) { + next = codec->next; + free_codec(codec); + codec = next; + } + ogg_data->codecs = NULL; +} + +static void free_codec(ogg_codec_t *codec) +{ + if (codec->free_data) + codec->free_data(codec->codec_data); + ogg_stream_clear(&codec->os); + free(codec); +} + +static int send_page(shout_t *self, ogg_page *page) +{ + int ret; + + ret = shout_send_raw(self, page->header, page->header_len); + if (ret != page->header_len) + return self->error = SHOUTERR_SOCKET; + ret = shout_send_raw(self, page->body, page->body_len); + if (ret != page->body_len) + return self->error = SHOUTERR_SOCKET; + + return SHOUTERR_SUCCESS; +} diff --git a/lib/libshout/src/format_ogg.h b/lib/libshout/src/format_ogg.h new file mode 100644 index 00000000000..b24fd33a7bc --- /dev/null +++ b/lib/libshout/src/format_ogg.h @@ -0,0 +1,56 @@ +/* -*- c-basic-offset: 8; -*- */ +/* format_ogg.h: Internal shout interface to Ogg codec handlers + * $Id$ + * + * Copyright (C) 2004 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LIBSHOUT_FORMAT_OGG_H__ +#define __LIBSHOUT_FORMAT_OGG_H__ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +typedef struct _ogg_codec_tag { + ogg_stream_state os; + + unsigned int headers; + uint64_t senttime; + + void *codec_data; + int (*read_page)(struct _ogg_codec_tag *codec, ogg_page *page); + void (*free_data)(void *codec_data); + + struct _ogg_codec_tag *next; +} ogg_codec_t; + +/* codec hooks */ +int _shout_open_vorbis(ogg_codec_t *codec, ogg_page *page); +#ifdef HAVE_THEORA +int _shout_open_theora(ogg_codec_t *codec, ogg_page *page); +#endif +#ifdef HAVE_SPEEX +int _shout_open_speex(ogg_codec_t *codec, ogg_page *page); +#endif +int _shout_open_opus(ogg_codec_t *codec, ogg_page *page); + +#endif diff --git a/lib/libshout/src/format_webm.c b/lib/libshout/src/format_webm.c new file mode 100644 index 00000000000..ace8edcb603 --- /dev/null +++ b/lib/libshout/src/format_webm.c @@ -0,0 +1,68 @@ +/* -*- c-basic-offset: 8; -*- */ +/* webm.c: WebM data handler + * $Id$ + * + * Copyright (C) 2002-2012 the Icecast team + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#ifdef HAVE_INTTYPES_H +#include +#endif + +#include +#include "shout_private.h" + +/* -- local datatypes -- */ + +/* no local state */ + +/* -- static prototypes -- */ +static int send_webm(shout_t *self, const unsigned char *data, size_t len); +static void close_webm(shout_t *self); + +int shout_open_webm(shout_t *self) +{ + self->format_data = NULL; + self->send = send_webm; + self->close = close_webm; + + return SHOUTERR_SUCCESS; +} + +static int send_webm(shout_t *self, const unsigned char *data, size_t len) +{ + /* IMPORTANT TODO: we just send the raw data. We need throttling. */ + + ssize_t ret = shout_send_raw(self, data, len); + if (ret != (ssize_t)len) + return self->error = SHOUTERR_SOCKET; + + return self->error = SHOUTERR_SUCCESS; +} + +static void close_webm(shout_t *self) +{ + /* no local state */ + (void)self; +} diff --git a/lib/libshout/src/proto_http.c b/lib/libshout/src/proto_http.c new file mode 100644 index 00000000000..806d14874ce --- /dev/null +++ b/lib/libshout/src/proto_http.c @@ -0,0 +1,340 @@ +/* -*- c-basic-offset: 8; -*- */ +/* proto_http.c: Implementation of protocol HTTP. + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include + +#include +#include "shout_private.h" +#include "common/httpp/httpp.h" + +char *shout_http_basic_authorization(shout_t *self) +{ + char *out, *in; + int len; + + if (!self || !self->user || !self->password) + return NULL; + + len = strlen(self->user) + strlen(self->password) + 2; + if (!(in = malloc(len))) + return NULL; + snprintf(in, len, "%s:%s", self->user, self->password); + out = _shout_util_base64_encode(in); + free(in); + + len = strlen(out) + 24; + if (!(in = malloc(len))) { + free(out); + return NULL; + } + snprintf(in, len, "Authorization: Basic %s\r\n", out); + free(out); + + return in; +} + +int shout_create_http_request(shout_t *self) +{ + char *auth; + char *ai; + int ret = SHOUTERR_MALLOC; + util_dict *dict; + const char *key, *val; + const char *mimetype; + + switch (self->format) { + case SHOUT_FORMAT_OGG: + mimetype = "application/ogg"; + break; + case SHOUT_FORMAT_MP3: + mimetype = "audio/mpeg"; + break; + case SHOUT_FORMAT_WEBM: + mimetype = "video/webm"; + break; + case SHOUT_FORMAT_WEBMAUDIO: + mimetype = "audio/webm"; + break; + default: + return SHOUTERR_INSANE; + break; + } + + /* this is lazy code that relies on the only error from queue_* being + * SHOUTERR_MALLOC */ + do { + if (shout_queue_printf(self, "SOURCE %s HTTP/1.0\r\n", self->mount)) + break; + if (self->password && (self->server_caps & LIBSHOUT_CAP_GOTCAPS)) { + if (! (auth = shout_http_basic_authorization(self))) + break; + if (shout_queue_str(self, auth)) { + free(auth); + break; + } + free(auth); + } + if (self->useragent && shout_queue_printf(self, "Host: %s:%i\r\n", self->host, self->port)) + break; + if (self->useragent && shout_queue_printf(self, "User-Agent: %s\r\n", self->useragent)) + break; + if (shout_queue_printf(self, "Content-Type: %s\r\n", mimetype)) + break; + if (shout_queue_printf(self, "ice-public: %d\r\n", self->public)) + break; + + _SHOUT_DICT_FOREACH(self->meta, dict, key, val) { + if (val && shout_queue_printf(self, "ice-%s: %s\r\n", key, val)) + break; + } + + if ((ai = _shout_util_dict_urlencode(self->audio_info, ';'))) { + if (shout_queue_printf(self, "ice-audio-info: %s\r\n", ai)) { + free(ai); + break; + } + free(ai); + } + if (shout_queue_str(self, "\r\n")) + break; + + ret = SHOUTERR_SUCCESS; + } while (0); + + return ret; +} + +int shout_create_http_request_upgrade(shout_t *self, const char *proto) +{ + do { + if (shout_queue_str(self, "GET / HTTP/1.1\r\nConnection: Upgrade\r\n")) + break; + if (shout_queue_printf(self, "Upgrade: %s\r\n", proto)) + break; + /* Send Host:-header as this one may be used to select cert! */ + if (shout_queue_printf(self, "Host: %s:%i\r\n", self->host, self->port)) + break; + if (shout_queue_str(self, "\r\n")) + break; + return SHOUTERR_SUCCESS; + } while (0); + + return SHOUTERR_MALLOC; +} + +int shout_get_http_response(shout_t *self) +{ + int blen; + char *pc; + shout_buf_t *queue; + int newlines = 0; + + /* work from the back looking for \r?\n\r?\n. Anything else means more + * is coming. */ + for (queue = self->rqueue.head; queue->next; queue = queue->next); + pc = (char*)queue->data + queue->len - 1; + blen = queue->len; + while (blen) { + if (*pc == '\n') + newlines++; + /* we may have to scan the entire queue if we got a response with + * data after the head line (this can happen with eg 401) */ + else if (*pc != '\r') + newlines = 0; + + if (newlines == 2) + return SHOUTERR_SUCCESS; + + blen--; + pc--; + + if (!blen && queue->prev) { + queue = queue->prev; + pc = (char*)queue->data + queue->len - 1; + blen = queue->len; + } + } + + return SHOUTERR_BUSY; +} + +static inline void parse_http_response_caps(shout_t *self, const char *header, const char *str) { + const char * end; + size_t len; + char buf[64]; + + if (!self || !header || !str) + return; + + do { + for (; *str == ' '; str++); + end = strstr(str, ","); + if (end) { + len = end - str; + } else { + len = strlen(str); + } + + if (len > (sizeof(buf) - 1)) + return; + memcpy(buf, str, len); + buf[len] = 0; + + if (strcmp(header, "Allow") == 0){ + if (strcasecmp(buf, "SOURCE") == 0) { + self->server_caps |= LIBSHOUT_CAP_SOURCE; + } else if (strcasecmp(buf, "PUT") == 0) { + self->server_caps |= LIBSHOUT_CAP_PUT; + } else if (strcasecmp(buf, "POST") == 0) { + self->server_caps |= LIBSHOUT_CAP_POST; + } else if (strcasecmp(buf, "GET") == 0) { + self->server_caps |= LIBSHOUT_CAP_GET; + } + } else if (strcmp(header, "Accept-Encoding") == 0){ + if (strcasecmp(buf, "chunked") == 0) { + self->server_caps |= LIBSHOUT_CAP_CHUNKED; + } + } else if (strcmp(header, "Upgrade") == 0){ + if (strcasecmp(buf, "TLS/1.0") == 0) { + self->server_caps |= LIBSHOUT_CAP_UPGRADETLS; + } + } else { + return; /* unknown header */ + } + + str += len + 1; + } while (end); + + return; +} + +static inline int eat_body(shout_t *self, size_t len, const char *buf, size_t buflen) +{ + const char *p; + size_t header_len = 0; + char buffer[256]; + ssize_t got; + + if (!len) + return 0; + + for (p = buf; p < (buf+buflen-3); p++) { + if (p[0] == '\r' && p[1] == '\n' && p[2] == '\r' && p[3] == '\n') { + header_len = p - buf + 4; + break; + } else if (p[0] == '\n' && p[1] == '\n') { + header_len = p - buf + 2; + break; + } + } + if (!header_len && buflen >= 3 && buf[buflen-2] == '\n' && buf[buflen-3] == '\n') { + header_len = buflen - 1; + } else if (!header_len && buflen >= 2 && buf[buflen-1] == '\n' && buf[buflen-2] == '\n') { + header_len = buflen; + } + + if ( (buflen - header_len) > len) + return -1; + + len -= buflen - header_len; + + while (len) { + got = shout_conn_read(self, buffer, len > sizeof(buffer) ? sizeof(buffer) : len); + if (got == -1 && shout_conn_recoverable(self)) { + continue; + } else if (got == -1) { + return -1; + } + + len -= got; + } + + return 0; +} + +int shout_parse_http_response(shout_t *self) +{ + http_parser_t *parser; + char *header = NULL; + ssize_t hlen; + int code; + const char *retcode; + + /* all this copying! */ + hlen = shout_queue_collect(self->rqueue.head, &header); + if (hlen <= 0) + return SHOUTERR_MALLOC; + shout_queue_free(&self->rqueue); + + parser = httpp_create_parser(); + httpp_initialize(parser, NULL); + if (httpp_parse_response(parser, header, hlen, self->mount)) { + /* TODO: Headers to Handle: + * Allow:, Accept-Encoding:, Warning:, Upgrade: + */ + parse_http_response_caps(self, "Allow", httpp_getvar(parser, "allow")); + parse_http_response_caps(self, "Accept-Encoding", httpp_getvar(parser, "accept-encoding")); + parse_http_response_caps(self, "Upgrade", httpp_getvar(parser, "upgrade")); + self->server_caps |= LIBSHOUT_CAP_GOTCAPS; + retcode = httpp_getvar(parser, HTTPP_VAR_ERROR_CODE); + code = atoi(retcode); + if(code >= 200 && code < 300) { + httpp_destroy(parser); + free (header); + return SHOUTERR_SUCCESS; + } else if (code == 401 || code == 405 || code == 426 || code == 101) { + const char *content_length = httpp_getvar(parser, "content-length"); + if (content_length) { + if (eat_body(self, atoi(content_length), header, hlen) == -1) + goto failure; + } +#ifdef HAVE_OPENSSL + switch (code) { + case 426: self->tls_mode = SHOUT_TLS_RFC2817; break; + case 101: self->upgrade_to_tls = 1; break; + } +#endif + self->retry++; + if (self->retry > LIBSHOUT_MAX_RETRY) + self->retry = 0; + + goto retry; + } else { + self->retry = 0; + } + } + +failure: + self->retry = 0; +retry: + free(header); + httpp_destroy(parser); + return self->error = SHOUTERR_NOLOGIN; +} diff --git a/lib/libshout/src/proto_icy.c b/lib/libshout/src/proto_icy.c new file mode 100644 index 00000000000..a12f564603a --- /dev/null +++ b/lib/libshout/src/proto_icy.c @@ -0,0 +1,71 @@ +/* -*- c-basic-offset: 8; -*- */ +/* proto_icy.c: Implementation of protocol ICY. + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include "shout_private.h" + +int shout_create_icy_request(shout_t *self) +{ + const char *bitrate; + const char *val; + int ret; + + bitrate = shout_get_audio_info(self, SHOUT_AI_BITRATE); + if (!bitrate) + bitrate = "0"; + + ret = SHOUTERR_MALLOC; + do { + if (shout_queue_printf(self, "%s\n", self->password)) + break; + if (shout_queue_printf(self, "icy-name:%s\n", shout_get_meta(self, "name"))) + break; + val = shout_get_meta(self, "url"); + if (shout_queue_printf(self, "icy-url:%s\n", val ? val : "http://www.icecast.org/")) + break; + val = shout_get_meta(self, "irc"); + if (shout_queue_printf(self, "icy-irc:%s\n", val ? val : "")) + break; + val = shout_get_meta(self, "aim"); + if (shout_queue_printf(self, "icy-aim:%s\n", val ? val : "")) + break; + val = shout_get_meta(self, "icq"); + if (shout_queue_printf(self, "icy-icq:%s\n", val ? val : "")) + break; + if (shout_queue_printf(self, "icy-pub:%i\n", self->public)) + break; + val = shout_get_meta(self, "genre"); + if (shout_queue_printf(self, "icy-genre:%s\n", val ? val : "icecast")) + break; + if (shout_queue_printf(self, "icy-br:%s\n\n", bitrate)) + break; + + ret = SHOUTERR_SUCCESS; + } while (0); + + return ret; +} diff --git a/lib/libshout/src/proto_roaraudio.c b/lib/libshout/src/proto_roaraudio.c new file mode 100644 index 00000000000..a90c3a6cd61 --- /dev/null +++ b/lib/libshout/src/proto_roaraudio.c @@ -0,0 +1,297 @@ +/* -*- c-basic-offset: 8; -*- */ +/* proto_roaraudio.c: RoarAudio protocol support. + * $Id$ + * + * Copyright (C) 2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* for htonl(). */ +#include + +#include +#include +#include + +#include +#include "shout_private.h" + +typedef enum { + STATE_IDENT = 0, + STATE_AUTH, + STATE_NEW_STREAM, + STATE_EXEC +} shout_roar_protocol_state_t; + +typedef enum { + CMD_IDENTIFY = 1, + CMD_AUTH = 2, + CMD_NEW_STREAM = 3, + CMD_EXEC_STREAM = 5, + CMD_OK = 254 +} shout_roar_command_t; + +#define STREAM_NONE ((uint16_t)0xFFFF) +#define HEADER_SIZE 10 + +static int command_send(shout_t *self, shout_roar_command_t command, uint16_t stream, const void *data, size_t datalen) +{ + uint8_t header[HEADER_SIZE]; + + if (!self) + return SHOUTERR_INSANE; + + if (datalen > 65535) + return SHOUTERR_INSANE; + + if (datalen && !data) + return SHOUTERR_INSANE; + + /* version. + * While version 2 is already on it's way we still go for version 0 + * as it will work well for us and is defined as part of the core + * every RoarAudio server MUST implement. + */ + header[0] = 0; + /* command ID. */ + header[1] = command; + /* stream ID. First upper then lower byte. */ + header[2] = (stream & 0xFF00) >> 8; + header[3] = (stream & 0x00FF); + /* now 4 bytes of stream position. + * This implementation doesn't need this so we + * set it to all zeros. + */ + header[4] = 0; + header[5] = 0; + header[6] = 0; + header[7] = 0; + /* Now body ("data") size. First upper then lower byte. */ + header[8] = (datalen & 0xFF00) >> 8; + header[9] = (datalen & 0x00FF); + + shout_queue_data(&self->wqueue, header, HEADER_SIZE); + if (datalen) + shout_queue_data(&self->wqueue, data, datalen); + + return SHOUTERR_SUCCESS; +} + +static int shout_create_roaraudio_request_ident(shout_t *self) +{ + int ret; + size_t datalen; + uint8_t *data; + const char *agent; + uint32_t pid = getpid(); + + /* We implement version 1 IDENTIFY header. + * It has the following structure: + * byte 0: version (1). + * byte 1-4: PID in big endian. + * byte 5-end: client name. + */ + + agent = shout_get_agent(self); + if (!agent) + return SHOUTERR_INSANE; + + datalen = 5 + strlen(agent); + data = malloc(datalen); + if (!data) + return SHOUTERR_MALLOC; + + /* version number (1). */ + data[0] = 1; + /* PID */ + data[1] = (pid & 0xFF000000UL) >> 24; + data[2] = (pid & 0x00FF0000UL) >> 16; + data[3] = (pid & 0x0000FF00UL) >> 8; + data[4] = (pid & 0x000000FFUL) >> 0; + /* agent name */ + memcpy(data+5, agent, datalen-5); + + ret = command_send(self, CMD_IDENTIFY, STREAM_NONE, data, datalen); + + free(data); + + return ret; +} + +static int shout_create_roaraudio_request_auth(shout_t *self) +{ + /* Now we send an AUTH command to the server. + * We currently only implement the NONE type. + * NONE type is assumed by the server if + * we send an empty body. + */ + return command_send(self, CMD_AUTH, STREAM_NONE, NULL, 0); +} + +static int shout_create_roaraudio_request_new_stream(shout_t *self) +{ + uint32_t data[6]; + + /* We implement 24 byte NEW_STREAM structure (version 0). + * It has the following structure: + * byte 0- 3: stream direction [0]. + * byte 4- 7: Rel Pos ID (here: -1=NONE) + * byte 8-11: Sample Rate[1]. + * byte 12-15: Bits per Sample[1]. + * byte 16-19: Number of Channels[1]. + * byte 20-23: Codec ID[2]. + * + * The following asumptions are based on us only supporting + * Ogg-based for now. + * [0] = We currently only suport playback of waveform signals (1). + * See https://bts.keep-cool.org/wiki/Specs/DirValues + * [1] = Server should detect automagically. defaulting to: 44100/16/2. + * [2] = Ogg/Vorbis = 0x0010, Ogg/Speex = 0x0012, Ogg/FLAC = 0x0014, + * Ogg/CELT = 0x0016, Ogg/GENERAL (unknown logical streams) = 0x0015. + * See https://bts.keep-cool.org/wiki/Specs/CodecsValues + */ + + data[0] = htonl(1); + data[1] = htonl((uint32_t)-1); + data[2] = htonl(44100); + data[3] = htonl(32); + data[4] = htonl(2); + data[5] = htonl(0x0010); /* we assume Ogg/Vorbis for now. */ + + return command_send(self, CMD_NEW_STREAM, STREAM_NONE, data, 24); +} + +static int shout_create_roaraudio_request_exec(shout_t *self) +{ + /* Last an EXEC_STREAM command should be sent to open + * an IO channel for the new stream. + * If successful the control socket will be used for data + * after that. This very much like with SOURCE requests. + * so no hard deal to intigrate. + */ + return command_send(self, CMD_EXEC_STREAM, self->protocol_extra, NULL, 0); +} + +int shout_create_roaraudio_request(shout_t *self) +{ + switch ((shout_roar_protocol_state_t)self->protocol_state) { + case STATE_IDENT: + return shout_create_roaraudio_request_ident(self); + break; + case STATE_AUTH: + return shout_create_roaraudio_request_auth(self); + break; + case STATE_NEW_STREAM: + return shout_create_roaraudio_request_new_stream(self); + break; + case STATE_EXEC: + return shout_create_roaraudio_request_exec(self); + break; + } + + return SHOUTERR_INSANE; +} + +int shout_get_roaraudio_response(shout_t *self) +{ + shout_buf_t *queue; + size_t total_len = 0; + uint8_t header[HEADER_SIZE]; + + for (queue = self->rqueue.head; queue; queue = queue->next) { + if (total_len < 10) + memcpy(header+total_len, queue->data, queue->len > (HEADER_SIZE - total_len) ? (HEADER_SIZE - total_len) : queue->len); + total_len += queue->len; + } + + /* the header alone has 10 bytes. */ + if (total_len < HEADER_SIZE) + return SHOUTERR_BUSY; + + /* ok. we got a header. + * Now find the body length ("data length") bytes + * and see if they are both zero. + * If not the server sent us extra infos we currently + * not support. + */ + + if (header[8] || header[9]) + return SHOUTERR_UNSUPPORTED; + + /* Hey, we got a response. */ + return SHOUTERR_SUCCESS; +} + +int shout_parse_roaraudio_response(shout_t *self) +{ + char *data = NULL; + uint8_t header[HEADER_SIZE]; + + /* ok, this is the most hacky function in here as we do not + * use a well designed and universal parser for the responses. + * Yet there is little need for it. + * We just need to check if we got an CMD_OK and + * pull out the stream ID in case of STATE_NEW_STREAM. + * "data length" is already checked by shout_get_roaraudio_response(). + */ + + if (shout_queue_collect(self->rqueue.head, &data) != HEADER_SIZE) { + free(data); + return SHOUTERR_INSANE; + } + shout_queue_free(&self->rqueue); + memcpy(header, data, HEADER_SIZE); + free(data); + + /* check version */ + if (header[0] != 0) + return SHOUTERR_UNSUPPORTED; + + /* have we got a positive response? */ + if (header[1] != CMD_OK) + return SHOUTERR_NOLOGIN; + + switch ((shout_roar_protocol_state_t)self->protocol_state) { + case STATE_IDENT: + self->protocol_state = STATE_AUTH; + break; + case STATE_AUTH: + self->protocol_state = STATE_NEW_STREAM; + break; + case STATE_NEW_STREAM: + self->protocol_extra = (((unsigned int)header[2]) << 8) | (unsigned int)header[3]; + self->protocol_state = STATE_EXEC; + break; + case STATE_EXEC: + /* ok. everything worked. Continue normally! */ + return SHOUTERR_SUCCESS; + break; + default: + return SHOUTERR_INSANE; + break; + } + + self->state = SHOUT_STATE_REQ_CREATION; + return SHOUTERR_RETRY; +} diff --git a/lib/libshout/src/proto_xaudiocast.c b/lib/libshout/src/proto_xaudiocast.c new file mode 100644 index 00000000000..aef8297b493 --- /dev/null +++ b/lib/libshout/src/proto_xaudiocast.c @@ -0,0 +1,89 @@ +/* -*- c-basic-offset: 8; -*- */ +/* proto_xaudiocast.c: Implementation of protocol xaudiocast. + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#include +#include "shout_private.h" + +int shout_create_xaudiocast_request(shout_t *self) +{ + const char *bitrate; + const char *val; + int ret; + + bitrate = shout_get_audio_info(self, SHOUT_AI_BITRATE); + if (!bitrate) + bitrate = "0"; + + ret = SHOUTERR_MALLOC; + do { + if (shout_queue_printf(self, "SOURCE %s %s\n", self->password, self->mount)) + break; + if (shout_queue_printf(self, "x-audiocast-name: %s\n", shout_get_meta(self, "name"))) + break; + val = shout_get_meta(self, "url"); + if (shout_queue_printf(self, "x-audiocast-url: %s\n", val ? val : "http://www.icecast.org/")) + break; + val = shout_get_meta(self, "genre"); + if (shout_queue_printf(self, "x-audiocast-genre: %s\n", val ? val : "icecast")) + break; + if (shout_queue_printf(self, "x-audiocast-bitrate: %s\n", bitrate)) + break; + if (shout_queue_printf(self, "x-audiocast-public: %i\n", self->public)) + break; + val = shout_get_meta(self, "description"); + if (shout_queue_printf(self, "x-audiocast-description: %s\n", val ? val : "Broadcasting with the icecast streaming media server!")) + break; + if (self->dumpfile && shout_queue_printf(self, "x-audiocast-dumpfile: %s\n", self->dumpfile)) + break; + if (shout_queue_str(self, "\n")) + break; + + ret = SHOUTERR_SUCCESS; + } while (0); + + return ret; +} + +int shout_parse_xaudiocast_response(shout_t *self) +{ + char *response; + + if (shout_queue_collect(self->rqueue.head, &response) <= 0) + return SHOUTERR_MALLOC; + shout_queue_free(&self->rqueue); + + if (!strstr(response, "OK")) { + free(response); + return SHOUTERR_NOLOGIN; + } + free(response); + + return SHOUTERR_SUCCESS; +} diff --git a/lib/libshout/src/queue.c b/lib/libshout/src/queue.c new file mode 100644 index 00000000000..ea7c39e6a3d --- /dev/null +++ b/lib/libshout/src/queue.c @@ -0,0 +1,147 @@ +/* -*- c-basic-offset: 8; -*- */ +/* queue.c: Implementation data queue logic. + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include + +#include +#include "shout_private.h" + +/* queue data in pages of SHOUT_BUFSIZE bytes */ +int shout_queue_data(shout_queue_t *queue, const unsigned char *data, size_t len) +{ + shout_buf_t *buf; + size_t plen; + + if (!len) + return SHOUTERR_SUCCESS; + + if (!queue->len) { + queue->head = calloc(1, sizeof (shout_buf_t)); + if (!queue->head) + return SHOUTERR_MALLOC; + } + + for (buf = queue->head; buf->next; buf = buf->next); + + /* Maybe any added data should be freed if we hit a malloc error? + * Otherwise it'd be impossible to tell where to start requeueing. + * (As if anyone ever tried to recover from a malloc error.) */ + while (len > 0) { + if (buf->len == SHOUT_BUFSIZE) { + buf->next = calloc(1, sizeof (shout_buf_t)); + if (!buf->next) + return SHOUTERR_MALLOC; + buf->next->prev = buf; + buf = buf->next; + } + + plen = len > SHOUT_BUFSIZE - buf->len ? SHOUT_BUFSIZE - buf->len : len; + memcpy(buf->data + buf->len, data, plen); + buf->len += plen; + data += plen; + len -= plen; + queue->len += plen; + } + + return SHOUTERR_SUCCESS; +} + +int shout_queue_str(shout_t *self, const char *str) +{ + return shout_queue_data(&self->wqueue, (const unsigned char*)str, strlen(str)); +} + +/* this should be shared with sock_write. Create libicecommon. */ +int shout_queue_printf(shout_t *self, const char *fmt, ...) +{ + char buffer[1024]; + char *buf; + va_list ap, ap_retry; + int len; + + buf = buffer; + + va_start(ap, fmt); + va_copy(ap_retry, ap); + + len = vsnprintf(buf, sizeof(buffer), fmt, ap); + + self->error = SHOUTERR_SUCCESS; + if (len > 0) { + if ((size_t)len < sizeof(buffer)) + shout_queue_data(&self->wqueue, (unsigned char*)buf, len); + else { + buf = malloc(++len); + if (buf) { + len = vsnprintf(buf, len, fmt, ap_retry); + shout_queue_data(&self->wqueue, (unsigned char*)buf, len); + free(buf); + } else + self->error = SHOUTERR_MALLOC; + } + } + + va_end(ap_retry); + va_end(ap); + + return self->error; +} + +void shout_queue_free(shout_queue_t *queue) +{ + shout_buf_t *prev; + + while (queue->head) { + prev = queue->head; + queue->head = queue->head->next; + free(prev); + } + queue->len = 0; +} + +/* collect nodes of a queue into a single buffer */ +ssize_t shout_queue_collect(shout_buf_t *queue, char **buf) +{ + shout_buf_t *node; + size_t pos = 0; + size_t len = 0; + + for (node = queue; node; node = node->next) + len += node->len; + + if (!(*buf = malloc(len))) + return SHOUTERR_MALLOC; + + for (node = queue; node; node = node->next) { + memcpy(*buf + pos, node->data, node->len); + pos += node->len; + } + + return len; +} diff --git a/lib/libshout/src/shout.c b/lib/libshout/src/shout.c new file mode 100644 index 00000000000..d296ff33214 --- /dev/null +++ b/lib/libshout/src/shout.c @@ -0,0 +1,1398 @@ +/* -*- c-basic-offset: 8; -*- */ +/* shout.c: Implementation of public libshout interface shout.h + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "common/timing/timing.h" +#include "common/httpp/httpp.h" + +#include "shout_private.h" +#include "util.h" + +#ifdef _MSC_VER +# ifndef va_copy +# define va_copy(ap1, ap2) memcpy(&ap1, &ap2, sizeof(va_list)) +# endif +# define vsnprintf _vsnprintf +# define inline _inline +#endif + +/* -- local prototypes -- */ +static int send_queue(shout_t *self); +static int get_response(shout_t *self); +static int try_connect (shout_t *self); +static int try_write (shout_t *self, const void *data, size_t len); + +static int create_request(shout_t *self); +static int parse_response(shout_t *self); + +/* -- static data -- */ +static int _initialized = 0; + +/* -- public functions -- */ + +void shout_init(void) +{ + if (_initialized) + return; + + sock_initialize(); + _initialized = 1; +} + +void shout_shutdown(void) +{ + if (!_initialized) + return; + + sock_shutdown(); + _initialized = 0; +} + +shout_t *shout_new(void) +{ + shout_t *self; + + /* in case users haven't done this explicitly. Should we error + * if not initialized instead? */ + shout_init(); + + if (!(self = (shout_t *)calloc(1, sizeof(shout_t)))) { + return NULL; + } + + if (shout_set_host(self, LIBSHOUT_DEFAULT_HOST) != SHOUTERR_SUCCESS) { + shout_free(self); + + return NULL; + } + if (shout_set_user(self, LIBSHOUT_DEFAULT_USER) != SHOUTERR_SUCCESS) { + shout_free(self); + + return NULL; + } + if (shout_set_agent(self, LIBSHOUT_DEFAULT_USERAGENT) != SHOUTERR_SUCCESS) { + shout_free(self); + + return NULL; + } + if (!(self->audio_info = _shout_util_dict_new())) { + shout_free(self); + + return NULL; + } + if (!(self->meta = _shout_util_dict_new())) { + shout_free(self); + + return NULL; + } + if (shout_set_meta(self, "name", "no name") != SHOUTERR_SUCCESS) { + shout_free(self); + + return NULL; + } + +#ifdef HAVE_OPENSSL + if (shout_set_allowed_ciphers(self, LIBSHOUT_DEFAULT_ALLOWED_CIPHERS) != SHOUTERR_SUCCESS) { + shout_free(self); + + return NULL; + } + self->tls_mode = SHOUT_TLS_AUTO; +#endif + + self->port = LIBSHOUT_DEFAULT_PORT; + self->format = LIBSHOUT_DEFAULT_FORMAT; + self->protocol = LIBSHOUT_DEFAULT_PROTOCOL; + + return self; +} + +void shout_free(shout_t *self) +{ + if (!self) return; + + if (self->state != SHOUT_STATE_UNCONNECTED) return; + + if (self->host) free(self->host); + if (self->password) free(self->password); + if (self->mount) free(self->mount); + if (self->user) free(self->user); + if (self->useragent) free(self->useragent); + if (self->audio_info) _shout_util_dict_free (self->audio_info); + if (self->meta) _shout_util_dict_free (self->meta); + +#ifdef HAVE_OPENSSL + if (self->ca_directory) free(self->ca_directory); + if (self->ca_file) free(self->ca_file); + if (self->allowed_ciphers) free(self->allowed_ciphers); + if (self->client_certificate) free(self->client_certificate); +#endif + + free(self); +} + +int shout_open(shout_t *self) +{ + /* sanity check */ + if (!self) + return SHOUTERR_INSANE; + if (self->state != SHOUT_STATE_UNCONNECTED) + return SHOUTERR_CONNECTED; + if (!self->host || !self->password || !self->port) + return self->error = SHOUTERR_INSANE; + if (self->format == SHOUT_FORMAT_OGG && (self->protocol != SHOUT_PROTOCOL_HTTP && self->protocol != SHOUT_PROTOCOL_ROARAUDIO)) + return self->error = SHOUTERR_UNSUPPORTED; + + return self->error = try_connect(self); +} + + +int shout_close(shout_t *self) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state == SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_UNCONNECTED; + + if (self->state == SHOUT_STATE_CONNECTED && self->close) + self->close(self); + +#ifdef HAVE_OPENSSL + if (self->tls) + shout_tls_close(self->tls); + self->tls = NULL; +#endif + + sock_close(self->socket); + self->state = SHOUT_STATE_UNCONNECTED; + self->starttime = 0; + self->senttime = 0; + shout_queue_free(&self->rqueue); + shout_queue_free(&self->wqueue); + + return self->error = SHOUTERR_SUCCESS; +} + +int shout_send(shout_t *self, const unsigned char *data, size_t len) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_CONNECTED) + return self->error = SHOUTERR_UNCONNECTED; + + if (self->starttime <= 0) + self->starttime = timing_get_time(); + + if (!len) + return send_queue(self); + + return self->send(self, data, len); +} + +ssize_t shout_send_raw(shout_t *self, const unsigned char *data, size_t len) +{ + ssize_t ret; + + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_CONNECTED) + return SHOUTERR_UNCONNECTED; + + self->error = SHOUTERR_SUCCESS; + + /* send immediately if possible (should be the common case) */ + if (len && ! self->wqueue.len) { + if ((ret = try_write(self, data, len)) < 0) + return self->error; + if (ret < (ssize_t)len) { + self->error = shout_queue_data(&self->wqueue, data + ret, len - ret); + if (self->error != SHOUTERR_SUCCESS) + return self->error; + } + + return len; + } + + self->error = shout_queue_data(&self->wqueue, data, len); + if (self->error != SHOUTERR_SUCCESS) + return self->error; + + ret = send_queue(self); + if (ret == SHOUTERR_SUCCESS || (len && ret == SHOUTERR_BUSY)) + return len; + + return ret; +} + +ssize_t shout_queuelen(shout_t *self) +{ + if (!self) + return SHOUTERR_INSANE; + + return (ssize_t)self->wqueue.len; +} + + +void shout_sync(shout_t *self) +{ + int64_t sleep; + + if (!self) + return; + + if (self->senttime == 0) + return; + + sleep = self->senttime / 1000 - (timing_get_time() - self->starttime); + if (sleep > 0) + timing_sleep((uint64_t)sleep); + +} + +int shout_delay(shout_t *self) +{ + + if (!self) + return 0; + + if (self->senttime == 0) + return 0; + + return self->senttime / 1000 - (timing_get_time() - self->starttime); +} + +shout_metadata_t *shout_metadata_new(void) +{ + return _shout_util_dict_new(); +} + +void shout_metadata_free(shout_metadata_t *self) +{ + if (!self) + return; + + _shout_util_dict_free(self); +} + +int shout_metadata_add(shout_metadata_t *self, const char *name, const char *value) +{ + if (!self || !name) + return SHOUTERR_INSANE; + + return _shout_util_dict_set(self, name, value); +} + +/* open second socket to server, send HTTP request to change metadata. + * TODO: prettier error-handling. */ +int shout_set_metadata(shout_t *self, shout_metadata_t *metadata) +{ + int error; + sock_t socket = -1; + int rv; + char *encvalue = NULL; + const char *request_template; + char *request = NULL; + size_t request_len; + char *auth = NULL; +#ifdef HAVE_OPENSSL + shout_tls_t *tls = NULL; +#endif + + if (!self || !metadata) + return SHOUTERR_INSANE; + + if (!(encvalue = _shout_util_dict_urlencode(metadata, '&'))) + goto error_malloc; + + switch (self->protocol) { + case SHOUT_PROTOCOL_ICY: + request_template = "GET /admin.cgi?mode=updinfo&pass=%s&%s HTTP/1.0\r\nUser-Agent: %s (Mozilla compatible)\r\n\r\n"; + request_len = strlen(request_template) + strlen(self->password) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1; + if (!(request = malloc(request_len))) + goto error_malloc; + snprintf(request, request_len, request_template, self->password, encvalue, shout_get_agent(self)); + break; + case SHOUT_PROTOCOL_HTTP: + auth = shout_http_basic_authorization(self); + + request_template = "GET /admin/metadata?mode=updinfo&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n%s\r\n"; + request_len = strlen(request_template) + strlen(self->mount) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1; + if (auth) + request_len += strlen(auth); + if (!(request = malloc(request_len))) + goto error_malloc; + snprintf(request, request_len, request_template, self->mount, encvalue, shout_get_agent(self), auth ? auth : ""); + break; + default: + request_template = "GET /admin.cgi?mode=updinfo&pass=%s&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n\r\n"; + request_len = strlen(request_template) + strlen(self->password) + strlen(self->mount) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1; + if (!(request = malloc(request_len))) + goto error_malloc; + snprintf(request, request_len, request_template, self->password, self->mount, encvalue, shout_get_agent(self)); + break; + } + + free(encvalue); + encvalue = NULL; + + if (auth) + free(auth); + auth = NULL; + + if ((socket = sock_connect(self->host, self->port)) <= 0) + return SHOUTERR_NOCONNECT; + +#ifdef HAVE_OPENSSL + switch (self->tls_mode) { + case SHOUT_TLS_DISABLED: + /* nothing to do */ + break; + case SHOUT_TLS_RFC2817: /* Use TLS via HTTP Upgrade:-header [RFC2817]. */ + do { /* use a subscope to avoid more function level variables */ + char upgrade[512]; + size_t len; + + /* send upgrade request */ + snprintf(upgrade, sizeof(upgrade), + "GET / HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: TLS/1.0\r\nHost: %s:%i\r\n\r\n", + self->host, self->port); + upgrade[sizeof(upgrade)-1] = 0; + len = strlen(upgrade); + if (len == (sizeof(upgrade) - 1)) + goto error_malloc; + rv = sock_write_bytes(socket, upgrade, len); + if (len != (size_t)rv) + goto error_socket; + + /* read status line */ + if (!sock_read_line(socket, upgrade, sizeof(upgrade))) + goto error_socket; + if (strncmp(upgrade, "HTTP/1.1 101 ", 13) != 0) + goto error_socket; + + /* read headers */ + len = 0; + do { + if (!sock_read_line(socket, upgrade, sizeof(upgrade))) + goto error_socket; + if (upgrade[0] == 0) + break; + if (!strncasecmp(upgrade, "Content-Length: ", 16) == 0) + len = atoi(upgrade + 16); + } while (1); + + /* read body */ + while (len) { + rv = sock_read_bytes(socket, upgrade, len > sizeof(upgrade) ? sizeof(upgrade) : len); + if (rv < 1) + goto error_socket; + len -= rv; + } + } while (0); + /* fall thru */ + case SHOUT_TLS_RFC2818: /* Use TLS for transport layer like HTTPS [RFC2818] does. */ + tls = shout_tls_new(self, socket); + if (!tls) + goto error_malloc; + error = shout_tls_try_connect(tls); + if (error != SHOUTERR_SUCCESS) + goto error; + break; + default: + /* Bad mode or auto detection not completed. */ + error = SHOUTERR_INSANE; + goto error; + break; + } +#endif + +#ifdef HAVE_OPENSSL + if (tls) { + rv = shout_tls_write(tls, request, strlen(request)); + } else { + rv = sock_write(socket, "%s", request); + } +#else + rv = sock_write(socket, "%s", request); +#endif + + if (!rv) + goto error_socket; + + error = SHOUTERR_SUCCESS; + goto error; + +error_socket: + error = SHOUTERR_SOCKET; + goto error; +error_malloc: + error = SHOUTERR_MALLOC; + goto error; +error: +#ifdef HAVE_OPENSSL + if (tls) + shout_tls_close(tls); +#endif + if (socket != -1) + sock_close(socket); + if (encvalue) + free(encvalue); + if (request) + free(request); + if (auth) + free(auth); + return error; +} + +/* getters/setters */ +const char *shout_version(int *major, int *minor, int *patch) +{ + if (major) + *major = LIBSHOUT_MAJOR; + if (minor) + *minor = LIBSHOUT_MINOR; + if (patch) + *patch = LIBSHOUT_MICRO; + + return VERSION; +} + +int shout_get_errno(shout_t *self) +{ + return self->error; +} + +const char *shout_get_error(shout_t *self) +{ + if (!self) + return "Invalid shout_t"; + + switch (self->error) { + case SHOUTERR_SUCCESS: + return "No error"; + case SHOUTERR_INSANE: + return "Nonsensical arguments"; + case SHOUTERR_NOCONNECT: + return "Couldn't connect"; + case SHOUTERR_NOLOGIN: + return "Login failed"; + case SHOUTERR_SOCKET: + return "Socket error"; + case SHOUTERR_MALLOC: + return "Out of memory"; + case SHOUTERR_CONNECTED: + return "Cannot set parameter while connected"; + case SHOUTERR_UNCONNECTED: + return "Not connected"; + case SHOUTERR_BUSY: + return "Socket is busy"; + case SHOUTERR_UNSUPPORTED: + return "This libshout doesn't support the requested option"; + case SHOUTERR_NOTLS: + return "TLS requested but not supported by peer"; + case SHOUTERR_TLSBADCERT: + return "TLS connection can not be established because of bad certificate"; + case SHOUTERR_RETRY: + return "Please retry current operation."; + default: + return "Unknown error"; + } +} + +/* Returns: + * SHOUTERR_CONNECTED if the connection is open, + * SHOUTERR_UNCONNECTED if it has not yet been opened, + * or an error from try_connect, including SHOUTERR_BUSY + */ +int shout_get_connected(shout_t *self) +{ + int rc; + + if (!self) + return SHOUTERR_INSANE; + + if (self->state == SHOUT_STATE_CONNECTED) + return SHOUTERR_CONNECTED; + if (self->state != SHOUT_STATE_UNCONNECTED) { + if ((rc = try_connect(self)) == SHOUTERR_SUCCESS) + return SHOUTERR_CONNECTED; + return rc; + } + + return SHOUTERR_UNCONNECTED; +} + +int shout_set_host(shout_t *self, const char *host) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->host) + free(self->host); + + if (!(self->host = _shout_util_strdup(host))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_host(shout_t *self) +{ + if (!self) + return NULL; + + return self->host; +} + +int shout_set_port(shout_t *self, unsigned short port) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + self->port = port; + + return self->error = SHOUTERR_SUCCESS; +} + +unsigned short shout_get_port(shout_t *self) +{ + if (!self) + return 0; + + return self->port; +} + +int shout_set_password(shout_t *self, const char *password) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->password) + free (self->password); + + if (!(self->password = _shout_util_strdup(password))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char* shout_get_password(shout_t *self) +{ + if (!self) + return NULL; + + return self->password; +} + +int shout_set_mount(shout_t *self, const char *mount) +{ + size_t len; + + if (!self || !mount) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->mount) + free(self->mount); + + len = strlen (mount) + 1; + if (mount[0] != '/') + len++; + + if (!(self->mount = malloc(len))) + return self->error = SHOUTERR_MALLOC; + + snprintf (self->mount, len, "%s%s", mount[0] == '/' ? "" : "/", mount); + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_mount(shout_t *self) +{ + if (!self) + return NULL; + + return self->mount; +} + +int shout_set_name(shout_t *self, const char *name) +{ + return shout_set_meta(self, "name", name); +} + +const char *shout_get_name(shout_t *self) +{ + return shout_get_meta(self, "name"); +} + +int shout_set_url(shout_t *self, const char *url) +{ + return shout_set_meta(self, "url", url); +} + +const char *shout_get_url(shout_t *self) +{ + return shout_get_meta(self, "url"); +} + +int shout_set_genre(shout_t *self, const char *genre) +{ + return shout_set_meta(self, "genre", genre); +} + +const char *shout_get_genre(shout_t *self) +{ + return shout_get_meta(self, "genre"); +} + +int shout_set_agent(shout_t *self, const char *agent) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->useragent) + free(self->useragent); + + if (! (self->useragent = _shout_util_strdup (agent))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_agent(shout_t *self) +{ + if (!self) + return NULL; + + return self->useragent; +} + + +int shout_set_user(shout_t *self, const char *username) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->user) + free(self->user); + + if (! (self->user = _shout_util_strdup (username))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_user(shout_t *self) +{ + if (!self) + return NULL; + + return self->user; +} + +int shout_set_description(shout_t *self, const char *description) +{ + return shout_set_meta(self, "description", description); +} + +const char *shout_get_description(shout_t *self) +{ + return shout_get_meta(self, "description"); +} + +int shout_set_dumpfile(shout_t *self, const char *dumpfile) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return SHOUTERR_CONNECTED; + + if (self->dumpfile) + free(self->dumpfile); + + if (! (self->dumpfile = _shout_util_strdup (dumpfile))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_dumpfile(shout_t *self) +{ + if (!self) + return NULL; + + return self->dumpfile; +} + +int shout_set_audio_info(shout_t *self, const char *name, const char *value) +{ + if (!self) + return SHOUTERR_INSANE; + + return self->error = _shout_util_dict_set(self->audio_info, name, value); +} + +const char *shout_get_audio_info(shout_t *self, const char *name) +{ + if (!self) + return NULL; + + return _shout_util_dict_get(self->audio_info, name); +} + +int shout_set_meta(shout_t *self, const char *name, const char *value) +{ + size_t i; + + if (!self || !name) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + for (i = 0; name[i]; i++) + if ((name[i] < 'a' || name[i] > 'z') && (name[i] < '0' || name[i] > '9')) + return self->error = SHOUTERR_INSANE; + + return self->error = _shout_util_dict_set(self->meta, name, value); +} + +const char *shout_get_meta(shout_t *self, const char *name) +{ + if (!self) + return NULL; + + return _shout_util_dict_get(self->meta, name); +} + +int shout_set_public(shout_t *self, unsigned int public) +{ + if (!self || (public != 0 && public != 1)) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + self->public = public; + + return self->error = SHOUTERR_SUCCESS; +} + +unsigned int shout_get_public(shout_t *self) +{ + if (!self) + return 0; + + return self->public; +} + +int shout_set_format(shout_t *self, unsigned int format) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (format != SHOUT_FORMAT_OGG + && format != SHOUT_FORMAT_MP3 + && format != SHOUT_FORMAT_WEBM + && format != SHOUT_FORMAT_WEBMAUDIO) + return self->error = SHOUTERR_UNSUPPORTED; + + self->format = format; + + return self->error = SHOUTERR_SUCCESS; +} + +unsigned int shout_get_format(shout_t* self) +{ + if (!self) + return 0; + + return self->format; +} + +int shout_set_protocol(shout_t *self, unsigned int protocol) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (protocol != SHOUT_PROTOCOL_HTTP && + protocol != SHOUT_PROTOCOL_XAUDIOCAST && + protocol != SHOUT_PROTOCOL_ICY && + protocol != SHOUT_PROTOCOL_ROARAUDIO) + return self->error = SHOUTERR_UNSUPPORTED; + + self->protocol = protocol; + + return self->error = SHOUTERR_SUCCESS; +} + +unsigned int shout_get_protocol(shout_t *self) +{ + if (!self) + return 0; + + return self->protocol; +} + +int shout_set_nonblocking(shout_t *self, unsigned int nonblocking) +{ + if (!self || (nonblocking != 0 && nonblocking != 1)) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + self->nonblocking = nonblocking; + + return SHOUTERR_SUCCESS; +} + +unsigned int shout_get_nonblocking(shout_t *self) +{ + if (!self) + return 0; + + return self->nonblocking; +} + +/* TLS functions */ +#ifdef HAVE_OPENSSL +int shout_set_tls(shout_t *self, int mode) +{ + if (!self) + return SHOUTERR_INSANE; + + if (mode != SHOUT_TLS_DISABLED && + mode != SHOUT_TLS_AUTO && + mode != SHOUT_TLS_AUTO_NO_PLAIN && + mode != SHOUT_TLS_RFC2818 && + mode != SHOUT_TLS_RFC2817) + return self->error = SHOUTERR_UNSUPPORTED; + + self->tls_mode = mode; + return SHOUTERR_SUCCESS; +} +int shout_get_tls(shout_t *self) +{ + if (!self) + return SHOUTERR_INSANE; + + return self->tls_mode; +} + +int shout_set_ca_directory(shout_t *self, const char *directory) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->ca_directory) + free (self->ca_directory); + + if (!(self->ca_directory = _shout_util_strdup(directory))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_ca_directory(shout_t *self) +{ + if (!self) + return NULL; + + return self->ca_directory; +} + +int shout_set_ca_file(shout_t *self, const char *file) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->ca_file) + free (self->ca_file); + + if (!(self->ca_file = _shout_util_strdup(file))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_ca_file(shout_t *self) +{ + if (!self) + return NULL; + + return self->ca_file; +} + +int shout_set_allowed_ciphers(shout_t *self, const char *ciphers) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->allowed_ciphers) + free (self->allowed_ciphers); + + if (!(self->allowed_ciphers = _shout_util_strdup(ciphers))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_allowed_ciphers(shout_t *self) +{ + if (!self) + return NULL; + + return self->allowed_ciphers; +} + +int shout_set_client_certificate(shout_t *self, const char *certificate) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return self->error = SHOUTERR_CONNECTED; + + if (self->client_certificate) + free (self->client_certificate); + + if (!(self->client_certificate = _shout_util_strdup(certificate))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_client_certificate(shout_t *self) +{ + if (!self) + return NULL; + + return self->client_certificate; +} +#else +int shout_set_tls(shout_t *self, int mode) +{ + if (!self) + return SHOUTERR_INSANE; + + if (mode == SHOUT_TLS_DISABLED) + return SHOUTERR_SUCCESS; + + return self->error = SHOUTERR_UNSUPPORTED; +} +int shout_get_tls(shout_t *self) +{ + return SHOUT_TLS_DISABLED; +} +int shout_set_ca_directory(shout_t *self, const char *directory) +{ + if (!self) + return SHOUTERR_INSANE; + return self->error = SHOUTERR_UNSUPPORTED; +} +const char *shout_get_ca_directory(shout_t *self) +{ + return NULL; +} + +int shout_set_ca_file(shout_t *self, const char *file) +{ + if (!self) + return SHOUTERR_INSANE; + return self->error = SHOUTERR_UNSUPPORTED; +} +const char *shout_get_ca_file(shout_t *self) +{ + return NULL; +} + +int shout_set_allowed_ciphers(shout_t *self, const char *ciphers) +{ + if (!self) + return SHOUTERR_INSANE; + return self->error = SHOUTERR_UNSUPPORTED; +} +const char *shout_get_allowed_ciphers(shout_t *self) +{ + return NULL; +} + +int shout_set_client_certificate(shout_t *self, const char *certificate) +{ + if (!self) + return SHOUTERR_INSANE; + return self->error = SHOUTERR_UNSUPPORTED; +} +const char *shout_get_client_certificate(shout_t *self) +{ + return NULL; +} +#endif + +/* -- static function definitions -- */ +static int get_response(shout_t *self) +{ + char buf[1024]; + int rc; + + rc = shout_conn_read(self, buf, sizeof(buf)); + + if (rc < 0 && shout_conn_recoverable(self)) + return SHOUTERR_BUSY; + if (rc <= 0) + return SHOUTERR_SOCKET; + + if ((rc = shout_queue_data(&self->rqueue, (unsigned char*)buf, rc))) + return rc; + + if (self->protocol == SHOUT_PROTOCOL_ROARAUDIO) + return shout_get_roaraudio_response(self); + + return shout_get_http_response(self); +} + +static int try_connect (shout_t *self) +{ + int rc; + int port; + + /* the breaks between cases are omitted intentionally */ +retry: + switch (self->state) { + case SHOUT_STATE_UNCONNECTED: + port = self->port; + if (shout_get_protocol(self) == SHOUT_PROTOCOL_ICY) + port++; + + if (shout_get_nonblocking(self)) { + if ((self->socket = sock_connect_non_blocking(self->host, port)) < 0) + return self->error = SHOUTERR_NOCONNECT; + self->state = SHOUT_STATE_CONNECT_PENDING; + } else { + if ((self->socket = sock_connect(self->host, port)) < 0) + return self->error = SHOUTERR_NOCONNECT; + self->state = SHOUT_STATE_CONNECT_PENDING; + } + + case SHOUT_STATE_CONNECT_PENDING: + if (shout_get_nonblocking(self)) { + if ((rc = sock_connected(self->socket, 0)) < 1) { + if (rc == SOCK_ERROR) { + rc = SHOUTERR_SOCKET; + goto failure; + } else + return SHOUTERR_BUSY; + } + } + self->state = SHOUT_STATE_TLS_PENDING; + + case SHOUT_STATE_TLS_PENDING: +#ifdef HAVE_OPENSSL + if (self->tls_mode == SHOUT_TLS_DISABLED) { + /* nothing to be done */ + } else if (self->tls_mode == SHOUT_TLS_AUTO || self->tls_mode == SHOUT_TLS_AUTO_NO_PLAIN) { + if (self->server_caps & LIBSHOUT_CAP_GOTCAPS) { + /* We had a probe allready, otherwise just do nothing to poke the server. */ + if (self->server_caps & LIBSHOUT_CAP_UPGRADETLS) { + self->tls_mode = SHOUT_TLS_RFC2817; + } else { + if (self->tls_mode == SHOUT_TLS_AUTO_NO_PLAIN) + return SHOUTERR_NOTLS; + self->tls_mode = SHOUT_TLS_DISABLED; + } + self->state = SHOUT_STATE_TLS_PENDING; + goto retry; + } + } else if (self->tls_mode == SHOUT_TLS_RFC2818 || self->upgrade_to_tls) { + if (!self->tls) { + self->tls = shout_tls_new(self, self->socket); + if (!self->tls) /* just guessing that it's a malloc error */ + return SHOUTERR_MALLOC; + } + if ((rc = shout_tls_try_connect(self->tls)) != SHOUTERR_SUCCESS) { + if (rc == SHOUTERR_BUSY) + return SHOUTERR_BUSY; + goto failure; + } + } else if (self->tls_mode == SHOUT_TLS_RFC2817) { + if ((rc = shout_create_http_request_upgrade(self, "TLS/1.0")) != SHOUTERR_SUCCESS) { + if (rc == SHOUTERR_BUSY) + return SHOUTERR_BUSY; + goto failure; + } + self->state = SHOUT_STATE_REQ_PENDING; + goto retry; + } else { + rc = SHOUTERR_INSANE; + goto failure; + } +#endif + self->state = SHOUT_STATE_REQ_CREATION; + + case SHOUT_STATE_REQ_CREATION: + if ((rc = create_request(self)) != SHOUTERR_SUCCESS) + goto failure; + self->state = SHOUT_STATE_REQ_PENDING; + + case SHOUT_STATE_REQ_PENDING: + do + rc = send_queue(self); + while (!shout_get_nonblocking(self) && rc == SHOUTERR_BUSY); + if (rc == SHOUTERR_BUSY) + return rc; + + if (rc == SHOUTERR_SOCKET && self->retry) { + self->state = SHOUT_STATE_RECONNECT; + goto retry; + } + + if (rc != SHOUTERR_SUCCESS) + goto failure; + self->state = SHOUT_STATE_RESP_PENDING; + + case SHOUT_STATE_RESP_PENDING: + do + rc = get_response(self); + while (!shout_get_nonblocking(self) && rc == SHOUTERR_BUSY); + if (rc == SHOUTERR_BUSY) + return rc; + + if (rc == SHOUTERR_SOCKET && self->retry) { + self->state = SHOUT_STATE_RECONNECT; + goto retry; +#ifdef HAVE_OPENSSL + } else if (rc == SHOUTERR_SOCKET && !(self->server_caps & LIBSHOUT_CAP_GOTCAPS) && + (self->tls_mode == SHOUT_TLS_AUTO || self->tls_mode == SHOUT_TLS_AUTO_NO_PLAIN)) { + self->state = SHOUT_STATE_RECONNECT; + self->tls_mode = SHOUT_TLS_RFC2818; + goto retry; +#endif + } + + if (rc != SHOUTERR_SUCCESS) + goto failure; + + if ((rc = parse_response(self)) != SHOUTERR_SUCCESS) { + if (rc == SHOUTERR_RETRY) + goto retry; + if (self->retry) { + self->state = SHOUT_STATE_TLS_PENDING; + goto retry; + } + goto failure; + } + + switch (self->format) { + case SHOUT_FORMAT_OGG: + if ((rc = self->error = shout_open_ogg(self)) != SHOUTERR_SUCCESS) + goto failure; + break; + case SHOUT_FORMAT_MP3: + if ((rc = self->error = shout_open_mp3(self)) != SHOUTERR_SUCCESS) + goto failure; + break; + case SHOUT_FORMAT_WEBM: + case SHOUT_FORMAT_WEBMAUDIO: + if ((rc = self->error = shout_open_webm(self)) != SHOUTERR_SUCCESS) + goto failure; + break; + default: + rc = SHOUTERR_INSANE; + goto failure; + } + + case SHOUT_STATE_CONNECTED: + self->state = SHOUT_STATE_CONNECTED; + break; + + /* special case, no fallthru to this */ + case SHOUT_STATE_RECONNECT: + sock_close(self->socket); + self->state = SHOUT_STATE_UNCONNECTED; + goto retry; + break; + } + + return SHOUTERR_SUCCESS; + +failure: + shout_close(self); + return rc; +} + +static int try_write (shout_t *self, const void *data_p, size_t len) +{ + int ret; + size_t pos = 0; + unsigned char *data = (unsigned char *)data_p; + + /* loop until whole buffer is written (unless it would block) */ + do { + ret = shout_conn_write(self, data + pos, len - pos); + if (ret > 0) + pos += ret; + } while (pos < len && ret >= 0); + + if (ret < 0) + { + if (shout_conn_recoverable(self)) + { + self->error = SHOUTERR_BUSY; + return pos; + } + self->error = SHOUTERR_SOCKET; + return ret; + } + + return pos; +} + +ssize_t shout_conn_read(shout_t *self, void *buf, size_t len) +{ +#ifdef HAVE_OPENSSL + if (self->tls) + return shout_tls_read(self->tls, buf, len); +#endif + return sock_read_bytes(self->socket, buf, len); +} +ssize_t shout_conn_write(shout_t *self, const void *buf, size_t len) +{ +#ifdef HAVE_OPENSSL + if (self->tls) + return shout_tls_write(self->tls, buf, len); +#endif + return sock_write_bytes(self->socket, buf, len); +} +int shout_conn_recoverable(shout_t *self) +{ +#ifdef HAVE_OPENSSL + if (self->tls) + return shout_tls_recoverable(self->tls); +#endif + return sock_recoverable(sock_error()); +} + +static int send_queue(shout_t *self) +{ + shout_buf_t *buf; + int ret; + + if (!self->wqueue.len) + return SHOUTERR_SUCCESS; + + buf = self->wqueue.head; + while (buf) { + ret = try_write (self, buf->data + buf->pos, buf->len - buf->pos); + if (ret < 0) + return self->error; + + buf->pos += ret; + self->wqueue.len -= ret; + if (buf->pos == buf->len) { + self->wqueue.head = buf->next; + free(buf); + buf = self->wqueue.head; + if (buf) + buf->prev = NULL; + } else /* incomplete write */ + return SHOUTERR_BUSY; + } + + return self->error = SHOUTERR_SUCCESS; +} + +static int create_request(shout_t *self) +{ + if (self->protocol == SHOUT_PROTOCOL_HTTP) + return shout_create_http_request(self); + else if (self->protocol == SHOUT_PROTOCOL_XAUDIOCAST) + return shout_create_xaudiocast_request(self); + else if (self->protocol == SHOUT_PROTOCOL_ICY) + return shout_create_icy_request(self); + else if (self->protocol == SHOUT_PROTOCOL_ROARAUDIO) + return shout_create_roaraudio_request(self); + + return self->error = SHOUTERR_UNSUPPORTED; +} + +static int parse_response(shout_t *self) +{ + if (self->protocol == SHOUT_PROTOCOL_HTTP) + return shout_parse_http_response(self); + else if (self->protocol == SHOUT_PROTOCOL_XAUDIOCAST || + self->protocol == SHOUT_PROTOCOL_ICY) + return shout_parse_xaudiocast_response(self); + else if (self->protocol == SHOUT_PROTOCOL_ROARAUDIO) + return shout_parse_roaraudio_response(self); + + return self->error = SHOUTERR_UNSUPPORTED; +} diff --git a/lib/libshout/src/shout_private.h b/lib/libshout/src/shout_private.h new file mode 100644 index 00000000000..7902d36d4a0 --- /dev/null +++ b/lib/libshout/src/shout_private.h @@ -0,0 +1,210 @@ +/* -*- c-basic-offset: 8; -*- */ +/* shout.h: Private libshout data structures and declarations + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012-2015 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef __LIBSHOUT_SHOUT_PRIVATE_H__ +#define __LIBSHOUT_SHOUT_PRIVATE_H__ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include "util.h" + +#include +#ifdef HAVE_STDINT_H +# include +#elif defined (HAVE_INTTYPES_H) +# include +#endif + +#ifdef HAVE_OPENSSL +#include +#endif + +#define LIBSHOUT_DEFAULT_HOST "localhost" +#define LIBSHOUT_DEFAULT_PORT 8000 +#define LIBSHOUT_DEFAULT_FORMAT SHOUT_FORMAT_OGG +#define LIBSHOUT_DEFAULT_PROTOCOL SHOUT_PROTOCOL_HTTP +#define LIBSHOUT_DEFAULT_USER "source" +#define LIBSHOUT_DEFAULT_USERAGENT "libshout/" VERSION +#define LIBSHOUT_DEFAULT_ALLOWED_CIPHERS "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" /* Mozilla's 'Intermediate' list as of 2015-04-19 */ + +/* server capabilities. + 0x000000XXUL -> Methods. + 0x0000XX00UL -> HTTP Options + 0x000X0000UL -> TLS Related + 0xX0000000UL -> State related + 0x0XX00000UL -> Reserved + */ +#define LIBSHOUT_CAP_SOURCE 0x00000001UL +#define LIBSHOUT_CAP_PUT 0x00000002UL +#define LIBSHOUT_CAP_GET 0x00000004UL +#define LIBSHOUT_CAP_POST 0x00000008UL +#define LIBSHOUT_CAP_CHUNKED 0x00000100UL +#define LIBSHOUT_CAP_100CONTINUE 0x00000200UL +#define LIBSHOUT_CAP_UPGRADETLS 0x00010000UL +#define LIBSHOUT_CAP_GOTCAPS 0x80000000UL + +#define LIBSHOUT_MAX_RETRY 2 + +#define SHOUT_BUFSIZE 4096 + +typedef struct _shout_tls shout_tls_t; + +typedef struct _shout_buf { + unsigned char data[SHOUT_BUFSIZE]; + unsigned int len; + unsigned int pos; + + struct _shout_buf *prev; + struct _shout_buf *next; +} shout_buf_t; + +typedef struct { + shout_buf_t *head; + size_t len; +} shout_queue_t; + +typedef enum { + SHOUT_STATE_UNCONNECTED = 0, + SHOUT_STATE_CONNECT_PENDING, + SHOUT_STATE_TLS_PENDING, + SHOUT_STATE_REQ_CREATION, + SHOUT_STATE_REQ_PENDING, + SHOUT_STATE_RESP_PENDING, + SHOUT_STATE_CONNECTED, + SHOUT_STATE_RECONNECT +} shout_state_e; + +struct shout { + /* hostname or IP of icecast server */ + char *host; + /* port of the icecast server */ + int port; + /* login password for the server */ + char *password; + /* server protocol to use */ + unsigned int protocol; + /* type of data being sent */ + unsigned int format; + /* audio encoding parameters */ + util_dict *audio_info; + + /* user-agent to use when doing HTTP login */ + char *useragent; + /* mountpoint for this stream */ + char *mount; + /* all the meta data about the stream */ + util_dict *meta; + /* icecast 1.x dumpfile */ + char *dumpfile; + /* username to use for HTTP auth. */ + char *user; + /* is this stream private? */ + int public; + + /* TLS options */ +#ifdef HAVE_OPENSSL + int upgrade_to_tls; + int tls_mode; + char *ca_directory; + char *ca_file; + char *allowed_ciphers; + char *client_certificate; + shout_tls_t *tls; +#endif + + /* server capabilities (LIBSHOUT_CAP_*) */ + uint32_t server_caps; + + /* Should we retry on error? */ + int retry; + + /* socket the connection is on */ + sock_t socket; + shout_state_e state; + int protocol_state; /* extra state information from the protocol */ + int protocol_extra; /* extra data from the protocol */ + int nonblocking; + + void *format_data; + int (*send)(shout_t* self, const unsigned char* buff, size_t len); + void (*close)(shout_t* self); + + shout_queue_t rqueue; + shout_queue_t wqueue; + + /* start of this period's timeclock */ + uint64_t starttime; + /* amout of data we've sent (in milliseconds) */ + uint64_t senttime; + + int error; +}; + +/* helper functions */ +int shout_queue_data(shout_queue_t *queue, const unsigned char *data, size_t len); +int shout_queue_str(shout_t *self, const char *str); +int shout_queue_printf(shout_t *self, const char *fmt, ...); +void shout_queue_free(shout_queue_t *queue); +ssize_t shout_queue_collect(shout_buf_t *queue, char **buf); + +/* transports */ +ssize_t shout_conn_read(shout_t *self, void *buf, size_t len); +ssize_t shout_conn_write(shout_t *self, const void *buf, size_t len); +int shout_conn_recoverable(shout_t *self); + +#ifdef HAVE_OPENSSL +shout_tls_t *shout_tls_new(shout_t *self, sock_t socket); +int shout_tls_try_connect(shout_tls_t *tls); +int shout_tls_close(shout_tls_t *tls); +ssize_t shout_tls_read(shout_tls_t *tls, void *buf, size_t len); +ssize_t shout_tls_write(shout_tls_t *tls, const void *buf, size_t len); +int shout_tls_recoverable(shout_tls_t *tls); +#endif + +/* protocols */ +char *shout_http_basic_authorization(shout_t *self); +int shout_create_http_request(shout_t *self); +int shout_create_http_request_upgrade(shout_t *self, const char *proto); +int shout_get_http_response(shout_t *self); +int shout_parse_http_response(shout_t *self); + +int shout_create_xaudiocast_request(shout_t *self); +int shout_parse_xaudiocast_response(shout_t *self); + +int shout_create_icy_request(shout_t *self); + +int shout_create_roaraudio_request(shout_t *self); +int shout_get_roaraudio_response(shout_t *self); +int shout_parse_roaraudio_response(shout_t *self); + +/* containsers */ +int shout_open_ogg(shout_t *self); +int shout_open_mp3(shout_t *self); +int shout_open_webm(shout_t *self); + +#endif /* __LIBSHOUT_SHOUT_PRIVATE_H__ */ diff --git a/lib/libshout/src/tls.c b/lib/libshout/src/tls.c new file mode 100644 index 00000000000..e0e5c1a5f07 --- /dev/null +++ b/lib/libshout/src/tls.c @@ -0,0 +1,247 @@ +/* -*- c-basic-offset: 8; -*- */ +/* tls.c: TLS support functions + * $Id$ + * + * Copyright (C) 2015 Philipp Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include "shout_private.h" + +#ifndef XXX_HAVE_X509_check_host +#include +#endif + +struct _shout_tls { + SSL_CTX *ssl_ctx; + SSL *ssl; + int ssl_ret; + /* only pointers into self, don't need to free them */ + sock_t socket; + const char *host; + const char *ca_directory; + const char *ca_file; + const char *allowed_ciphers; + const char *client_certificate; +}; + +shout_tls_t *shout_tls_new(shout_t *self, sock_t socket) +{ + shout_tls_t *tls = calloc(1, sizeof(shout_tls_t)); + if (!tls) + return NULL; + + tls->socket = socket; + tls->host = self->host; + tls->ca_directory = self->ca_directory; + tls->ca_file = self->ca_file; + tls->allowed_ciphers = self->allowed_ciphers; + tls->client_certificate = self->client_certificate; + + return tls; +} + +static inline int tls_setup(shout_tls_t *tls) +{ + const SSL_METHOD *meth; +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) + SSL_library_init(); + SSL_load_error_strings(); + SSLeay_add_all_algorithms(); + SSLeay_add_ssl_algorithms(); + + meth = SSLv23_client_method(); +#else + meth = TLS_client_method(); +#endif + if (!meth) + goto error; + + tls->ssl_ctx = SSL_CTX_new(meth); + if (!tls->ssl_ctx) + goto error; + + SSL_CTX_set_default_verify_paths(tls->ssl_ctx); + SSL_CTX_load_verify_locations(tls->ssl_ctx, tls->ca_file, tls->ca_directory); + + SSL_CTX_set_verify(tls->ssl_ctx, SSL_VERIFY_NONE, NULL); + + if (tls->client_certificate) { + if (SSL_CTX_use_certificate_file(tls->ssl_ctx, tls->client_certificate, SSL_FILETYPE_PEM) != 1) + goto error; + if (SSL_CTX_use_PrivateKey_file(tls->ssl_ctx, tls->client_certificate, SSL_FILETYPE_PEM) != 1) + goto error; + } + + if (SSL_CTX_set_cipher_list(tls->ssl_ctx, tls->allowed_ciphers) <= 0) + goto error; + + SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_AUTO_RETRY); + + tls->ssl = SSL_new(tls->ssl_ctx); + if (!tls->ssl) + goto error; + + if (!SSL_set_fd(tls->ssl, tls->socket)) + goto error; + + SSL_set_tlsext_host_name(tls->ssl, tls->host); + SSL_set_connect_state(tls->ssl); + tls->ssl_ret = SSL_connect(tls->ssl); + + return SHOUTERR_SUCCESS; + + error: + if (tls->ssl) + SSL_free(tls->ssl); + if (tls->ssl_ctx) + SSL_CTX_free(tls->ssl_ctx); + return SHOUTERR_UNSUPPORTED; +} + +#ifndef XXX_HAVE_X509_check_host +static inline int tls_check_pattern(const char *key, const char *pattern) +{ + for (; *key && *pattern; key++) { + if (*pattern == '*') { + for (; *pattern == '*'; pattern++); + for (; *key && *key != '.'; key++); + if (!*pattern && !*key) + return 1; + if (!*pattern || !*key) + return 0; + } + + if (tolower(*key) != tolower(*pattern)) + return 0; + pattern++; + } + + return *key == 0 && *pattern == 0; +} +static inline int tls_check_host(X509 *cert, const char *hostname) +{ + char common_name[256] = ""; + X509_NAME *xname = X509_get_subject_name(cert); + X509_NAME_ENTRY *xentry; + ASN1_STRING *sdata; + int i, j; + int ret; + + ret = X509_NAME_get_text_by_NID(xname, NID_commonName, common_name, sizeof(common_name)); + if (ret < 1 || (size_t)ret >= (sizeof(common_name)-1)) + return SHOUTERR_TLSBADCERT; + + if (!tls_check_pattern(hostname, common_name)) + return SHOUTERR_TLSBADCERT; + + /* check for inlined \0, see https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike */ + for (i = -1; ; i = j) { + j = X509_NAME_get_index_by_NID(xname, NID_commonName, i); + if (j == -1) + break; + } + + xentry = X509_NAME_get_entry(xname, i); + sdata = X509_NAME_ENTRY_get_data(xentry); + + if ((size_t)ASN1_STRING_length(sdata) != strlen(common_name)) + return SHOUTERR_TLSBADCERT; + + return SHOUTERR_SUCCESS; +} +#endif + +static inline int tls_check_cert(shout_tls_t *tls) +{ + X509 *cert = SSL_get_peer_certificate(tls->ssl); + int cert_ok = 0; + if (!cert) + return SHOUTERR_TLSBADCERT; + + do { + if (SSL_get_verify_result(tls->ssl) != X509_V_OK) + break; + +#ifdef XXX_HAVE_X509_check_host + if (X509_check_host(cert, tls->host, 0, 0, NULL) != 1) + break; +#else + if (tls_check_host(cert, tls->host) != SHOUTERR_SUCCESS) + break; +#endif + + /* ok, all test passed... */ + cert_ok = 1; + } while (0); + + X509_free(cert); + return cert_ok ? SHOUTERR_SUCCESS : SHOUTERR_TLSBADCERT; +} + +static inline int tls_setup_process(shout_tls_t *tls) +{ + if (SSL_is_init_finished(tls->ssl)) + return tls_check_cert(tls); + tls->ssl_ret = SSL_connect(tls->ssl); + if (SSL_is_init_finished(tls->ssl)) + return tls_check_cert(tls); + return SHOUTERR_BUSY; +} + +int shout_tls_try_connect(shout_tls_t *tls) +{ + if (!tls->ssl) + tls_setup(tls); + if (tls->ssl) + return tls_setup_process(tls); + return SHOUTERR_UNSUPPORTED; +} +int shout_tls_close(shout_tls_t *tls) { + if (tls->ssl) { + SSL_shutdown(tls->ssl); + SSL_free(tls->ssl); + } + if (tls->ssl_ctx) + SSL_CTX_free(tls->ssl_ctx); + free(tls); + return SHOUTERR_SUCCESS; +} + +ssize_t shout_tls_read(shout_tls_t *tls, void *buf, size_t len) +{ + return tls->ssl_ret = SSL_read(tls->ssl, buf, len); +} + +ssize_t shout_tls_write(shout_tls_t *tls, const void *buf, size_t len) +{ + return tls->ssl_ret = SSL_write(tls->ssl, buf, len); +} + +int shout_tls_recoverable(shout_tls_t *tls) +{ + int error = SSL_get_error(tls->ssl, tls->ssl_ret); + if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) + return 1; + return 0; +} diff --git a/lib/libshout/src/util.c b/lib/libshout/src/util.c new file mode 100644 index 00000000000..fdc217845b5 --- /dev/null +++ b/lib/libshout/src/util.c @@ -0,0 +1,328 @@ +/* util.c: libshout utility/portability functions + * + * Copyright (C) 2002-2003 the Icecast team , + * Copyright (C) 2012 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include + +#include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#include +#include "util.h" + +char *_shout_util_strdup(const char *s) +{ + if (!s) + return NULL; + + return strdup(s); +} + +int _shout_util_read_header(int sock, char *buff, unsigned long len) +{ + int read_bytes, ret; + unsigned long pos; + char c; + + read_bytes = 1; + pos = 0; + ret = 0; + + while ((read_bytes == 1) && (pos < (len - 1))) { + read_bytes = 0; + + if ((read_bytes = recv(sock, &c, 1, 0))) { + if (c != '\r') + buff[pos++] = c; + if ((pos > 1) && (buff[pos - 1] == '\n' && buff[pos - 2] == '\n')) { + ret = 1; + break; + } + } else { + break; + } + } + + if (ret) buff[pos] = '\0'; + + return ret; +} + +static char base64table[65] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/', +}; + +/* This isn't efficient, but it doesn't need to be */ +char *_shout_util_base64_encode(char *data) +{ + int len = strlen(data); + char *out = malloc(len*4/3 + 4); + char *result = out; + int chunk; + + while(len > 0) { + chunk = (len >3)?3:len; + *out++ = base64table[(*data & 0xFC)>>2]; + *out++ = base64table[((*data & 0x03)<<4) | ((*(data+1) & 0xF0) >> 4)]; + + switch(chunk) { + case 3: + *out++ = base64table[((*(data+1) & 0x0F)<<2) | ((*(data+2) & 0xC0)>>6)]; + *out++ = base64table[(*(data+2)) & 0x3F]; + break; + case 2: + *out++ = base64table[((*(data+1) & 0x0F)<<2)]; + *out++ = '='; + break; + case 1: + *out++ = '='; + *out++ = '='; + break; + } + data += chunk; + len -= chunk; + } + *out = 0; + + return result; +} + +static char urltable[16] = { + '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' +}; + +static char safechars[256] = { + 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, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, +}; + +/* modified from libshout1, which credits Rick Franchuk . + * Caller must free result. */ +char *_shout_util_url_encode(const char *data) { + const char *p; + char *q, *dest; + int digit; + size_t n; + + for (p = data, n = 0; *p; p++) { + n++; + if (!safechars[(unsigned char)(*p)]) + n += 2; + } + if (!(dest = malloc(n+1))) + return NULL; + + for (p = data, q = dest; *p; p++, q++) { + if (safechars[(unsigned char)(*p)]) { + *q = *p; + } else { + *q++ = '%'; + digit = (*p >> 4) & 0xF; + *q++ = urltable[digit]; + digit = *p & 0xf; + *q = urltable[digit]; + n += 2; + } + } + *q = '\0'; + + return dest; +} + +util_dict *_shout_util_dict_new(void) +{ + return (util_dict *)calloc(1, sizeof(util_dict)); +} + +void _shout_util_dict_free(util_dict *dict) +{ + util_dict *next; + + while (dict) { + next = dict->next; + + if (dict->key) + free (dict->key); + if (dict->val) + free (dict->val); + free (dict); + + dict = next; + } +} + +const char *_shout_util_dict_get(util_dict *dict, const char *key) +{ + while (dict) { + if (dict->key && !strcmp(key, dict->key)) + return dict->val; + dict = dict->next; + } + + return NULL; +} + +int _shout_util_dict_set(util_dict *dict, const char *key, const char *val) +{ + util_dict *prev; + + if (!dict || !key) + return SHOUTERR_INSANE; + + prev = NULL; + while (dict) { + if (!dict->key || !strcmp(dict->key, key)) + break; + prev = dict; + dict = dict->next; + } + + if (!dict) { + dict = _shout_util_dict_new(); + if (!dict) + return SHOUTERR_MALLOC; + if (prev) + prev->next = dict; + } + + if (dict->key) + free (dict->val); + else if (!(dict->key = strdup(key))) { + if (prev) + prev->next = NULL; + _shout_util_dict_free (dict); + + return SHOUTERR_MALLOC; + } + + dict->val = strdup(val); + if (!dict->val) { + return SHOUTERR_MALLOC; + } + + return SHOUTERR_SUCCESS; +} + +/* given a dictionary, URL-encode each key and val and stringify them in order as + key=val&key=val... if val is set, or just key&key if val is NULL. + TODO: Memory management needs overhaul. */ +char *_shout_util_dict_urlencode(util_dict *dict, char delim) +{ + size_t reslen, resoffset; + char *res, *tmp; + char *enc; + int start = 1; + + for (res = NULL; dict; dict = dict->next) { + /* encode key */ + if (!dict->key) + continue; + if (!(enc = _shout_util_url_encode(dict->key))) { + if (res) + free(res); + return NULL; + } + if (start) { + reslen = strlen(enc) + 1; + if (!(res = malloc(reslen))) { + free(enc); + return NULL; + } + snprintf(res, reslen, "%s", enc); + free(enc); + start = 0; + } else { + resoffset = strlen(res); + reslen = resoffset + strlen(enc) + 2; + if (!(tmp = realloc(res, reslen))) { + free(enc); + free(res); + return NULL; + } else + res = tmp; + snprintf(res + resoffset, reslen - resoffset, "%c%s", delim, enc); + free(enc); + } + + /* encode value */ + if (!dict->val) + continue; + if (!(enc = _shout_util_url_encode(dict->val))) { + free(res); + return NULL; + } + + resoffset = strlen(res); + reslen = resoffset + strlen(enc) + 2; + if (!(tmp = realloc(res, reslen))) { + free(enc); + free(res); + return NULL; + } else + res = tmp; + snprintf(res + resoffset, reslen - resoffset, "=%s", enc); + free(enc); + } + + return res; +} + +const char *_shout_util_dict_next(util_dict **dict, const char **key, const char **val) { + *key = NULL; + *val = NULL; + + if (!dict) + return NULL; + *dict = (*dict)->next; + while (*dict && !(*dict)->key) + *dict = (*dict)->next; + if (!*dict) + return NULL; + *key = (*dict)->key; + *val = (*dict)->val; + return *key; +} diff --git a/lib/libshout/src/util.h b/lib/libshout/src/util.h new file mode 100644 index 00000000000..d58b5d33516 --- /dev/null +++ b/lib/libshout/src/util.h @@ -0,0 +1,50 @@ +/* util.h: libshout utility/portability functions + * + * Copyright (C) 2002-2004 the Icecast team , + * Copyright (C) 2012 Philipp "ph3-der-loewe" Schafft + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef __LIBSHOUT_UTIL_H__ +#define __LIBSHOUT_UTIL_H__ + +/* String dictionary type, without support for NULL keys, or multiple + * instances of the same key */ +typedef struct _util_dict { + char *key; + char *val; + struct _util_dict *next; +} util_dict; + +char *_shout_util_strdup(const char *s); + +util_dict *_shout_util_dict_new(void); +void _shout_util_dict_free(util_dict *dict); +/* dict, key must not be NULL. */ +int _shout_util_dict_set(util_dict *dict, const char *key, const char *val); +const char *_shout_util_dict_get(util_dict *dict, const char *key); +char *_shout_util_dict_urlencode(util_dict *dict, char delim); + +const char *_shout_util_dict_next(util_dict **dict, const char **key, const char **val); +#define _SHOUT_DICT_FOREACH(init,var,keyvar,valvar) for ((var) = (init), (keyvar) = (var)->key ? (var)->key : _shout_util_dict_next(&(var), &(keyvar), &(valvar)), (valvar) = (var)->val; (var); _shout_util_dict_next(&(var), &(keyvar), &(valvar))) + +char *_shout_util_base64_encode(char *data); +char *_shout_util_url_encode(const char *data); +int _shout_util_read_header(int sock, char *buff, unsigned long len); + +#endif /* __LIBSHOUT_UTIL_H__ */ diff --git a/lib/libshout/win32/Makefile.am b/lib/libshout/win32/Makefile.am new file mode 100644 index 00000000000..c8ef5a68714 --- /dev/null +++ b/lib/libshout/win32/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = libshout.dsp libshout.dsw + diff --git a/lib/libshout/win32/libshout.dsp b/lib/libshout/win32/libshout.dsp new file mode 100755 index 00000000000..9b35845e385 --- /dev/null +++ b/lib/libshout/win32/libshout.dsp @@ -0,0 +1,172 @@ +# Microsoft Developer Studio Project File - Name="libshout" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libshout - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libshout.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libshout.mak" CFG="libshout - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libshout - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libshout - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libshout - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\src" /I "..\src/httpp" /I "..\src/thread" /I "..\src/log" /I "..\src/avl" /I "..\src/net" /I "..\src/timings" /I "../" /I "../../pthreads" /I "../../oggvorbis-win32sdk-1.0.1/include" /I "../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "_WIN32" /D VERSION=\"2.4.1\" /D LIBSHOUT_MAJOR=2 /D LIBSHOUT_MINOR=0 /D LIBSHOUT_MICRO=0 /D "HAVE_WINSOCK2_H" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libshout - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\src" /I "..\src/httpp" /I "..\src/thread" /I "..\src/log" /I "..\src/avl" /I "..\src/net" /I "..\src/timings" /I "../" /I "../../pthreads" /I "../../oggvorbis-win32sdk-1.0.1/include" /I "../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "_WIN32" /D VERSION=\"2.0.0\" /D LIBSHOUT_MAJOR=2 /D LIBSHOUT_MINOR=0 /D LIBSHOUT_MICRO=0 /D "HAVE_WINSOCK2_H" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "libshout - Win32 Release" +# Name "libshout - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\src\avl\avl.c +# End Source File +# Begin Source File + +SOURCE=..\src\avl\avl.h +# End Source File +# Begin Source File + +SOURCE=..\src\httpp\httpp.c +# End Source File +# Begin Source File + +SOURCE=..\src\httpp\httpp.h +# End Source File +# Begin Source File + +SOURCE=..\src\mp3.c +# End Source File +# Begin Source File + +SOURCE=..\src\ogg.c +# End Source File +# Begin Source File + +SOURCE=..\src\net\resolver.c +# End Source File +# Begin Source File + +SOURCE=..\src\net\resolver.h +# End Source File +# Begin Source File + +SOURCE=..\src\shout.c +# End Source File +# Begin Source File + +SOURCE=..\src\shout_private.h +# End Source File +# Begin Source File + +SOURCE=..\src\net\sock.c +# End Source File +# Begin Source File + +SOURCE=..\src\net\sock.h +# End Source File +# Begin Source File + +SOURCE=..\src\thread\thread.c +# End Source File +# Begin Source File + +SOURCE=..\src\thread\thread.h +# End Source File +# Begin Source File + +SOURCE=..\src\timing\timing.c +# End Source File +# Begin Source File + +SOURCE=..\src\timing\timing.h +# End Source File +# Begin Source File + +SOURCE=..\src\util.c +# End Source File +# Begin Source File + +SOURCE=..\src\util.h +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\include\os.h +# End Source File +# Begin Source File + +SOURCE=..\include\shout\shout.h +# End Source File +# End Group +# End Target +# End Project diff --git a/lib/libshout/win32/libshout.dsw b/lib/libshout/win32/libshout.dsw new file mode 100755 index 00000000000..efe61dd5225 --- /dev/null +++ b/lib/libshout/win32/libshout.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libshout"=.\libshout.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### +