aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2008-05-19 00:47:31 +0000
committerChristian Grothoff <christian@grothoff.org>2008-05-19 00:47:31 +0000
commitd02a81c7f85a6d3bb084092666e74efe4ab86d9d (patch)
treedacf69352fbe4cea85a49a7307b506f2e8426118
parent9d1eb1175cad66e138021713954eb7199a6bd6f1 (diff)
downloadgnunet-gtk-d02a81c7f85a6d3bb084092666e74efe4ab86d9d.tar.gz
gnunet-gtk-d02a81c7f85a6d3bb084092666e74efe4ab86d9d.zip
no libltdl needed
-rw-r--r--ChangeLog4
-rw-r--r--TODO1
-rwxr-xr-xbootstrap3
-rw-r--r--configure.ac10
-rw-r--r--libltdl/COPYING.LIB510
-rw-r--r--libltdl/Makefile.am51
-rw-r--r--libltdl/README10
-rw-r--r--libltdl/config-h.in195
-rw-r--r--libltdl/configure.ac80
-rw-r--r--libltdl/ltdl.c4525
-rw-r--r--libltdl/ltdl.h350
-rw-r--r--ltmain.sh2
12 files changed, 7 insertions, 5734 deletions
diff --git a/ChangeLog b/ChangeLog
index 37e553b6..e74826b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Sun May 18 17:28:43 MDT 2008
2 Removed libltdl tests and directory. We do not need
3 those anymore since we use libgnunetutil anyway.
4
1Sun Mar 2 19:13:39 MST 2008 5Sun Mar 2 19:13:39 MST 2008
2 Releasing gnunet-gtk 0.8.0pre0. 6 Releasing gnunet-gtk 0.8.0pre0.
3 7
diff --git a/TODO b/TODO
index 8e5c5ae1..c0152bb3 100644
--- a/TODO
+++ b/TODO
@@ -8,6 +8,7 @@ Annotations:
8 => need to incorporate into code! 8 => need to incorporate into code!
9- use new search ranking features 9- use new search ranking features
10 => need to implement function in search.c and update tree views/model 10 => need to implement function in search.c and update tree views/model
11- better uritracker support
11- pop-up dialogs / context menus (show extra information, in particular full metadata) [RC] 12- pop-up dialogs / context menus (show extra information, in particular full metadata) [RC]
12- much more testing!!! 13- much more testing!!!
13 14
diff --git a/bootstrap b/bootstrap
index 57648b9e..cffc4978 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,7 +1,4 @@
1#!/bin/sh 1#!/bin/sh
2export MKDIR_P="mkdir -p" 2export MKDIR_P="mkdir -p"
3automake -fi 3automake -fi
4cd libltdl
5autoreconf -f -i
6cd ..
7autoreconf -f -i 4autoreconf -f -i
diff --git a/configure.ac b/configure.ac
index 7ec286fc..dd421a4d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
1# This file is part of GNUnet. 1# This file is part of GNUnet.
2# (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors) 2# (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Christian Grothoff (and other contributing authors)
3# 3#
4# GNUnet is free software; you can redistribute it and/or modify 4# GNUnet is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published 5# it under the terms of the GNU General Public License as published
@@ -42,17 +42,9 @@ AC_PROG_CXX
42AC_HEADER_STDC 42AC_HEADER_STDC
43AC_CANONICAL_HOST 43AC_CANONICAL_HOST
44 44
45
46# dynamic libraries/plugins 45# dynamic libraries/plugins
47AC_LIBTOOL_DLOPEN
48AC_LIBLTDL_INSTALLABLE
49AC_SUBST(LTDLINCL)
50AC_SUBST(LIBLTDL)
51AC_DISABLE_STATIC 46AC_DISABLE_STATIC
52AC_PROG_LIBTOOL 47AC_PROG_LIBTOOL
53AC_LIB_LTDL
54AC_CONFIG_SUBDIRS(libltdl)
55
56 48
57AC_SYS_LARGEFILE 49AC_SYS_LARGEFILE
58AC_FUNC_FSEEKO 50AC_FUNC_FSEEKO
diff --git a/libltdl/COPYING.LIB b/libltdl/COPYING.LIB
deleted file mode 100644
index 0d516d2d..00000000
--- a/libltdl/COPYING.LIB
+++ /dev/null
@@ -1,510 +0,0 @@
1
2 GNU LESSER GENERAL PUBLIC LICENSE
3 Version 2.1, February 1999
4
5 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
6 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7 Everyone is permitted to copy and distribute verbatim copies
8 of this license document, but changing it is not allowed.
9
10[This is the first released version of the Lesser GPL. It also counts
11 as the successor of the GNU Library Public License, version 2, hence
12 the version number 2.1.]
13
14 Preamble
15
16 The licenses for most software are designed to take away your
17freedom to share and change it. By contrast, the GNU General Public
18Licenses are intended to guarantee your freedom to share and change
19free software--to make sure the software is free for all its users.
20
21 This license, the Lesser General Public License, applies to some
22specially designated software packages--typically libraries--of the
23Free Software Foundation and other authors who decide to use it. You
24can use it too, but we suggest you first think carefully about whether
25this license or the ordinary General Public License is the better
26strategy to use in any particular case, based on the explanations
27below.
28
29 When we speak of free software, we are referring to freedom of use,
30not price. Our General Public Licenses are designed to make sure that
31you have the freedom to distribute copies of free software (and charge
32for this service if you wish); that you receive source code or can get
33it if you want it; that you can change the software and use pieces of
34it in new free programs; and that you are informed that you can do
35these things.
36
37 To protect your rights, we need to make restrictions that forbid
38distributors to deny you these rights or to ask you to surrender these
39rights. These restrictions translate to certain responsibilities for
40you if you distribute copies of the library or if you modify it.
41
42 For example, if you distribute copies of the library, whether gratis
43or for a fee, you must give the recipients all the rights that we gave
44you. You must make sure that they, too, receive or can get the source
45code. If you link other code with the library, you must provide
46complete object files to the recipients, so that they can relink them
47with the library after making changes to the library and recompiling
48it. And you must show them these terms so they know their rights.
49
50 We protect your rights with a two-step method: (1) we copyright the
51library, and (2) we offer you this license, which gives you legal
52permission to copy, distribute and/or modify the library.
53
54 To protect each distributor, we want to make it very clear that
55there is no warranty for the free library. Also, if the library is
56modified by someone else and passed on, the recipients should know
57that what they have is not the original version, so that the original
58author's reputation will not be affected by problems that might be
59introduced by others.
60
61 Finally, software patents pose a constant threat to the existence of
62any free program. We wish to make sure that a company cannot
63effectively restrict the users of a free program by obtaining a
64restrictive license from a patent holder. Therefore, we insist that
65any patent license obtained for a version of the library must be
66consistent with the full freedom of use specified in this license.
67
68 Most GNU software, including some libraries, is covered by the
69ordinary GNU General Public License. This license, the GNU Lesser
70General Public License, applies to certain designated libraries, and
71is quite different from the ordinary General Public License. We use
72this license for certain libraries in order to permit linking those
73libraries into non-free programs.
74
75 When a program is linked with a library, whether statically or using
76a shared library, the combination of the two is legally speaking a
77combined work, a derivative of the original library. The ordinary
78General Public License therefore permits such linking only if the
79entire combination fits its criteria of freedom. The Lesser General
80Public License permits more lax criteria for linking other code with
81the library.
82
83 We call this license the "Lesser" General Public License because it
84does Less to protect the user's freedom than the ordinary General
85Public License. It also provides other free software developers Less
86of an advantage over competing non-free programs. These disadvantages
87are the reason we use the ordinary General Public License for many
88libraries. However, the Lesser license provides advantages in certain
89special circumstances.
90
91 For example, on rare occasions, there may be a special need to
92encourage the widest possible use of a certain library, so that it
93becomes a de-facto standard. To achieve this, non-free programs must
94be allowed to use the library. A more frequent case is that a free
95library does the same job as widely used non-free libraries. In this
96case, there is little to gain by limiting the free library to free
97software only, so we use the Lesser General Public License.
98
99 In other cases, permission to use a particular library in non-free
100programs enables a greater number of people to use a large body of
101free software. For example, permission to use the GNU C Library in
102non-free programs enables many more people to use the whole GNU
103operating system, as well as its variant, the GNU/Linux operating
104system.
105
106 Although the Lesser General Public License is Less protective of the
107users' freedom, it does ensure that the user of a program that is
108linked with the Library has the freedom and the wherewithal to run
109that program using a modified version of the Library.
110
111 The precise terms and conditions for copying, distribution and
112modification follow. Pay close attention to the difference between a
113"work based on the library" and a "work that uses the library". The
114former contains code derived from the library, whereas the latter must
115be combined with the library in order to run.
116
117 GNU LESSER GENERAL PUBLIC LICENSE
118 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
119
120 0. This License Agreement applies to any software library or other
121program which contains a notice placed by the copyright holder or
122other authorized party saying it may be distributed under the terms of
123this Lesser General Public License (also called "this License").
124Each licensee is addressed as "you".
125
126 A "library" means a collection of software functions and/or data
127prepared so as to be conveniently linked with application programs
128(which use some of those functions and data) to form executables.
129
130 The "Library", below, refers to any such software library or work
131which has been distributed under these terms. A "work based on the
132Library" means either the Library or any derivative work under
133copyright law: that is to say, a work containing the Library or a
134portion of it, either verbatim or with modifications and/or translated
135straightforwardly into another language. (Hereinafter, translation is
136included without limitation in the term "modification".)
137
138 "Source code" for a work means the preferred form of the work for
139making modifications to it. For a library, complete source code means
140all the source code for all modules it contains, plus any associated
141interface definition files, plus the scripts used to control
142compilation and installation of the library.
143
144 Activities other than copying, distribution and modification are not
145covered by this License; they are outside its scope. The act of
146running a program using the Library is not restricted, and output from
147such a program is covered only if its contents constitute a work based
148on the Library (independent of the use of the Library in a tool for
149writing it). Whether that is true depends on what the Library does
150and what the program that uses the Library does.
151
152 1. You may copy and distribute verbatim copies of the Library's
153complete source code as you receive it, in any medium, provided that
154you conspicuously and appropriately publish on each copy an
155appropriate copyright notice and disclaimer of warranty; keep intact
156all the notices that refer to this License and to the absence of any
157warranty; and distribute a copy of this License along with the
158Library.
159
160 You may charge a fee for the physical act of transferring a copy,
161and you may at your option offer warranty protection in exchange for a
162fee.
163
164 2. You may modify your copy or copies of the Library or any portion
165of it, thus forming a work based on the Library, and copy and
166distribute such modifications or work under the terms of Section 1
167above, provided that you also meet all of these conditions:
168
169 a) The modified work must itself be a software library.
170
171 b) You must cause the files modified to carry prominent notices
172 stating that you changed the files and the date of any change.
173
174 c) You must cause the whole of the work to be licensed at no
175 charge to all third parties under the terms of this License.
176
177 d) If a facility in the modified Library refers to a function or a
178 table of data to be supplied by an application program that uses
179 the facility, other than as an argument passed when the facility
180 is invoked, then you must make a good faith effort to ensure that,
181 in the event an application does not supply such function or
182 table, the facility still operates, and performs whatever part of
183 its purpose remains meaningful.
184
185 (For example, a function in a library to compute square roots has
186 a purpose that is entirely well-defined independent of the
187 application. Therefore, Subsection 2d requires that any
188 application-supplied function or table used by this function must
189 be optional: if the application does not supply it, the square
190 root function must still compute square roots.)
191
192These requirements apply to the modified work as a whole. If
193identifiable sections of that work are not derived from the Library,
194and can be reasonably considered independent and separate works in
195themselves, then this License, and its terms, do not apply to those
196sections when you distribute them as separate works. But when you
197distribute the same sections as part of a whole which is a work based
198on the Library, the distribution of the whole must be on the terms of
199this License, whose permissions for other licensees extend to the
200entire whole, and thus to each and every part regardless of who wrote
201it.
202
203Thus, it is not the intent of this section to claim rights or contest
204your rights to work written entirely by you; rather, the intent is to
205exercise the right to control the distribution of derivative or
206collective works based on the Library.
207
208In addition, mere aggregation of another work not based on the Library
209with the Library (or with a work based on the Library) on a volume of
210a storage or distribution medium does not bring the other work under
211the scope of this License.
212
213 3. You may opt to apply the terms of the ordinary GNU General Public
214License instead of this License to a given copy of the Library. To do
215this, you must alter all the notices that refer to this License, so
216that they refer to the ordinary GNU General Public License, version 2,
217instead of to this License. (If a newer version than version 2 of the
218ordinary GNU General Public License has appeared, then you can specify
219that version instead if you wish.) Do not make any other change in
220these notices.
221
222 Once this change is made in a given copy, it is irreversible for
223that copy, so the ordinary GNU General Public License applies to all
224subsequent copies and derivative works made from that copy.
225
226 This option is useful when you wish to copy part of the code of
227the Library into a program that is not a library.
228
229 4. You may copy and distribute the Library (or a portion or
230derivative of it, under Section 2) in object code or executable form
231under the terms of Sections 1 and 2 above provided that you accompany
232it with the complete corresponding machine-readable source code, which
233must be distributed under the terms of Sections 1 and 2 above on a
234medium customarily used for software interchange.
235
236 If distribution of object code is made by offering access to copy
237from a designated place, then offering equivalent access to copy the
238source code from the same place satisfies the requirement to
239distribute the source code, even though third parties are not
240compelled to copy the source along with the object code.
241
242 5. A program that contains no derivative of any portion of the
243Library, but is designed to work with the Library by being compiled or
244linked with it, is called a "work that uses the Library". Such a
245work, in isolation, is not a derivative work of the Library, and
246therefore falls outside the scope of this License.
247
248 However, linking a "work that uses the Library" with the Library
249creates an executable that is a derivative of the Library (because it
250contains portions of the Library), rather than a "work that uses the
251library". The executable is therefore covered by this License.
252Section 6 states terms for distribution of such executables.
253
254 When a "work that uses the Library" uses material from a header file
255that is part of the Library, the object code for the work may be a
256derivative work of the Library even though the source code is not.
257Whether this is true is especially significant if the work can be
258linked without the Library, or if the work is itself a library. The
259threshold for this to be true is not precisely defined by law.
260
261 If such an object file uses only numerical parameters, data
262structure layouts and accessors, and small macros and small inline
263functions (ten lines or less in length), then the use of the object
264file is unrestricted, regardless of whether it is legally a derivative
265work. (Executables containing this object code plus portions of the
266Library will still fall under Section 6.)
267
268 Otherwise, if the work is a derivative of the Library, you may
269distribute the object code for the work under the terms of Section 6.
270Any executables containing that work also fall under Section 6,
271whether or not they are linked directly with the Library itself.
272
273 6. As an exception to the Sections above, you may also combine or
274link a "work that uses the Library" with the Library to produce a
275work containing portions of the Library, and distribute that work
276under terms of your choice, provided that the terms permit
277modification of the work for the customer's own use and reverse
278engineering for debugging such modifications.
279
280 You must give prominent notice with each copy of the work that the
281Library is used in it and that the Library and its use are covered by
282this License. You must supply a copy of this License. If the work
283during execution displays copyright notices, you must include the
284copyright notice for the Library among them, as well as a reference
285directing the user to the copy of this License. Also, you must do one
286of these things:
287
288 a) Accompany the work with the complete corresponding
289 machine-readable source code for the Library including whatever
290 changes were used in the work (which must be distributed under
291 Sections 1 and 2 above); and, if the work is an executable linked
292 with the Library, with the complete machine-readable "work that
293 uses the Library", as object code and/or source code, so that the
294 user can modify the Library and then relink to produce a modified
295 executable containing the modified Library. (It is understood
296 that the user who changes the contents of definitions files in the
297 Library will not necessarily be able to recompile the application
298 to use the modified definitions.)
299
300 b) Use a suitable shared library mechanism for linking with the
301 Library. A suitable mechanism is one that (1) uses at run time a
302 copy of the library already present on the user's computer system,
303 rather than copying library functions into the executable, and (2)
304 will operate properly with a modified version of the library, if
305 the user installs one, as long as the modified version is
306 interface-compatible with the version that the work was made with.
307
308 c) Accompany the work with a written offer, valid for at least
309 three years, to give the same user the materials specified in
310 Subsection 6a, above, for a charge no more than the cost of
311 performing this distribution.
312
313 d) If distribution of the work is made by offering access to copy
314 from a designated place, offer equivalent access to copy the above
315 specified materials from the same place.
316
317 e) Verify that the user has already received a copy of these
318 materials or that you have already sent this user a copy.
319
320 For an executable, the required form of the "work that uses the
321Library" must include any data and utility programs needed for
322reproducing the executable from it. However, as a special exception,
323the materials to be distributed need not include anything that is
324normally distributed (in either source or binary form) with the major
325components (compiler, kernel, and so on) of the operating system on
326which the executable runs, unless that component itself accompanies
327the executable.
328
329 It may happen that this requirement contradicts the license
330restrictions of other proprietary libraries that do not normally
331accompany the operating system. Such a contradiction means you cannot
332use both them and the Library together in an executable that you
333distribute.
334
335 7. You may place library facilities that are a work based on the
336Library side-by-side in a single library together with other library
337facilities not covered by this License, and distribute such a combined
338library, provided that the separate distribution of the work based on
339the Library and of the other library facilities is otherwise
340permitted, and provided that you do these two things:
341
342 a) Accompany the combined library with a copy of the same work
343 based on the Library, uncombined with any other library
344 facilities. This must be distributed under the terms of the
345 Sections above.
346
347 b) Give prominent notice with the combined library of the fact
348 that part of it is a work based on the Library, and explaining
349 where to find the accompanying uncombined form of the same work.
350
351 8. You may not copy, modify, sublicense, link with, or distribute
352the Library except as expressly provided under this License. Any
353attempt otherwise to copy, modify, sublicense, link with, or
354distribute the Library is void, and will automatically terminate your
355rights under this License. However, parties who have received copies,
356or rights, from you under this License will not have their licenses
357terminated so long as such parties remain in full compliance.
358
359 9. You are not required to accept this License, since you have not
360signed it. However, nothing else grants you permission to modify or
361distribute the Library or its derivative works. These actions are
362prohibited by law if you do not accept this License. Therefore, by
363modifying or distributing the Library (or any work based on the
364Library), you indicate your acceptance of this License to do so, and
365all its terms and conditions for copying, distributing or modifying
366the Library or works based on it.
367
368 10. Each time you redistribute the Library (or any work based on the
369Library), the recipient automatically receives a license from the
370original licensor to copy, distribute, link with or modify the Library
371subject to these terms and conditions. You may not impose any further
372restrictions on the recipients' exercise of the rights granted herein.
373You are not responsible for enforcing compliance by third parties with
374this License.
375
376 11. If, as a consequence of a court judgment or allegation of patent
377infringement or for any other reason (not limited to patent issues),
378conditions are imposed on you (whether by court order, agreement or
379otherwise) that contradict the conditions of this License, they do not
380excuse you from the conditions of this License. If you cannot
381distribute so as to satisfy simultaneously your obligations under this
382License and any other pertinent obligations, then as a consequence you
383may not distribute the Library at all. For example, if a patent
384license would not permit royalty-free redistribution of the Library by
385all those who receive copies directly or indirectly through you, then
386the only way you could satisfy both it and this License would be to
387refrain entirely from distribution of the Library.
388
389If any portion of this section is held invalid or unenforceable under
390any particular circumstance, the balance of the section is intended to
391apply, and the section as a whole is intended to apply in other
392circumstances.
393
394It is not the purpose of this section to induce you to infringe any
395patents or other property right claims or to contest validity of any
396such claims; this section has the sole purpose of protecting the
397integrity of the free software distribution system which is
398implemented by public license practices. Many people have made
399generous contributions to the wide range of software distributed
400through that system in reliance on consistent application of that
401system; it is up to the author/donor to decide if he or she is willing
402to distribute software through any other system and a licensee cannot
403impose that choice.
404
405This section is intended to make thoroughly clear what is believed to
406be a consequence of the rest of this License.
407
408 12. If the distribution and/or use of the Library is restricted in
409certain countries either by patents or by copyrighted interfaces, the
410original copyright holder who places the Library under this License
411may add an explicit geographical distribution limitation excluding those
412countries, so that distribution is permitted only in or among
413countries not thus excluded. In such case, this License incorporates
414the limitation as if written in the body of this License.
415
416 13. The Free Software Foundation may publish revised and/or new
417versions of the Lesser General Public License from time to time.
418Such new versions will be similar in spirit to the present version,
419but may differ in detail to address new problems or concerns.
420
421Each version is given a distinguishing version number. If the Library
422specifies a version number of this License which applies to it and
423"any later version", you have the option of following the terms and
424conditions either of that version or of any later version published by
425the Free Software Foundation. If the Library does not specify a
426license version number, you may choose any version ever published by
427the Free Software Foundation.
428
429 14. If you wish to incorporate parts of the Library into other free
430programs whose distribution conditions are incompatible with these,
431write to the author to ask for permission. For software which is
432copyrighted by the Free Software Foundation, write to the Free
433Software Foundation; we sometimes make exceptions for this. Our
434decision will be guided by the two goals of preserving the free status
435of all derivatives of our free software and of promoting the sharing
436and reuse of software generally.
437
438 NO WARRANTY
439
440 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
441WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
442EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
443OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
444KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
445IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
446PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
447LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
448THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
449
450 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
451WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
452AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
453FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
454CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
455LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
456RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
457FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
458SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
459DAMAGES.
460
461 END OF TERMS AND CONDITIONS
462
463 How to Apply These Terms to Your New Libraries
464
465 If you develop a new library, and you want it to be of the greatest
466possible use to the public, we recommend making it free software that
467everyone can redistribute and change. You can do so by permitting
468redistribution under these terms (or, alternatively, under the terms
469of the ordinary General Public License).
470
471 To apply these terms, attach the following notices to the library.
472It is safest to attach them to the start of each source file to most
473effectively convey the exclusion of warranty; and each file should
474have at least the "copyright" line and a pointer to where the full
475notice is found.
476
477
478 <one line to give the library's name and a brief idea of what it does.>
479 Copyright (C) <year> <name of author>
480
481 This library is free software; you can redistribute it and/or
482 modify it under the terms of the GNU Lesser General Public
483 License as published by the Free Software Foundation; either
484 version 2.1 of the License, or (at your option) any later version.
485
486 This library is distributed in the hope that it will be useful,
487 but WITHOUT ANY WARRANTY; without even the implied warranty of
488 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
489 Lesser General Public License for more details.
490
491 You should have received a copy of the GNU Lesser General Public
492 License along with this library; if not, write to the Free Software
493 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
494
495Also add information on how to contact you by electronic and paper mail.
496
497You should also get your employer (if you work as a programmer) or
498your school, if any, to sign a "copyright disclaimer" for the library,
499if necessary. Here is a sample; alter the names:
500
501 Yoyodyne, Inc., hereby disclaims all copyright interest in the
502 library `Frob' (a library for tweaking knobs) written by James
503 Random Hacker.
504
505 <signature of Ty Coon>, 1 April 1990
506 Ty Coon, President of Vice
507
508That's all there is to it!
509
510
diff --git a/libltdl/Makefile.am b/libltdl/Makefile.am
deleted file mode 100644
index 9b560285..00000000
--- a/libltdl/Makefile.am
+++ /dev/null
@@ -1,51 +0,0 @@
1## Process this file with automake to produce Makefile.in
2
3AUTOMAKE_OPTIONS = no-dependencies foreign
4
5if INSTALL_LTDL
6include_HEADERS = ltdl.h
7lib_LTLIBRARIES = libltdl.la
8else
9noinst_HEADERS = ltdl.h
10endif
11
12if CONVENIENCE_LTDL
13noinst_LTLIBRARIES = libltdlc.la
14endif
15
16## Make sure these will be cleaned even when they're not built by
17## default.
18CLEANFILES = libltdl.la libltdlc.la
19
20libltdl_la_SOURCES = ltdl.c
21libltdl_la_LDFLAGS = -no-undefined -version-info 4:0:1
22libltdl_la_LIBADD = $(LIBADD_DL)
23
24libltdlc_la_SOURCES = ltdl.c
25libltdlc_la_LIBADD = $(LIBADD_DL)
26
27## Because we do not have automatic dependency tracking:
28ltdl.lo: ltdl.h config.h
29
30$(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS): libtool
31libtool: $(LIBTOOL_DEPS)
32 $(SHELL) ./config.status --recheck
33
34## This allows us to install libltdl without using ln and without creating
35## a world writeable directory.
36## FIXME: Remove this rule once automake can do this properly by itself.
37local-install-files: $(DISTFILES)
38 -rm -rf $(DESTDIR)$(datadir)/libtool/libltdl
39 $(mkinstalldirs) $(DESTDIR)$(datadir)/libtool/libltdl
40 @for file in $(DISTFILES); do \
41 case $$file in \
42 $(srcdir)/*) file=`echo "$$file" | sed "s|^$(srcdir)/||"`;; \
43 esac; \
44 d=$(srcdir); \
45 if test -d $$d/$$file; then \
46 cp -r $$d/$$file $(DESTDIR)$(datadir)/libtool/libltdl/$$file; \
47 else \
48 test -f $(DESTDIR)$(datadir)/libtool/libltdl/$$file \
49 || cp $$d/$$file $(DESTDIR)$(datadir)/libtool/libltdl/$$file || :; \
50 fi; \
51 done
diff --git a/libltdl/README b/libltdl/README
deleted file mode 100644
index da0a449c..00000000
--- a/libltdl/README
+++ /dev/null
@@ -1,10 +0,0 @@
1This is GNU libltdl, a system independent dlopen wrapper for GNU libtool.
2
3It supports the following dlopen interfaces:
4* dlopen (Solaris, Linux and various BSD flavors)
5* shl_load (HP-UX)
6* LoadLibrary (Win16 and Win32)
7* load_add_on (BeOS)
8* GNU DLD (emulates dynamic linking for static libraries)
9* dyld (darwin/Mac OS X)
10* libtool's dlpreopen
diff --git a/libltdl/config-h.in b/libltdl/config-h.in
deleted file mode 100644
index b8640710..00000000
--- a/libltdl/config-h.in
+++ /dev/null
@@ -1,195 +0,0 @@
1/* config-h.in. Generated from configure.ac by autoheader. */
2
3/* Define to 1 if you have the `argz_append' function. */
4#undef HAVE_ARGZ_APPEND
5
6/* Define to 1 if you have the `argz_create_sep' function. */
7#undef HAVE_ARGZ_CREATE_SEP
8
9/* Define to 1 if you have the <argz.h> header file. */
10#undef HAVE_ARGZ_H
11
12/* Define to 1 if you have the `argz_insert' function. */
13#undef HAVE_ARGZ_INSERT
14
15/* Define to 1 if you have the `argz_next' function. */
16#undef HAVE_ARGZ_NEXT
17
18/* Define to 1 if you have the `argz_stringify' function. */
19#undef HAVE_ARGZ_STRINGIFY
20
21/* Define to 1 if you have the <assert.h> header file. */
22#undef HAVE_ASSERT_H
23
24/* Define to 1 if you have the `bcopy' function. */
25#undef HAVE_BCOPY
26
27/* Define to 1 if you have the `closedir' function. */
28#undef HAVE_CLOSEDIR
29
30/* Define to 1 if you have the <ctype.h> header file. */
31#undef HAVE_CTYPE_H
32
33/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
34 */
35#undef HAVE_DIRENT_H
36
37/* Define if you have the GNU dld library. */
38#undef HAVE_DLD
39
40/* Define to 1 if you have the <dld.h> header file. */
41#undef HAVE_DLD_H
42
43/* Define to 1 if you have the `dlerror' function. */
44#undef HAVE_DLERROR
45
46/* Define to 1 if you have the <dlfcn.h> header file. */
47#undef HAVE_DLFCN_H
48
49/* Define to 1 if you have the <dl.h> header file. */
50#undef HAVE_DL_H
51
52/* Define if you have the _dyld_func_lookup function. */
53#undef HAVE_DYLD
54
55/* Define to 1 if you have the <errno.h> header file. */
56#undef HAVE_ERRNO_H
57
58/* Define to 1 if the system has the type `error_t'. */
59#undef HAVE_ERROR_T
60
61/* Define to 1 if you have the `index' function. */
62#undef HAVE_INDEX
63
64/* Define to 1 if you have the <inttypes.h> header file. */
65#undef HAVE_INTTYPES_H
66
67/* Define if you have the libdl library or equivalent. */
68#undef HAVE_LIBDL
69
70/* Define to 1 if you have the <mach-o/dyld.h> header file. */
71#undef HAVE_MACH_O_DYLD_H
72
73/* Define to 1 if you have the <malloc.h> header file. */
74#undef HAVE_MALLOC_H
75
76/* Define to 1 if you have the `memcpy' function. */
77#undef HAVE_MEMCPY
78
79/* Define to 1 if you have the `memmove' function. */
80#undef HAVE_MEMMOVE
81
82/* Define to 1 if you have the <memory.h> header file. */
83#undef HAVE_MEMORY_H
84
85/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
86#undef HAVE_NDIR_H
87
88/* Define to 1 if you have the `opendir' function. */
89#undef HAVE_OPENDIR
90
91/* Define if libtool can extract symbol lists from object files. */
92#undef HAVE_PRELOADED_SYMBOLS
93
94/* Define to 1 if you have the `readdir' function. */
95#undef HAVE_READDIR
96
97/* Define to 1 if you have the `rindex' function. */
98#undef HAVE_RINDEX
99
100/* Define if you have the shl_load function. */
101#undef HAVE_SHL_LOAD
102
103/* Define to 1 if you have the <stdint.h> header file. */
104#undef HAVE_STDINT_H
105
106/* Define to 1 if you have the <stdio.h> header file. */
107#undef HAVE_STDIO_H
108
109/* Define to 1 if you have the <stdlib.h> header file. */
110#undef HAVE_STDLIB_H
111
112/* Define to 1 if you have the `strchr' function. */
113#undef HAVE_STRCHR
114
115/* Define to 1 if you have the `strcmp' function. */
116#undef HAVE_STRCMP
117
118/* Define to 1 if you have the <strings.h> header file. */
119#undef HAVE_STRINGS_H
120
121/* Define to 1 if you have the <string.h> header file. */
122#undef HAVE_STRING_H
123
124/* Define to 1 if you have the `strrchr' function. */
125#undef HAVE_STRRCHR
126
127/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
128 */
129#undef HAVE_SYS_DIR_H
130
131/* Define to 1 if you have the <sys/dl.h> header file. */
132#undef HAVE_SYS_DL_H
133
134/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
135 */
136#undef HAVE_SYS_NDIR_H
137
138/* Define to 1 if you have the <sys/stat.h> header file. */
139#undef HAVE_SYS_STAT_H
140
141/* Define to 1 if you have the <sys/types.h> header file. */
142#undef HAVE_SYS_TYPES_H
143
144/* Define to 1 if you have the <unistd.h> header file. */
145#undef HAVE_UNISTD_H
146
147/* Define if the OS needs help to load dependent libraries for dlopen(). */
148#undef LTDL_DLOPEN_DEPLIBS
149
150/* Define to the sub-directory in which libtool stores uninstalled libraries.
151 */
152#undef LTDL_OBJDIR
153
154/* Define to the name of the environment variable that determines the dynamic
155 library search path. */
156#undef LTDL_SHLIBPATH_VAR
157
158/* Define to the extension used for shared libraries, say, ".so". */
159#undef LTDL_SHLIB_EXT
160
161/* Define to the system default library search path. */
162#undef LTDL_SYSSEARCHPATH
163
164/* Define if dlsym() requires a leading underscore in symbol names. */
165#undef NEED_USCORE
166
167/* Define to the address where bug reports for this package should be sent. */
168#undef PACKAGE_BUGREPORT
169
170/* Define to the full name of this package. */
171#undef PACKAGE_NAME
172
173/* Define to the full name and version of this package. */
174#undef PACKAGE_STRING
175
176/* Define to the one symbol short name of this package. */
177#undef PACKAGE_TARNAME
178
179/* Define to the version of this package. */
180#undef PACKAGE_VERSION
181
182/* Define to 1 if you have the ANSI C header files. */
183#undef STDC_HEADERS
184
185/* Define to empty if `const' does not conform to ANSI C. */
186#undef const
187
188/* Define to a type to use for `error_t' if it is not otherwise available. */
189#undef error_t
190
191/* Define to `__inline__' or `__inline' if that's what the C compiler
192 calls it, or to nothing if 'inline' is not supported under any name. */
193#ifndef __cplusplus
194#undef inline
195#endif
diff --git a/libltdl/configure.ac b/libltdl/configure.ac
deleted file mode 100644
index 56c9f237..00000000
--- a/libltdl/configure.ac
+++ /dev/null
@@ -1,80 +0,0 @@
1## Process this file with autoconf to create configure. -*- autoconf -*-
2# Copyright 2001 Free Software Foundation, Inc.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17# 02111-1307 USA
18
19
20## FIXME: Is this really new enough? ##
21AC_PREREQ(2.50)
22
23
24## ------------------------ ##
25## Autoconf initialisation. ##
26## ------------------------ ##
27AC_INIT([libltdl], [1.2], [bug-libtool@gnu.org])
28AC_CONFIG_SRCDIR([ltdl.c])
29
30
31## ------------------------------- ##
32## Libltdl specific configuration. ##
33## ------------------------------- ##
34
35AC_CONFIG_AUX_DIR([.])
36
37if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
38 if test -f ${srcdir}/ltmain.sh; then
39 # if libltdl is libtoolized, it is assumed to be stand-alone and
40 # installed unless the command line overrides it (tested above)
41 enable_ltdl_install=yes
42 else
43 AC_MSG_WARN([*** The top-level configure must select either])
44 AC_MSG_WARN([*** [A""C_LIBLTDL_INSTALLABLE] or [A""C_LIBLTDL_CONVENIENCE].])
45 AC_MSG_ERROR([*** Maybe you want to --enable-ltdl-install?])
46 fi
47fi
48
49
50## ------------------------ ##
51## Automake Initialisation. ##
52## ------------------------ ##
53AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, -)
54AM_CONFIG_HEADER([config.h:config-h.in])
55AM_MAINTAINER_MODE
56
57
58## ------------------ ##
59## C compiler checks. ##
60## ------------------ ##
61AC_PROG_CC
62AC_C_CONST
63AC_C_INLINE
64
65
66## ----------------------- ##
67## Libtool initialisation. ##
68## ----------------------- ##
69AC_LIBTOOL_WIN32_DLL
70AC_PROG_LIBTOOL
71AC_SUBST([LIBTOOL_DEPS])
72
73AC_LIB_LTDL
74
75
76## -------- ##
77## Outputs. ##
78## -------- ##
79AC_CONFIG_FILES([Makefile])
80AC_OUTPUT
diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c
deleted file mode 100644
index 68037d23..00000000
--- a/libltdl/ltdl.c
+++ /dev/null
@@ -1,4525 +0,0 @@
1/* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
5
6This library is free software; you can redistribute it and/or
7modify it under the terms of the GNU Lesser General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11As a special exception to the GNU Lesser General Public License,
12if you distribute this file as part of a program or library that
13is built using GNU libtool, you may include it under the same
14distribution terms that you use for the rest of that program.
15
16This library is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public
22License along with this library; if not, write to the Free Software
23Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2402111-1307 USA
25
26*/
27
28#if HAVE_CONFIG_H
29# include <config.h>
30#endif
31
32#if HAVE_UNISTD_H
33# include <unistd.h>
34#endif
35
36#if HAVE_STDIO_H
37# include <stdio.h>
38#endif
39
40/* Include the header defining malloc. On K&R C compilers,
41 that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
42#if HAVE_STDLIB_H
43# include <stdlib.h>
44#else
45# if HAVE_GNUNET_malloc_H
46# include <malloc.h>
47# endif
48#endif
49
50#if HAVE_STRING_H
51# include <string.h>
52#else
53# if HAVE_STRINGS_H
54# include <strings.h>
55# endif
56#endif
57
58#if HAVE_CTYPE_H
59# include <ctype.h>
60#endif
61
62#if HAVE_MEMORY_H
63# include <memory.h>
64#endif
65
66#if HAVE_ERRNO_H
67# include <errno.h>
68#endif
69
70
71#ifndef __WINDOWS__
72# ifdef __WIN32__
73# define __WINDOWS__
74# endif
75#endif
76
77
78#undef LT_USE_POSIX_DIRENT
79#ifdef HAVE_CLOSEDIR
80# ifdef HAVE_OPENDIR
81# ifdef HAVE_READDIR
82# ifdef HAVE_DIRENT_H
83# define LT_USE_POSIX_DIRENT
84# endif /* HAVE_DIRENT_H */
85# endif /* HAVE_READDIR */
86# endif /* HAVE_OPENDIR */
87#endif /* HAVE_CLOSEDIR */
88
89
90#undef LT_USE_WINDOWS_DIRENT_EMULATION
91#ifndef LT_USE_POSIX_DIRENT
92# ifdef __WINDOWS__
93# define LT_USE_WINDOWS_DIRENT_EMULATION
94# endif /* __WINDOWS__ */
95#endif /* LT_USE_POSIX_DIRENT */
96
97
98#ifdef LT_USE_POSIX_DIRENT
99# include <dirent.h>
100# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
101#else
102# ifdef LT_USE_WINDOWS_DIRENT_EMULATION
103# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
104# else
105# define dirent direct
106# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
107# if HAVE_SYS_NDIR_H
108# include <sys/ndir.h>
109# endif
110# if HAVE_SYS_DIR_H
111# include <sys/dir.h>
112# endif
113# if HAVE_NDIR_H
114# include <ndir.h>
115# endif
116# endif
117#endif
118
119#if HAVE_ARGZ_H
120# include <argz.h>
121#endif
122
123#if HAVE_ASSERT_H
124# include <assert.h>
125#else
126# define assert(arg) ((void) 0)
127#endif
128
129#include "ltdl.h"
130
131#if WITH_DGNUNET_malloc
132# include <dmalloc.h>
133#endif
134
135
136
137
138/* --- WINDOWS SUPPORT --- */
139
140
141#ifdef DLL_EXPORT
142# define LT_GLOBAL_DATA __declspec(dllexport)
143#else
144# define LT_GLOBAL_DATA
145#endif
146
147/* fopen() mode flags for reading a text file */
148#undef LT_READTEXT_MODE
149#ifdef __WINDOWS__
150# define LT_READTEXT_MODE "rt"
151#else
152# define LT_READTEXT_MODE "r"
153#endif
154
155#ifdef LT_USE_WINDOWS_DIRENT_EMULATION
156
157#include <windows.h>
158
159#define dirent lt_dirent
160#define DIR lt_DIR
161
162struct dirent
163{
164 char d_name[2048];
165 int d_namlen;
166};
167
168typedef struct _DIR
169{
170 HANDLE hSearch;
171 WIN32_FIND_DATA Win32FindData;
172 BOOL firsttime;
173 struct dirent file_info;
174} DIR;
175
176#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
177
178
179/* --- MANIFEST CONSTANTS --- */
180
181
182/* Standard libltdl search path environment variable name */
183#undef LTDL_SEARCHPATH_VAR
184#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
185
186/* Standard libtool archive file extension. */
187#undef LTDL_ARCHIVE_EXT
188#define LTDL_ARCHIVE_EXT ".la"
189
190/* max. filename length */
191#ifndef LT_FILENAME_MAX
192# define LT_FILENAME_MAX 1024
193#endif
194
195/* This is the maximum symbol size that won't require malloc/free */
196#undef LT_SYMBOL_LENGTH
197#define LT_SYMBOL_LENGTH 128
198
199/* This accounts for the _LTX_ separator */
200#undef LT_SYMBOL_OVERHEAD
201#define LT_SYMBOL_OVERHEAD 5
202
203
204
205
206/* --- MEMORY HANDLING --- */
207
208
209/* These are the functions used internally. In addition to making
210 use of the associated function pointers above, they also perform
211 error handling. */
212static char *lt_estrdup LT_PARAMS ((const char *str));
213static lt_ptr lt_emalloc LT_PARAMS ((size_t size));
214static lt_ptr lt_erealloc LT_PARAMS ((lt_ptr addr, size_t size));
215
216/* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
217#define rpl_realloc realloc
218
219/* These are the pointers that can be changed by the caller: */
220LT_GLOBAL_DATA
221lt_ptr (*lt_dlmalloc)
222LT_PARAMS ((size_t size)) = (lt_ptr (*)LT_PARAMS ((size_t))) malloc;
223 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)
224 LT_PARAMS ((lt_ptr ptr, size_t size)) =
225 (lt_ptr (*)LT_PARAMS ((lt_ptr, size_t))) rpl_realloc;
226 LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS ((lt_ptr ptr)) =
227 (void (*)LT_PARAMS ((lt_ptr))) free;
228
229/* The following macros reduce the amount of typing needed to cast
230 assigned memory. */
231#if WITH_DGNUNET_malloc
232
233#define LT_DLGNUNET_malloc(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
234#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
235#define LT_DLGNUNET_free(p) \
236 LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
237
238#define LT_EGNUNET_malloc(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
239#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
240
241#else
242
243#define LT_DLGNUNET_malloc(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
244#define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
245#define LT_DLGNUNET_free(p) \
246 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
247
248#define LT_EGNUNET_malloc(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
249#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
250
251#endif
252
253#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
254 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
255 } LT_STMT_END
256
257
258/* --- REPLACEMENT FUNCTIONS --- */
259
260
261#undef strdup
262#define strdup rpl_strdup
263
264 static char *strdup LT_PARAMS ((const char *str));
265
266 static char *strdup (str)
267 const char *str;
268{
269 char *tmp = 0;
270
271 if (str)
272 {
273 tmp = LT_DLGNUNET_malloc (char, 1 + strlen (str));
274 if (tmp)
275 {
276 strcpy (tmp, str);
277 }
278 }
279
280 return tmp;
281}
282
283
284#if ! HAVE_STRCMP
285
286#undef strcmp
287#define strcmp rpl_strcmp
288
289static int strcmp LT_PARAMS ((const char *str1, const char *str2));
290
291static int
292strcmp (str1, str2)
293 const char *str1;
294 const char *str2;
295{
296 if (str1 == str2)
297 return 0;
298 if (str1 == 0)
299 return -1;
300 if (str2 == 0)
301 return 1;
302
303 for (; *str1 && *str2; ++str1, ++str2)
304 {
305 if (*str1 != *str2)
306 break;
307 }
308
309 return (int) (*str1 - *str2);
310}
311#endif
312
313
314#if ! HAVE_STRCHR
315
316# if HAVE_INDEX
317# define strchr index
318# else
319# define strchr rpl_strchr
320
321static const char *strchr LT_PARAMS ((const char *str, int ch));
322
323static const char *
324strchr (str, ch)
325 const char *str;
326 int ch;
327{
328 const char *p;
329
330 for (p = str; *p != (char) ch && *p != LT_EOS_CHAR; ++p)
331 /*NOWORK*/;
332
333 return (*p == (char) ch) ? p : 0;
334}
335
336# endif
337#endif /* !HAVE_STRCHR */
338
339
340#if ! HAVE_STRRCHR
341
342# if HAVE_RINDEX
343# define strrchr rindex
344# else
345# define strrchr rpl_strrchr
346
347static const char *strrchr LT_PARAMS ((const char *str, int ch));
348
349static const char *
350strrchr (str, ch)
351 const char *str;
352 int ch;
353{
354 const char *p, *q = 0;
355
356 for (p = str; *p != LT_EOS_CHAR; ++p)
357 {
358 if (*p == (char) ch)
359 {
360 q = p;
361 }
362 }
363
364 return q;
365}
366
367# endif
368#endif
369
370/* NOTE: Neither bcopy nor the memcpy implementation below can
371 reliably handle copying in overlapping areas of memory. Use
372 memmove (for which there is a fallback implmentation below)
373 if you need that behaviour. */
374#if ! HAVE_MEMCPY
375
376# if HAVE_BCOPY
377# define memcpy(dest, src, size) bcopy (src, dest, size)
378# else
379# define memcpy rpl_memcpy
380
381static lt_ptr memcpy LT_PARAMS ((lt_ptr dest, const lt_ptr src, size_t size));
382
383static lt_ptr
384memcpy (dest, src, size)
385 lt_ptr dest;
386 const lt_ptr src;
387 size_t size;
388{
389 size_t i = 0;
390
391 for (i = 0; i < size; ++i)
392 {
393 dest[i] = src[i];
394 }
395
396 return dest;
397}
398
399# endif /* !HAVE_BCOPY */
400#endif /* !HAVE_MEMCPY */
401
402#if ! HAVE_MEMMOVE
403# define memmove rpl_memmove
404
405static lt_ptr memmove
406LT_PARAMS ((lt_ptr dest, const lt_ptr src, size_t size));
407
408static lt_ptr
409memmove (dest, src, size)
410 lt_ptr dest;
411 const lt_ptr src;
412 size_t size;
413{
414 size_t i;
415
416 if (dest < src)
417 for (i = 0; i < size; ++i)
418 {
419 dest[i] = src[i];
420 }
421 else if (dest > src)
422 for (i = size - 1; i >= 0; --i)
423 {
424 dest[i] = src[i];
425 }
426
427 return dest;
428}
429
430#endif /* !HAVE_MEMMOVE */
431
432#ifdef LT_USE_WINDOWS_DIRENT_EMULATION
433
434static void closedir LT_PARAMS ((DIR * entry));
435
436static void
437closedir (entry)
438 DIR *entry;
439{
440 assert (entry != (DIR *) NULL);
441 FindClose (entry->hSearch);
442 lt_dlfree ((lt_ptr) entry);
443}
444
445
446static DIR *opendir LT_PARAMS ((const char *path));
447
448static DIR *
449opendir (path)
450 const char *path;
451{
452 char file_specification[LT_FILENAME_MAX];
453 DIR *entry;
454
455 assert (path != (char *) NULL);
456 (void) strncpy (file_specification, path, LT_FILENAME_MAX - 1);
457 (void) strcat (file_specification, "\\");
458 entry = LT_DLGNUNET_malloc (DIR, sizeof (DIR));
459 if (entry != (DIR *) 0)
460 {
461 entry->firsttime = TRUE;
462 entry->hSearch =
463 FindFirstFile (file_specification, &entry->Win32FindData);
464 }
465 if (entry->hSearch == INVALID_HANDLE_VALUE)
466 {
467 (void) strcat (file_specification, "\\*.*");
468 entry->hSearch =
469 FindFirstFile (file_specification, &entry->Win32FindData);
470 if (entry->hSearch == INVALID_HANDLE_VALUE)
471 {
472 LT_DLGNUNET_free (entry);
473 return (DIR *) 0;
474 }
475 }
476 return (entry);
477}
478
479
480static struct dirent *readdir LT_PARAMS ((DIR * entry));
481
482static struct dirent *
483readdir (entry)
484 DIR *entry;
485{
486 int status;
487
488 if (entry == (DIR *) 0)
489 return ((struct dirent *) 0);
490 if (!entry->firsttime)
491 {
492 status = FindNextFile (entry->hSearch, &entry->Win32FindData);
493 if (status == 0)
494 return ((struct dirent *) 0);
495 }
496 entry->firsttime = FALSE;
497 (void) strncpy (entry->file_info.d_name, entry->Win32FindData.cFileName,
498 LT_FILENAME_MAX - 1);
499 entry->file_info.d_namlen = strlen (entry->file_info.d_name);
500 return (&entry->file_info);
501}
502
503#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
504
505/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
506 ``realloc is not entirely portable''
507 In any case we want to use the allocator supplied by the user without
508 burdening them with an lt_dlrealloc function pointer to maintain.
509 Instead implement our own version (with known boundary conditions)
510 using lt_dlmalloc and lt_dlfree. */
511
512/* #undef realloc
513 #define realloc rpl_realloc
514*/
515#if 0
516 /* You can't (re)define realloc unless you also (re)define malloc.
517 Right now, this code uses the size of the *destination* to decide
518 how much to copy. That's not right, but you can't know the size
519 of the source unless you know enough about, or wrote malloc. So
520 this code is disabled... */
521
522static lt_ptr
523realloc (ptr, size)
524 lt_ptr ptr;
525 size_t size;
526{
527 if (size == 0)
528 {
529 /* For zero or less bytes, free the original memory */
530 if (ptr != 0)
531 {
532 lt_dlfree (ptr);
533 }
534
535 return (lt_ptr) 0;
536 }
537 else if (ptr == 0)
538 {
539 /* Allow reallocation of a NULL pointer. */
540 return lt_dlmalloc (size);
541 }
542 else
543 {
544 /* Allocate a new block, copy and free the old block. */
545 lt_ptr mem = lt_dlmalloc (size);
546
547 if (mem)
548 {
549 memcpy (mem, ptr, size);
550 lt_dlfree (ptr);
551 }
552
553 /* Note that the contents of PTR are not damaged if there is
554 insufficient memory to realloc. */
555 return mem;
556 }
557}
558#endif
559
560
561#if ! HAVE_ARGZ_APPEND
562# define argz_append rpl_argz_append
563
564static error_t argz_append LT_PARAMS ((char **pargz, size_t * pargz_len,
565 const char *buf, size_t buf_len));
566
567static error_t
568argz_append (pargz, pargz_len, buf, buf_len)
569 char **pargz;
570 size_t *pargz_len;
571 const char *buf;
572 size_t buf_len;
573{
574 size_t argz_len;
575 char *argz;
576
577 assert (pargz);
578 assert (pargz_len);
579 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
580
581 /* If nothing needs to be appended, no more work is required. */
582 if (buf_len == 0)
583 return 0;
584
585 /* Ensure there is enough room to append BUF_LEN. */
586 argz_len = *pargz_len + buf_len;
587 argz = LT_DLREALLOC (char, *pargz, argz_len);
588 if (!argz)
589 return ENOMEM;
590
591 /* Copy characters from BUF after terminating '\0' in ARGZ. */
592 memcpy (argz + *pargz_len, buf, buf_len);
593
594 /* Assign new values. */
595 *pargz = argz;
596 *pargz_len = argz_len;
597
598 return 0;
599}
600#endif /* !HAVE_ARGZ_APPEND */
601
602
603#if ! HAVE_ARGZ_CREATE_SEP
604# define argz_create_sep rpl_argz_create_sep
605
606static error_t argz_create_sep LT_PARAMS ((const char *str, int delim,
607 char **pargz, size_t * pargz_len));
608
609static error_t
610argz_create_sep (str, delim, pargz, pargz_len)
611 const char *str;
612 int delim;
613 char **pargz;
614 size_t *pargz_len;
615{
616 size_t argz_len;
617 char *argz = 0;
618
619 assert (str);
620 assert (pargz);
621 assert (pargz_len);
622
623 /* Make a copy of STR, but replacing each occurence of
624 DELIM with '\0'. */
625 argz_len = 1 + LT_STRLEN (str);
626 if (argz_len)
627 {
628 const char *p;
629 char *q;
630
631 argz = LT_DLGNUNET_malloc (char, argz_len);
632 if (!argz)
633 return ENOMEM;
634
635 for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
636 {
637 if (*p == delim)
638 {
639 /* Ignore leading delimiters, and fold consecutive
640 delimiters in STR into a single '\0' in ARGZ. */
641 if ((q > argz) && (q[-1] != LT_EOS_CHAR))
642 *q++ = LT_EOS_CHAR;
643 else
644 --argz_len;
645 }
646 else
647 *q++ = *p;
648 }
649 /* Copy terminating LT_EOS_CHAR. */
650 *q = *p;
651 }
652
653 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
654 if (!argz_len)
655 LT_DLGNUNET_free (argz);
656
657 /* Assign new values. */
658 *pargz = argz;
659 *pargz_len = argz_len;
660
661 return 0;
662}
663#endif /* !HAVE_ARGZ_CREATE_SEP */
664
665
666#if ! HAVE_ARGZ_INSERT
667# define argz_insert rpl_argz_insert
668
669static error_t argz_insert LT_PARAMS ((char **pargz, size_t * pargz_len,
670 char *before, const char *entry));
671
672static error_t
673argz_insert (pargz, pargz_len, before, entry)
674 char **pargz;
675 size_t *pargz_len;
676 char *before;
677 const char *entry;
678{
679 assert (pargz);
680 assert (pargz_len);
681 assert (entry && *entry);
682
683 /* No BEFORE address indicates ENTRY should be inserted after the
684 current last element. */
685 if (!before)
686 return argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry));
687
688 /* This probably indicates a programmer error, but to preserve
689 semantics, scan back to the start of an entry if BEFORE points
690 into the middle of it. */
691 while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
692 --before;
693
694 {
695 size_t entry_len = 1 + LT_STRLEN (entry);
696 size_t argz_len = *pargz_len + entry_len;
697 size_t offset = before - *pargz;
698 char *argz = LT_DLREALLOC (char, *pargz, argz_len);
699
700 if (!argz)
701 return ENOMEM;
702
703 /* Make BEFORE point to the equivalent offset in ARGZ that it
704 used to have in *PARGZ incase realloc() moved the block. */
705 before = argz + offset;
706
707 /* Move the ARGZ entries starting at BEFORE up into the new
708 space at the end -- making room to copy ENTRY into the
709 resulting gap. */
710 memmove (before + entry_len, before, *pargz_len - offset);
711 memcpy (before, entry, entry_len);
712
713 /* Assign new values. */
714 *pargz = argz;
715 *pargz_len = argz_len;
716 }
717
718 return 0;
719}
720#endif /* !HAVE_ARGZ_INSERT */
721
722
723#if ! HAVE_ARGZ_NEXT
724# define argz_next rpl_argz_next
725
726static char *argz_next LT_PARAMS ((char *argz, size_t argz_len,
727 const char *entry));
728
729static char *
730argz_next (argz, argz_len, entry)
731 char *argz;
732 size_t argz_len;
733 const char *entry;
734{
735 assert ((argz && argz_len) || (!argz && !argz_len));
736
737 if (entry)
738 {
739 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
740 within the ARGZ vector. */
741 assert ((!argz && !argz_len)
742 || ((argz <= entry) && (entry < (argz + argz_len))));
743
744 /* Move to the char immediately after the terminating
745 '\0' of ENTRY. */
746 entry = 1 + strchr (entry, LT_EOS_CHAR);
747
748 /* Return either the new ENTRY, or else NULL if ARGZ is
749 exhausted. */
750 return (entry >= argz + argz_len) ? 0 : (char *) entry;
751 }
752 else
753 {
754 /* This should probably be flagged as a programmer error,
755 since starting an argz_next loop with the iterator set
756 to ARGZ is safer. To preserve semantics, handle the NULL
757 case by returning the start of ARGZ (if any). */
758 if (argz_len > 0)
759 return argz;
760 else
761 return 0;
762 }
763}
764#endif /* !HAVE_ARGZ_NEXT */
765
766
767
768#if ! HAVE_ARGZ_STRINGIFY
769# define argz_stringify rpl_argz_stringify
770
771static void argz_stringify LT_PARAMS ((char *argz, size_t argz_len, int sep));
772
773static void
774argz_stringify (argz, argz_len, sep)
775 char *argz;
776 size_t argz_len;
777 int sep;
778{
779 assert ((argz && argz_len) || (!argz && !argz_len));
780
781 if (sep)
782 {
783 --argz_len; /* don't stringify the terminating EOS */
784 while (--argz_len > 0)
785 {
786 if (argz[argz_len] == LT_EOS_CHAR)
787 argz[argz_len] = sep;
788 }
789 }
790}
791#endif /* !HAVE_ARGZ_STRINGIFY */
792
793
794
795
796/* --- TYPE DEFINITIONS -- */
797
798
799/* This type is used for the array of caller data sets in each handler. */
800typedef struct
801{
802 lt_dlcaller_id key;
803 lt_ptr data;
804} lt_caller_data;
805
806
807
808
809/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
810
811
812/* Extract the diagnostic strings from the error table macro in the same
813 order as the enumerated indices in ltdl.h. */
814
815static const char *lt_dlerror_strings[] = {
816#define LT_ERROR(name, diagnostic) (diagnostic),
817 lt_dlerror_table
818#undef LT_ERROR
819 0
820};
821
822/* This structure is used for the list of registered loaders. */
823struct lt_dlloader
824{
825 struct lt_dlloader *next;
826 const char *loader_name; /* identifying name for each loader */
827 const char *sym_prefix; /* prefix for symbols */
828 lt_module_open *module_open;
829 lt_module_close *module_close;
830 lt_find_sym *find_sym;
831 lt_dlloader_exit *dlloader_exit;
832 lt_user_data dlloader_data;
833};
834
835struct lt_dlhandle_struct
836{
837 struct lt_dlhandle_struct *next;
838 lt_dlloader *loader; /* dlopening interface */
839 lt_dlinfo info;
840 int depcount; /* number of dependencies */
841 lt_dlhandle *deplibs; /* dependencies */
842 lt_module module; /* system module handle */
843 lt_ptr system; /* system specific data */
844 lt_caller_data *caller_data; /* per caller associated data */
845 int flags; /* various boolean stats */
846};
847
848/* Various boolean flags can be stored in the flags field of an
849 lt_dlhandle_struct... */
850#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
851#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
852
853#define LT_DLRESIDENT_FLAG (0x01 << 0)
854/* ...add more flags here... */
855
856#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
857
858
859#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
860
861static const char objdir[] = LTDL_OBJDIR;
862static const char archive_ext[] = LTDL_ARCHIVE_EXT;
863#ifdef LTDL_SHLIB_EXT
864static const char shlib_ext[] = LTDL_SHLIB_EXT;
865#endif
866#ifdef LTDL_SYSSEARCHPATH
867static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
868#endif
869
870
871
872
873/* --- GNUNET_Mutex LOCKING --- */
874
875
876/* Macros to make it easier to run the lock functions only if they have
877 been registered. The reason for the complicated lock macro is to
878 ensure that the stored error message from the last error is not
879 accidentally erased if the current function doesn't generate an
880 error of its own. */
881#define LT_DLGNUNET_mutex_lock() LT_STMT_START { \
882 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
883 } LT_STMT_END
884#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
885 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
886 } LT_STMT_END
887#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
888 if (lt_dlmutex_seterror_func) \
889 (*lt_dlmutex_seterror_func) (errormsg); \
890 else lt_dllast_error = (errormsg); } LT_STMT_END
891#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
892 if (lt_dlmutex_seterror_func) \
893 (errormsg) = (*lt_dlmutex_geterror_func) (); \
894 else (errormsg) = lt_dllast_error; } LT_STMT_END
895
896/* The mutex functions stored here are global, and are necessarily the
897 same for all threads that wish to share access to libltdl. */
898static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
899static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
900static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
901static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
902static const char *lt_dllast_error = 0;
903
904
905/* Either set or reset the mutex functions. Either all the arguments must
906 be valid functions, or else all can be NULL to turn off locking entirely.
907 The registered functions should be manipulating a static global lock
908 from the lock() and unlock() callbacks, which needs to be reentrant. */
909int
910lt_dlmutex_register (lock, unlock, seterror, geterror)
911 lt_dlmutex_lock *lock;
912 lt_dlmutex_unlock *unlock;
913 lt_dlmutex_seterror *seterror;
914 lt_dlmutex_geterror *geterror;
915{
916 lt_dlmutex_unlock *old_unlock = unlock;
917 int errors = 0;
918
919 /* Lock using the old lock() callback, if any. */
920 LT_DLGNUNET_mutex_lock ();
921
922 if ((lock && unlock && seterror && geterror)
923 || !(lock || unlock || seterror || geterror))
924 {
925 lt_dlmutex_lock_func = lock;
926 lt_dlmutex_unlock_func = unlock;
927 lt_dlmutex_geterror_func = geterror;
928 }
929 else
930 {
931 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
932 ++errors;
933 }
934
935 /* Use the old unlock() callback we saved earlier, if any. Otherwise
936 record any errors using internal storage. */
937 if (old_unlock)
938 (*old_unlock) ();
939
940 /* Return the number of errors encountered during the execution of
941 this function. */
942 return errors;
943}
944
945
946
947
948/* --- ERROR HANDLING --- */
949
950
951static const char **user_error_strings = 0;
952static int errorcount = LT_ERROR_MAX;
953
954int
955lt_dladderror (diagnostic)
956 const char *diagnostic;
957{
958 int errindex = 0;
959 int result = -1;
960 const char **temp = (const char **) 0;
961
962 assert (diagnostic);
963
964 LT_DLGNUNET_mutex_lock ();
965
966 errindex = errorcount - LT_ERROR_MAX;
967 temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
968 if (temp)
969 {
970 user_error_strings = temp;
971 user_error_strings[errindex] = diagnostic;
972 result = errorcount++;
973 }
974
975 LT_DLMUTEX_UNLOCK ();
976
977 return result;
978}
979
980int
981lt_dlseterror (errindex)
982 int errindex;
983{
984 int errors = 0;
985
986 LT_DLGNUNET_mutex_lock ();
987
988 if (errindex >= errorcount || errindex < 0)
989 {
990 /* Ack! Error setting the error message! */
991 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
992 ++errors;
993 }
994 else if (errindex < LT_ERROR_MAX)
995 {
996 /* No error setting the error message! */
997 LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
998 }
999 else
1000 {
1001 /* No error setting the error message! */
1002 LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
1003 }
1004
1005 LT_DLMUTEX_UNLOCK ();
1006
1007 return errors;
1008}
1009
1010static lt_ptr
1011lt_emalloc (size)
1012 size_t size;
1013{
1014 lt_ptr mem = lt_dlmalloc (size);
1015 if (size && !mem)
1016 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1017 return mem;
1018}
1019
1020static lt_ptr
1021lt_erealloc (addr, size)
1022 lt_ptr addr;
1023 size_t size;
1024{
1025 lt_ptr mem = lt_dlrealloc (addr, size);
1026 if (size && !mem)
1027 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1028 return mem;
1029}
1030
1031static char *
1032lt_estrdup (str)
1033 const char *str;
1034{
1035 char *copy = strdup (str);
1036 if (LT_STRLEN (str) && !copy)
1037 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1038 return copy;
1039}
1040
1041
1042
1043
1044/* --- DLOPEN() INTERFACE LOADER --- */
1045
1046
1047#if HAVE_LIBDL
1048
1049/* dynamic linking with dlopen/dlsym */
1050
1051#if HAVE_DLFCN_H
1052# include <dlfcn.h>
1053#endif
1054
1055#if HAVE_SYS_DL_H
1056# include <sys/dl.h>
1057#endif
1058
1059/* We may have to define LT_LAZY_OR_NOW in the command line if we
1060 find out it does not work in some platform. */
1061#ifndef LT_LAZY_OR_NOW
1062# ifdef RTLD_LAZY
1063# define LT_LAZY_OR_NOW RTLD_LAZY
1064# else
1065# ifdef DL_LAZY
1066# define LT_LAZY_OR_NOW DL_LAZY
1067# endif
1068# endif /* !RTLD_LAZY */
1069#endif
1070#ifndef LT_LAZY_OR_NOW
1071# ifdef RTLD_NOW
1072# define LT_LAZY_OR_NOW RTLD_NOW
1073# else
1074# ifdef DL_NOW
1075# define LT_LAZY_OR_NOW DL_NOW
1076# endif
1077# endif /* !RTLD_NOW */
1078#endif
1079#ifndef LT_LAZY_OR_NOW
1080# define LT_LAZY_OR_NOW 0
1081#endif /* !LT_LAZY_OR_NOW */
1082
1083#if HAVE_DLERROR
1084# define DLERROR(arg) dlerror ()
1085#else
1086# define DLERROR(arg) LT_DLSTRERROR (arg)
1087#endif
1088
1089static lt_module
1090sys_dl_open (loader_data, filename)
1091 lt_user_data loader_data;
1092 const char *filename;
1093{
1094 lt_module module = dlopen (filename, LT_LAZY_OR_NOW);
1095
1096 if (!module)
1097 {
1098 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
1099 }
1100
1101 return module;
1102}
1103
1104static int
1105sys_dl_close (loader_data, module)
1106 lt_user_data loader_data;
1107 lt_module module;
1108{
1109 int errors = 0;
1110
1111 if (dlclose (module) != 0)
1112 {
1113 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1114 ++errors;
1115 }
1116
1117 return errors;
1118}
1119
1120static lt_ptr
1121sys_dl_sym (loader_data, module, symbol)
1122 lt_user_data loader_data;
1123 lt_module module;
1124 const char *symbol;
1125{
1126 lt_ptr address = dlsym (module, symbol);
1127
1128 if (!address)
1129 {
1130 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1131 }
1132
1133 return address;
1134}
1135
1136static struct lt_user_dlloader sys_dl = {
1137# ifdef NEED_USCORE
1138 "_",
1139# else
1140 0,
1141# endif
1142 sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0
1143};
1144
1145
1146#endif /* HAVE_LIBDL */
1147
1148
1149
1150/* --- SHL_LOAD() INTERFACE LOADER --- */
1151
1152#if HAVE_SHL_LOAD
1153
1154/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1155
1156#ifdef HAVE_DL_H
1157# include <dl.h>
1158#endif
1159
1160/* some flags are missing on some systems, so we provide
1161 * harmless defaults.
1162 *
1163 * Mandatory:
1164 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1165 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1166 *
1167 * Optionally:
1168 * BIND_FIRST - Place the library at the head of the symbol search
1169 * order.
1170 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1171 * unsatisfied symbols as fatal. This flag allows
1172 * binding of unsatisfied code symbols to be deferred
1173 * until use.
1174 * [Perl: For certain libraries, like DCE, deferred
1175 * binding often causes run time problems. Adding
1176 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1177 * unresolved references in situations like this.]
1178 * BIND_NOSTART - Do not call the initializer for the shared library
1179 * when the library is loaded, nor on a future call to
1180 * shl_unload().
1181 * BIND_VERBOSE - Print verbose messages concerning possible
1182 * unsatisfied symbols.
1183 *
1184 * hp9000s700/hp9000s800:
1185 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1186 * present at library load time.
1187 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1188 * library specified by the path argument.
1189 */
1190
1191#ifndef DYNAMIC_PATH
1192# define DYNAMIC_PATH 0
1193#endif
1194#ifndef BIND_RESTRICTED
1195# define BIND_RESTRICTED 0
1196#endif
1197
1198#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1199
1200static lt_module
1201sys_shl_open (loader_data, filename)
1202 lt_user_data loader_data;
1203 const char *filename;
1204{
1205 static shl_t self = (shl_t) 0;
1206 lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1207
1208 /* Since searching for a symbol against a NULL module handle will also
1209 look in everything else that was already loaded and exported with
1210 the -E compiler flag, we always cache a handle saved before any
1211 modules are loaded. */
1212 if (!self)
1213 {
1214 lt_ptr address;
1215 shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1216 }
1217
1218 if (!filename)
1219 {
1220 module = self;
1221 }
1222 else
1223 {
1224 module = shl_load (filename, LT_BIND_FLAGS, 0L);
1225
1226 if (!module)
1227 {
1228 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1229 }
1230 }
1231
1232 return module;
1233}
1234
1235static int
1236sys_shl_close (loader_data, module)
1237 lt_user_data loader_data;
1238 lt_module module;
1239{
1240 int errors = 0;
1241
1242 if (module && (shl_unload ((shl_t) (module)) != 0))
1243 {
1244 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1245 ++errors;
1246 }
1247
1248 return errors;
1249}
1250
1251static lt_ptr
1252sys_shl_sym (loader_data, module, symbol)
1253 lt_user_data loader_data;
1254 lt_module module;
1255 const char *symbol;
1256{
1257 lt_ptr address = 0;
1258
1259 /* sys_shl_open should never return a NULL module handle */
1260 if (module == (lt_module) 0)
1261 {
1262 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1263 }
1264 else
1265 if (!shl_findsym ((shl_t *) & module, symbol, TYPE_UNDEFINED, &address))
1266 {
1267 if (!address)
1268 {
1269 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1270 }
1271 }
1272
1273 return address;
1274}
1275
1276static struct lt_user_dlloader sys_shl = {
1277 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1278};
1279
1280#endif /* HAVE_SHL_LOAD */
1281
1282
1283
1284
1285/* --- LOADLIBRARY() INTERFACE LOADER --- */
1286
1287#ifdef __WINDOWS__
1288
1289/* dynamic linking for Win32 */
1290
1291#include <windows.h>
1292
1293/* Forward declaration; required to implement handle search below. */
1294static lt_dlhandle handles;
1295
1296static lt_module
1297sys_wll_open (loader_data, filename)
1298 lt_user_data loader_data;
1299 const char *filename;
1300{
1301 lt_dlhandle cur;
1302 lt_module module = 0;
1303 const char *errormsg = 0;
1304 char *searchname = 0;
1305 char *ext;
1306 char self_name_buf[MAX_PATH];
1307
1308 if (!filename)
1309 {
1310 /* Get the name of main module */
1311 *self_name_buf = 0;
1312 GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1313 filename = ext = self_name_buf;
1314 }
1315 else
1316 {
1317 ext = strrchr (filename, '.');
1318 }
1319
1320 if (ext)
1321 {
1322 /* FILENAME already has an extension. */
1323 searchname = lt_estrdup (filename);
1324 }
1325 else
1326 {
1327 /* Append a `.' to stop Windows from adding an
1328 implicit `.dll' extension. */
1329 searchname = LT_EGNUNET_malloc (char, 2 + LT_STRLEN (filename));
1330 if (searchname)
1331 sprintf (searchname, "%s.", filename);
1332 }
1333 if (!searchname)
1334 return 0;
1335
1336#if __CYGWIN__
1337 {
1338 char wpath[MAX_PATH];
1339 cygwin_conv_to_full_win32_path (searchname, wpath);
1340 module = LoadLibrary (wpath);
1341 }
1342#else
1343 module = LoadLibrary (searchname);
1344#endif
1345 LT_DLGNUNET_free (searchname);
1346
1347 /* libltdl expects this function to fail if it is unable
1348 to physically load the library. Sadly, LoadLibrary
1349 will search the loaded libraries for a match and return
1350 one of them if the path search load fails.
1351
1352 We check whether LoadLibrary is returning a handle to
1353 an already loaded module, and simulate failure if we
1354 find one. */
1355 LT_DLGNUNET_mutex_lock ();
1356 cur = handles;
1357 while (cur)
1358 {
1359 if (!cur->module)
1360 {
1361 cur = 0;
1362 break;
1363 }
1364
1365 if (cur->module == module)
1366 {
1367 break;
1368 }
1369
1370 cur = cur->next;
1371 }
1372 LT_DLMUTEX_UNLOCK ();
1373
1374 if (cur || !module)
1375 {
1376 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1377 module = 0;
1378 }
1379
1380 return module;
1381}
1382
1383static int
1384sys_wll_close (loader_data, module)
1385 lt_user_data loader_data;
1386 lt_module module;
1387{
1388 int errors = 0;
1389
1390 if (FreeLibrary (module) == 0)
1391 {
1392 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1393 ++errors;
1394 }
1395
1396 return errors;
1397}
1398
1399static lt_ptr
1400sys_wll_sym (loader_data, module, symbol)
1401 lt_user_data loader_data;
1402 lt_module module;
1403 const char *symbol;
1404{
1405 lt_ptr address = GetProcAddress (module, symbol);
1406
1407 if (!address)
1408 {
1409 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1410 }
1411
1412 return address;
1413}
1414
1415static struct lt_user_dlloader sys_wll = {
1416 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1417};
1418
1419#endif /* __WINDOWS__ */
1420
1421
1422
1423
1424/* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1425
1426
1427#ifdef __BEOS__
1428
1429/* dynamic linking for BeOS */
1430
1431#include <kernel/image.h>
1432
1433static lt_module
1434sys_bedl_open (loader_data, filename)
1435 lt_user_data loader_data;
1436 const char *filename;
1437{
1438 image_id image = 0;
1439
1440 if (filename)
1441 {
1442 image = load_add_on (filename);
1443 }
1444 else
1445 {
1446 image_info info;
1447 int32 cookie = 0;
1448 if (get_next_image_info (0, &cookie, &info) == B_OK)
1449 image = load_add_on (info.name);
1450 }
1451
1452 if (image <= 0)
1453 {
1454 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1455 image = 0;
1456 }
1457
1458 return (lt_module) image;
1459}
1460
1461static int
1462sys_bedl_close (loader_data, module)
1463 lt_user_data loader_data;
1464 lt_module module;
1465{
1466 int errors = 0;
1467
1468 if (unload_add_on ((image_id) module) != B_OK)
1469 {
1470 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1471 ++errors;
1472 }
1473
1474 return errors;
1475}
1476
1477static lt_ptr
1478sys_bedl_sym (loader_data, module, symbol)
1479 lt_user_data loader_data;
1480 lt_module module;
1481 const char *symbol;
1482{
1483 lt_ptr address = 0;
1484 image_id image = (image_id) module;
1485
1486 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1487 {
1488 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1489 address = 0;
1490 }
1491
1492 return address;
1493}
1494
1495static struct lt_user_dlloader sys_bedl = {
1496 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1497};
1498
1499#endif /* __BEOS__ */
1500
1501
1502
1503
1504/* --- DLD_LINK() INTERFACE LOADER --- */
1505
1506
1507#if HAVE_DLD
1508
1509/* dynamic linking with dld */
1510
1511#if HAVE_DLD_H
1512#include <dld.h>
1513#endif
1514
1515static lt_module
1516sys_dld_open (loader_data, filename)
1517 lt_user_data loader_data;
1518 const char *filename;
1519{
1520 lt_module module = strdup (filename);
1521
1522 if (dld_link (filename) != 0)
1523 {
1524 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1525 LT_DLGNUNET_free (module);
1526 module = 0;
1527 }
1528
1529 return module;
1530}
1531
1532static int
1533sys_dld_close (loader_data, module)
1534 lt_user_data loader_data;
1535 lt_module module;
1536{
1537 int errors = 0;
1538
1539 if (dld_unlink_by_file ((char *) (module), 1) != 0)
1540 {
1541 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1542 ++errors;
1543 }
1544 else
1545 {
1546 LT_DLGNUNET_free (module);
1547 }
1548
1549 return errors;
1550}
1551
1552static lt_ptr
1553sys_dld_sym (loader_data, module, symbol)
1554 lt_user_data loader_data;
1555 lt_module module;
1556 const char *symbol;
1557{
1558 lt_ptr address = dld_get_func (symbol);
1559
1560 if (!address)
1561 {
1562 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1563 }
1564
1565 return address;
1566}
1567
1568static struct lt_user_dlloader sys_dld = {
1569 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1570};
1571
1572#endif /* HAVE_DLD */
1573
1574/* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1575#if HAVE_DYLD
1576
1577
1578#if HAVE_MACH_O_DYLD_H
1579#if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1580/* Is this correct? Does it still function properly? */
1581#define __private_extern__ extern
1582#endif
1583# include <mach-o/dyld.h>
1584#endif
1585#include <mach-o/getsect.h>
1586
1587/* We have to put some stuff here that isn't in older dyld.h files */
1588#ifndef ENUM_DYLD_BOOL
1589# define ENUM_DYLD_BOOL
1590# undef FALSE
1591# undef TRUE
1592enum DYLD_BOOL
1593{
1594 FALSE,
1595 TRUE
1596};
1597#endif
1598#ifndef LC_REQ_DYLD
1599# define LC_REQ_DYLD 0x80000000
1600#endif
1601#ifndef LC_LOAD_WEAK_DYLIB
1602# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1603#endif
1604static const struct mach_header *(*ltdl_NSAddImage) (const char *image_name,
1605 unsigned long options) =
1606 0;
1607static NSSymbol (*ltdl_NSLookupSymbolInImage) (const struct mach_header *
1608 image, const char *symbolName,
1609 unsigned long options) = 0;
1610static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage) (const struct
1611 mach_header *
1612 image,
1613 const char
1614 *symbolName) = 0;
1615static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic) (NSModule module) = 0;
1616
1617#ifndef NSADDIMAGE_OPTION_NONE
1618#define NSADDIMAGE_OPTION_NONE 0x0
1619#endif
1620#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1621#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1622#endif
1623#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1624#define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1625#endif
1626#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1627#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1628#endif
1629#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1630#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1631#endif
1632#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1633#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1634#endif
1635#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1636#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1637#endif
1638#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1639#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1640#endif
1641#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1642#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1643#endif
1644
1645
1646static const char *
1647lt_int_dyld_error (othererror)
1648 char *othererror;
1649{
1650/* return the dyld error string, or the passed in error string if none */
1651 NSLinkEditErrors ler;
1652 int lerno;
1653 const char *errstr;
1654 const char *file;
1655 NSLinkEditError (&ler, &lerno, &file, &errstr);
1656 if (!errstr || !strlen (errstr))
1657 errstr = othererror;
1658 return errstr;
1659}
1660
1661static const struct mach_header *
1662lt_int_dyld_get_mach_header_from_nsmodule (module)
1663 NSModule module;
1664{
1665/* There should probably be an apple dyld api for this */
1666 int i = _dyld_image_count ();
1667 int j;
1668 const char *modname = NSNameOfModule (module);
1669 const struct mach_header *mh = NULL;
1670 if (!modname)
1671 return NULL;
1672 for (j = 0; j < i; j++)
1673 {
1674 if (!strcmp (_dyld_get_image_name (j), modname))
1675 {
1676 mh = _dyld_get_image_header (j);
1677 break;
1678 }
1679 }
1680 return mh;
1681}
1682
1683static const char *
1684lt_int_dyld_lib_install_name (mh)
1685 const struct mach_header *mh;
1686{
1687/* NSAddImage is also used to get the loaded image, but it only works if the lib
1688 is installed, for uninstalled libs we need to check the install_names against
1689 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1690 different lib was loaded as a result
1691*/
1692 int j;
1693 struct load_command *lc;
1694 unsigned long offset = sizeof (struct mach_header);
1695 const char *retStr = NULL;
1696 for (j = 0; j < mh->ncmds; j++)
1697 {
1698 lc = (struct load_command *) (((unsigned long) mh) + offset);
1699 if (LC_ID_DYLIB == lc->cmd)
1700 {
1701 retStr =
1702 (char *) (((struct dylib_command *) lc)->dylib.name.offset +
1703 (unsigned long) lc);
1704 }
1705 offset += lc->cmdsize;
1706 }
1707 return retStr;
1708}
1709
1710static const struct mach_header *
1711lt_int_dyld_match_loaded_lib_by_install_name (const char *name)
1712{
1713 int i = _dyld_image_count ();
1714 int j;
1715 const struct mach_header *mh = NULL;
1716 const char *id = NULL;
1717 for (j = 0; j < i; j++)
1718 {
1719 id = lt_int_dyld_lib_install_name (_dyld_get_image_header (j));
1720 if ((id) && (!strcmp (id, name)))
1721 {
1722 mh = _dyld_get_image_header (j);
1723 break;
1724 }
1725 }
1726 return mh;
1727}
1728
1729static NSSymbol
1730lt_int_dyld_NSlookupSymbolInLinkedLibs (symbol, mh)
1731 const char *symbol;
1732 const struct mach_header *mh;
1733{
1734 /* Safe to assume our mh is good */
1735 int j;
1736 struct load_command *lc;
1737 unsigned long offset = sizeof (struct mach_header);
1738 NSSymbol retSym = 0;
1739 const struct mach_header *mh1;
1740 if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined (symbol))
1741 {
1742 for (j = 0; j < mh->ncmds; j++)
1743 {
1744 lc = (struct load_command *) (((unsigned long) mh) + offset);
1745 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1746 {
1747 mh1 =
1748 lt_int_dyld_match_loaded_lib_by_install_name ((char
1749 *) (((struct
1750 dylib_command
1751 *) lc)->
1752 dylib.name.
1753 offset +
1754 (unsigned
1755 long)
1756 lc));
1757 if (!mh1)
1758 {
1759 /* Maybe NSAddImage can find it */
1760 mh1 =
1761 ltdl_NSAddImage ((char *) (((struct dylib_command *) lc)->
1762 dylib.name.offset +
1763 (unsigned long) lc),
1764 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1765 +
1766 NSADDIMAGE_OPTION_WITH_SEARCHING +
1767 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1768 }
1769 if (mh1)
1770 {
1771 retSym = ltdl_NSLookupSymbolInImage (mh1,
1772 symbol,
1773 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1774 |
1775 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
1776 if (retSym)
1777 break;
1778 }
1779 }
1780 offset += lc->cmdsize;
1781 }
1782 }
1783 return retSym;
1784}
1785
1786static int
1787sys_dyld_init ()
1788{
1789 int retCode = 0;
1790 int err = 0;
1791 if (!_dyld_present ())
1792 {
1793 retCode = 1;
1794 }
1795 else
1796 {
1797 err =
1798 _dyld_func_lookup ("__dyld_NSAddImage",
1799 (unsigned long *) &ltdl_NSAddImage);
1800 err =
1801 _dyld_func_lookup ("__dyld_NSLookupSymbolInImage",
1802 (unsigned long *) &ltdl_NSLookupSymbolInImage);
1803 err =
1804 _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage",
1805 (unsigned long *)
1806 &ltdl_NSIsSymbolNameDefinedInImage);
1807 err =
1808 _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic",
1809 (unsigned long *) &ltdl_NSMakePrivateModulePublic);
1810 }
1811 return retCode;
1812}
1813
1814static lt_module
1815sys_dyld_open (loader_data, filename)
1816 lt_user_data loader_data;
1817 const char *filename;
1818{
1819 lt_module module = 0;
1820 NSObjectFileImage ofi = 0;
1821 NSObjectFileImageReturnCode ofirc;
1822
1823 if (!filename)
1824 return (lt_module) - 1;
1825 ofirc = NSCreateObjectFileImageFromFile (filename, &ofi);
1826 switch (ofirc)
1827 {
1828 case NSObjectFileImageSuccess:
1829 module = NSLinkModule (ofi, filename,
1830 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1831 | NSLINKMODULE_OPTION_PRIVATE
1832 | NSLINKMODULE_OPTION_BINDNOW);
1833 NSDestroyObjectFileImage (ofi);
1834 if (module)
1835 ltdl_NSMakePrivateModulePublic (module);
1836 break;
1837 case NSObjectFileImageInappropriateFile:
1838 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1839 {
1840 module =
1841 (lt_module) ltdl_NSAddImage (filename,
1842 NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1843 break;
1844 }
1845 default:
1846 LT_DLMUTEX_SETERROR (lt_int_dyld_error (LT_DLSTRERROR (CANNOT_OPEN)));
1847 return 0;
1848 }
1849 if (!module)
1850 LT_DLMUTEX_SETERROR (lt_int_dyld_error (LT_DLSTRERROR (CANNOT_OPEN)));
1851 return module;
1852}
1853
1854static int
1855sys_dyld_close (loader_data, module)
1856 lt_user_data loader_data;
1857 lt_module module;
1858{
1859 int retCode = 0;
1860 int flags = 0;
1861 if (module == (lt_module) - 1)
1862 return 0;
1863#ifdef __BIG_ENDIAN__
1864 if (((struct mach_header *) module)->magic == MH_MAGIC)
1865#else
1866 if (((struct mach_header *) module)->magic == MH_CIGAM)
1867#endif
1868 {
1869 LT_DLMUTEX_SETERROR ("Can not close a dylib");
1870 retCode = 1;
1871 }
1872 else
1873 {
1874#if 1
1875/* Currently, if a module contains c++ static destructors and it is unloaded, we
1876 get a segfault in atexit(), due to compiler and dynamic loader differences of
1877 opinion, this works around that.
1878*/
1879 if ((const struct section *) NULL !=
1880 getsectbynamefromheader (lt_int_dyld_get_mach_header_from_nsmodule
1881 (module), "__DATA", "__mod_term_func"))
1882 {
1883 flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1884 }
1885#endif
1886#ifdef __ppc__
1887 flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1888#endif
1889 if (!NSUnLinkModule (module, flags))
1890 {
1891 retCode = 1;
1892 LT_DLMUTEX_SETERROR (lt_int_dyld_error
1893 (LT_DLSTRERROR (CANNOT_CLOSE)));
1894 }
1895 }
1896
1897 return retCode;
1898}
1899
1900static lt_ptr
1901sys_dyld_sym (loader_data, module, symbol)
1902 lt_user_data loader_data;
1903 lt_module module;
1904 const char *symbol;
1905{
1906 lt_ptr address = 0;
1907 NSSymbol *nssym = 0;
1908 void *unused;
1909 const struct mach_header *mh = NULL;
1910 char saveError[256] = "Symbol not found";
1911 if (module == (lt_module) - 1)
1912 {
1913 _dyld_lookup_and_bind (symbol, (unsigned long *) &address, &unused);
1914 return address;
1915 }
1916#ifdef __BIG_ENDIAN__
1917 if (((struct mach_header *) module)->magic == MH_MAGIC)
1918#else
1919 if (((struct mach_header *) module)->magic == MH_CIGAM)
1920#endif
1921 {
1922 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1923 {
1924 mh = module;
1925 if (ltdl_NSIsSymbolNameDefinedInImage
1926 ((struct mach_header *) module, symbol))
1927 {
1928 nssym =
1929 ltdl_NSLookupSymbolInImage ((struct mach_header *) module,
1930 symbol,
1931 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1932 |
1933 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
1934 }
1935 }
1936
1937 }
1938 else
1939 {
1940 nssym = NSLookupSymbolInModule (module, symbol);
1941 }
1942 if (!nssym)
1943 {
1944 strncpy (saveError,
1945 lt_int_dyld_error (LT_DLSTRERROR (SYMBOL_NOT_FOUND)), 255);
1946 saveError[255] = 0;
1947 if (!mh)
1948 mh = lt_int_dyld_get_mach_header_from_nsmodule (module);
1949 nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs (symbol, mh);
1950 }
1951 if (!nssym)
1952 {
1953 LT_DLMUTEX_SETERROR (saveError);
1954 return NULL;
1955 }
1956 return NSAddressOfSymbol (nssym);
1957}
1958
1959static struct lt_user_dlloader sys_dyld =
1960 { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1961
1962
1963#endif /* HAVE_DYLD */
1964
1965
1966/* --- DLPREOPEN() INTERFACE LOADER --- */
1967
1968
1969/* emulate dynamic linking using preloaded_symbols */
1970
1971typedef struct lt_dlsymlists_t
1972{
1973 struct lt_dlsymlists_t *next;
1974 const lt_dlsymlist *syms;
1975} lt_dlsymlists_t;
1976
1977static const lt_dlsymlist *default_preloaded_symbols = 0;
1978static lt_dlsymlists_t *preloaded_symbols = 0;
1979
1980static int
1981presym_init (loader_data)
1982 lt_user_data loader_data;
1983{
1984 int errors = 0;
1985
1986 LT_DLGNUNET_mutex_lock ();
1987
1988 preloaded_symbols = 0;
1989 if (default_preloaded_symbols)
1990 {
1991 errors = lt_dlpreload (default_preloaded_symbols);
1992 }
1993
1994 LT_DLMUTEX_UNLOCK ();
1995
1996 return errors;
1997}
1998
1999static int
2000presym_free_symlists ()
2001{
2002 lt_dlsymlists_t *lists;
2003
2004 LT_DLGNUNET_mutex_lock ();
2005
2006 lists = preloaded_symbols;
2007 while (lists)
2008 {
2009 lt_dlsymlists_t *tmp = lists;
2010
2011 lists = lists->next;
2012 LT_DLGNUNET_free (tmp);
2013 }
2014 preloaded_symbols = 0;
2015
2016 LT_DLMUTEX_UNLOCK ();
2017
2018 return 0;
2019}
2020
2021static int
2022presym_exit (loader_data)
2023 lt_user_data loader_data;
2024{
2025 presym_free_symlists ();
2026 return 0;
2027}
2028
2029static int
2030presym_add_symlist (preloaded)
2031 const lt_dlsymlist *preloaded;
2032{
2033 lt_dlsymlists_t *tmp;
2034 lt_dlsymlists_t *lists;
2035 int errors = 0;
2036
2037 LT_DLGNUNET_mutex_lock ();
2038
2039 lists = preloaded_symbols;
2040 while (lists)
2041 {
2042 if (lists->syms == preloaded)
2043 {
2044 goto done;
2045 }
2046 lists = lists->next;
2047 }
2048
2049 tmp = LT_EGNUNET_malloc (lt_dlsymlists_t, 1);
2050 if (tmp)
2051 {
2052 memset (tmp, 0, sizeof (lt_dlsymlists_t));
2053 tmp->syms = preloaded;
2054 tmp->next = preloaded_symbols;
2055 preloaded_symbols = tmp;
2056 }
2057 else
2058 {
2059 ++errors;
2060 }
2061
2062done:
2063 LT_DLMUTEX_UNLOCK ();
2064 return errors;
2065}
2066
2067static lt_module
2068presym_open (loader_data, filename)
2069 lt_user_data loader_data;
2070 const char *filename;
2071{
2072 lt_dlsymlists_t *lists;
2073 lt_module module = (lt_module) 0;
2074
2075 LT_DLGNUNET_mutex_lock ();
2076 lists = preloaded_symbols;
2077
2078 if (!lists)
2079 {
2080 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
2081 goto done;
2082 }
2083
2084 /* Can't use NULL as the reflective symbol header, as NULL is
2085 used to mark the end of the entire symbol list. Self-dlpreopened
2086 symbols follow this magic number, chosen to be an unlikely
2087 clash with a real module name. */
2088 if (!filename)
2089 {
2090 filename = "@PROGRAM@";
2091 }
2092
2093 while (lists)
2094 {
2095 const lt_dlsymlist *syms = lists->syms;
2096
2097 while (syms->name)
2098 {
2099 if (!syms->address && strcmp (syms->name, filename) == 0)
2100 {
2101 module = (lt_module) syms;
2102 goto done;
2103 }
2104 ++syms;
2105 }
2106
2107 lists = lists->next;
2108 }
2109
2110 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2111
2112done:
2113 LT_DLMUTEX_UNLOCK ();
2114 return module;
2115}
2116
2117static int
2118presym_close (loader_data, module)
2119 lt_user_data loader_data;
2120 lt_module module;
2121{
2122 /* Just to silence gcc -Wall */
2123 module = 0;
2124 return 0;
2125}
2126
2127static lt_ptr
2128presym_sym (loader_data, module, symbol)
2129 lt_user_data loader_data;
2130 lt_module module;
2131 const char *symbol;
2132{
2133 lt_dlsymlist *syms = (lt_dlsymlist *) module;
2134
2135 ++syms;
2136 while (syms->address)
2137 {
2138 if (strcmp (syms->name, symbol) == 0)
2139 {
2140 return syms->address;
2141 }
2142
2143 ++syms;
2144 }
2145
2146 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2147
2148 return 0;
2149}
2150
2151static struct lt_user_dlloader presym = {
2152 0, presym_open, presym_close, presym_sym, presym_exit, 0
2153};
2154
2155
2156
2157
2158
2159/* --- DYNAMIC MODULE LOADING --- */
2160
2161
2162/* The type of a function used at each iteration of foreach_dirinpath(). */
2163typedef int foreach_callback_func LT_PARAMS ((char *filename, lt_ptr data1,
2164 lt_ptr data2));
2165
2166static int foreach_dirinpath LT_PARAMS ((const char *search_path,
2167 const char *base_name,
2168 foreach_callback_func * func,
2169 lt_ptr data1, lt_ptr data2));
2170
2171static int find_file_callback LT_PARAMS ((char *filename, lt_ptr data,
2172 lt_ptr ignored));
2173static int find_handle_callback LT_PARAMS ((char *filename, lt_ptr data,
2174 lt_ptr ignored));
2175static int foreachfile_callback LT_PARAMS ((char *filename, lt_ptr data1,
2176 lt_ptr data2));
2177
2178
2179static int canonicalize_path LT_PARAMS ((const char *path,
2180 char **pcanonical));
2181static int argzize_path LT_PARAMS ((const char *path,
2182 char **pargz, size_t * pargz_len));
2183static FILE *find_file LT_PARAMS ((const char *search_path,
2184 const char *base_name, char **pdir));
2185static lt_dlhandle *find_handle LT_PARAMS ((const char *search_path,
2186 const char *base_name,
2187 lt_dlhandle * handle));
2188static int find_module LT_PARAMS ((lt_dlhandle * handle,
2189 const char *dir,
2190 const char *libdir,
2191 const char *dlname,
2192 const char *old_name, int installed));
2193static int free_vars LT_PARAMS ((char *dlname, char *oldname,
2194 char *libdir, char *deplibs));
2195static int load_deplibs LT_PARAMS ((lt_dlhandle handle, char *deplibs));
2196static int trim LT_PARAMS ((char **dest, const char *str));
2197static int try_dlopen LT_PARAMS ((lt_dlhandle * handle,
2198 const char *filename));
2199static int tryall_dlopen LT_PARAMS ((lt_dlhandle * handle,
2200 const char *filename));
2201static int unload_deplibs LT_PARAMS ((lt_dlhandle handle));
2202static int lt_argz_insert LT_PARAMS ((char **pargz,
2203 size_t * pargz_len,
2204 char *before, const char *entry));
2205static int lt_argz_insertinorder LT_PARAMS ((char **pargz,
2206 size_t * pargz_len,
2207 const char *entry));
2208static int lt_argz_insertdir LT_PARAMS ((char **pargz,
2209 size_t * pargz_len,
2210 const char *dirnam,
2211 struct dirent * dp));
2212static int lt_dlpath_insertdir LT_PARAMS ((char **ppath,
2213 char *before, const char *dir));
2214static int list_files_by_dir LT_PARAMS ((const char *dirnam,
2215 char **pargz, size_t * pargz_len));
2216static int file_not_found LT_PARAMS ((void));
2217
2218static char *user_search_path = 0;
2219static lt_dlloader *loaders = 0;
2220static lt_dlhandle handles = 0;
2221static int initialized = 0;
2222
2223/* Initialize libltdl. */
2224int
2225lt_dlinit ()
2226{
2227 int errors = 0;
2228
2229 LT_DLGNUNET_mutex_lock ();
2230
2231 /* Initialize only at first call. */
2232 if (++initialized == 1)
2233 {
2234 handles = 0;
2235 user_search_path = 0; /* empty search path */
2236
2237#if HAVE_LIBDL
2238 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2239#endif
2240#if HAVE_SHL_LOAD
2241 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2242#endif
2243#ifdef __WINDOWS__
2244 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2245#endif
2246#ifdef __BEOS__
2247 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2248#endif
2249#if HAVE_DLD
2250 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2251#endif
2252#if HAVE_DYLD
2253 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2254 errors += sys_dyld_init ();
2255#endif
2256 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2257
2258 if (presym_init (presym.dlloader_data))
2259 {
2260 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2261 ++errors;
2262 }
2263 else if (errors != 0)
2264 {
2265 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2266 ++errors;
2267 }
2268 }
2269
2270 LT_DLMUTEX_UNLOCK ();
2271
2272 return errors;
2273}
2274
2275int
2276lt_dlpreload (preloaded)
2277 const lt_dlsymlist *preloaded;
2278{
2279 int errors = 0;
2280
2281 if (preloaded)
2282 {
2283 errors = presym_add_symlist (preloaded);
2284 }
2285 else
2286 {
2287 presym_free_symlists ();
2288
2289 LT_DLGNUNET_mutex_lock ();
2290 if (default_preloaded_symbols)
2291 {
2292 errors = lt_dlpreload (default_preloaded_symbols);
2293 }
2294 LT_DLMUTEX_UNLOCK ();
2295 }
2296
2297 return errors;
2298}
2299
2300int
2301lt_dlpreload_default (preloaded)
2302 const lt_dlsymlist *preloaded;
2303{
2304 LT_DLGNUNET_mutex_lock ();
2305 default_preloaded_symbols = preloaded;
2306 LT_DLMUTEX_UNLOCK ();
2307 return 0;
2308}
2309
2310int
2311lt_dlexit ()
2312{
2313 /* shut down libltdl */
2314 lt_dlloader *loader;
2315 int errors = 0;
2316
2317 LT_DLGNUNET_mutex_lock ();
2318 loader = loaders;
2319
2320 if (!initialized)
2321 {
2322 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2323 ++errors;
2324 goto done;
2325 }
2326
2327 /* shut down only at last call. */
2328 if (--initialized == 0)
2329 {
2330 int level;
2331
2332 while (handles && LT_DLIS_RESIDENT (handles))
2333 {
2334 handles = handles->next;
2335 }
2336
2337 /* close all modules */
2338 for (level = 1; handles; ++level)
2339 {
2340 lt_dlhandle cur = handles;
2341 int saw_nonresident = 0;
2342
2343 while (cur)
2344 {
2345 lt_dlhandle tmp = cur;
2346 cur = cur->next;
2347 if (!LT_DLIS_RESIDENT (tmp))
2348 saw_nonresident = 1;
2349 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2350 {
2351 if (lt_dlclose (tmp))
2352 {
2353 ++errors;
2354 }
2355 }
2356 }
2357 /* done if only resident modules are left */
2358 if (!saw_nonresident)
2359 break;
2360 }
2361
2362 /* close all loaders */
2363 while (loader)
2364 {
2365 lt_dlloader *next = loader->next;
2366 lt_user_data data = loader->dlloader_data;
2367 if (loader->dlloader_exit && loader->dlloader_exit (data))
2368 {
2369 ++errors;
2370 }
2371
2372 LT_DLMEM_REASSIGN (loader, next);
2373 }
2374 loaders = 0;
2375 }
2376
2377done:
2378 LT_DLMUTEX_UNLOCK ();
2379 return errors;
2380}
2381
2382static int
2383tryall_dlopen (handle, filename)
2384 lt_dlhandle *handle;
2385 const char *filename;
2386{
2387 lt_dlhandle cur;
2388 lt_dlloader *loader;
2389 const char *saved_error;
2390 int errors = 0;
2391
2392 LT_DLMUTEX_GETERROR (saved_error);
2393 LT_DLGNUNET_mutex_lock ();
2394
2395 cur = handles;
2396 loader = loaders;
2397
2398 /* check whether the module was already opened */
2399 while (cur)
2400 {
2401 /* try to dlopen the program itself? */
2402 if (!cur->info.filename && !filename)
2403 {
2404 break;
2405 }
2406
2407 if (cur->info.filename && filename
2408 && strcmp (cur->info.filename, filename) == 0)
2409 {
2410 break;
2411 }
2412
2413 cur = cur->next;
2414 }
2415
2416 if (cur)
2417 {
2418 ++cur->info.ref_count;
2419 *handle = cur;
2420 goto done;
2421 }
2422
2423 cur = *handle;
2424 if (filename)
2425 {
2426 /* Comment out the check of file permissions using access.
2427 This call seems to always return -1 with error EACCES.
2428 */
2429 /* We need to catch missing file errors early so that
2430 file_not_found() can detect what happened.
2431 if (access (filename, R_OK) != 0)
2432 {
2433 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2434 ++errors;
2435 goto done;
2436 } */
2437
2438 cur->info.filename = lt_estrdup (filename);
2439 if (!cur->info.filename)
2440 {
2441 ++errors;
2442 goto done;
2443 }
2444 }
2445 else
2446 {
2447 cur->info.filename = 0;
2448 }
2449
2450 while (loader)
2451 {
2452 lt_user_data data = loader->dlloader_data;
2453
2454 cur->module = loader->module_open (data, filename);
2455
2456 if (cur->module != 0)
2457 {
2458 break;
2459 }
2460 loader = loader->next;
2461 }
2462
2463 if (!loader)
2464 {
2465 LT_DLGNUNET_free (cur->info.filename);
2466 ++errors;
2467 goto done;
2468 }
2469
2470 cur->loader = loader;
2471 LT_DLMUTEX_SETERROR (saved_error);
2472
2473done:
2474 LT_DLMUTEX_UNLOCK ();
2475
2476 return errors;
2477}
2478
2479static int
2480tryall_dlopen_module (handle, prefix, dirname, dlname)
2481 lt_dlhandle *handle;
2482 const char *prefix;
2483 const char *dirname;
2484 const char *dlname;
2485{
2486 int error = 0;
2487 char *filename = 0;
2488 size_t filename_len = 0;
2489 size_t dirname_len = LT_STRLEN (dirname);
2490
2491 assert (handle);
2492 assert (dirname);
2493 assert (dlname);
2494#ifdef LT_DIRSEP_CHAR
2495 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2496 should make it into this function: */
2497 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2498#endif
2499
2500 if (dirname_len > 0)
2501 if (dirname[dirname_len - 1] == '/')
2502 --dirname_len;
2503 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2504
2505 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2506 The PREFIX (if any) is handled below. */
2507 filename = LT_EGNUNET_malloc (char, dirname_len + 1 + filename_len + 1);
2508 if (!filename)
2509 return 1;
2510
2511 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
2512
2513 /* Now that we have combined DIRNAME and MODULENAME, if there is
2514 also a PREFIX to contend with, simply recurse with the arguments
2515 shuffled. Otherwise, attempt to open FILENAME as a module. */
2516 if (prefix)
2517 {
2518 error += tryall_dlopen_module (handle,
2519 (const char *) 0, prefix, filename);
2520 }
2521 else if (tryall_dlopen (handle, filename) != 0)
2522 {
2523 ++error;
2524 }
2525
2526 LT_DLGNUNET_free (filename);
2527 return error;
2528}
2529
2530static int
2531find_module (handle, dir, libdir, dlname, old_name, installed)
2532 lt_dlhandle *handle;
2533 const char *dir;
2534 const char *libdir;
2535 const char *dlname;
2536 const char *old_name;
2537 int installed;
2538{
2539 /* Try to open the old library first; if it was dlpreopened,
2540 we want the preopened version of it, even if a dlopenable
2541 module is available. */
2542 if (old_name && tryall_dlopen (handle, old_name) == 0)
2543 {
2544 return 0;
2545 }
2546
2547 /* Try to open the dynamic library. */
2548 if (dlname)
2549 {
2550 /* try to open the installed module */
2551 if (installed && libdir)
2552 {
2553 if (tryall_dlopen_module (handle,
2554 (const char *) 0, libdir, dlname) == 0)
2555 return 0;
2556 }
2557
2558 /* try to open the not-installed module */
2559 if (!installed)
2560 {
2561 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2562 return 0;
2563 }
2564
2565 /* maybe it was moved to another directory */
2566 {
2567 if (tryall_dlopen_module (handle, (const char *) 0, dir, dlname) == 0)
2568 return 0;
2569 }
2570 }
2571
2572 return 1;
2573}
2574
2575
2576static int
2577canonicalize_path (path, pcanonical)
2578 const char *path;
2579 char **pcanonical;
2580{
2581 char *canonical = 0;
2582
2583 assert (path && *path);
2584 assert (pcanonical);
2585
2586 canonical = LT_EGNUNET_malloc (char, 1 + LT_STRLEN (path));
2587 if (!canonical)
2588 return 1;
2589
2590 {
2591 size_t dest = 0;
2592 size_t src;
2593 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2594 {
2595 /* Path separators are not copied to the beginning or end of
2596 the destination, or if another separator would follow
2597 immediately. */
2598 if (path[src] == LT_PATHSEP_CHAR)
2599 {
2600 if ((dest == 0)
2601 || (path[1 + src] == LT_PATHSEP_CHAR)
2602 || (path[1 + src] == LT_EOS_CHAR))
2603 continue;
2604 }
2605
2606 /* Anything other than a directory separator is copied verbatim. */
2607 if ((path[src] != '/')
2608#ifdef LT_DIRSEP_CHAR
2609 && (path[src] != LT_DIRSEP_CHAR)
2610#endif
2611 )
2612 {
2613 canonical[dest++] = path[src];
2614 }
2615 /* Directory separators are converted and copied only if they are
2616 not at the end of a path -- i.e. before a path separator or
2617 NULL terminator. */
2618 else if ((path[1 + src] != LT_PATHSEP_CHAR)
2619 && (path[1 + src] != LT_EOS_CHAR)
2620#ifdef LT_DIRSEP_CHAR
2621 && (path[1 + src] != LT_DIRSEP_CHAR)
2622#endif
2623 && (path[1 + src] != '/'))
2624 {
2625 canonical[dest++] = '/';
2626 }
2627 }
2628
2629 /* Add an end-of-string marker at the end. */
2630 canonical[dest] = LT_EOS_CHAR;
2631 }
2632
2633 /* Assign new value. */
2634 *pcanonical = canonical;
2635
2636 return 0;
2637}
2638
2639static int
2640argzize_path (path, pargz, pargz_len)
2641 const char *path;
2642 char **pargz;
2643 size_t *pargz_len;
2644{
2645 error_t error;
2646
2647 assert (path);
2648 assert (pargz);
2649 assert (pargz_len);
2650
2651 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2652 {
2653 switch (error)
2654 {
2655 case ENOMEM:
2656 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2657 break;
2658 default:
2659 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2660 break;
2661 }
2662
2663 return 1;
2664 }
2665
2666 return 0;
2667}
2668
2669/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2670 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2671 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2672 it is appended to each SEARCH_PATH element before FUNC is called. */
2673static int
2674foreach_dirinpath (search_path, base_name, func, data1, data2)
2675 const char *search_path;
2676 const char *base_name;
2677 foreach_callback_func *func;
2678 lt_ptr data1;
2679 lt_ptr data2;
2680{
2681 int result = 0;
2682 int filenamesize = 0;
2683 size_t lenbase = LT_STRLEN (base_name);
2684 size_t argz_len = 0;
2685 char *argz = 0;
2686 char *filename = 0;
2687 char *canonical = 0;
2688
2689 LT_DLGNUNET_mutex_lock ();
2690
2691 if (!search_path || !*search_path)
2692 {
2693 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2694 goto cleanup;
2695 }
2696
2697 if (canonicalize_path (search_path, &canonical) != 0)
2698 goto cleanup;
2699
2700 if (argzize_path (canonical, &argz, &argz_len) != 0)
2701 goto cleanup;
2702
2703 {
2704 char *dir_name = 0;
2705 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2706 {
2707 size_t lendir = LT_STRLEN (dir_name);
2708
2709 if (lendir + 1 + lenbase >= filenamesize)
2710 {
2711 LT_DLGNUNET_free (filename);
2712 filenamesize = lendir + 1 + lenbase + 1; /* "/d" + '/' + "f" + '\0' */
2713 filename = LT_EGNUNET_malloc (char, filenamesize);
2714 if (!filename)
2715 goto cleanup;
2716 }
2717
2718 assert (filenamesize > lendir);
2719 strcpy (filename, dir_name);
2720
2721 if (base_name && *base_name)
2722 {
2723 if (filename[lendir - 1] != '/')
2724 filename[lendir++] = '/';
2725 strcpy (filename + lendir, base_name);
2726 }
2727
2728 if ((result = (*func) (filename, data1, data2)))
2729 {
2730 break;
2731 }
2732 }
2733 }
2734
2735cleanup:
2736 LT_DLGNUNET_free (argz);
2737 LT_DLGNUNET_free (canonical);
2738 LT_DLGNUNET_free (filename);
2739
2740 LT_DLMUTEX_UNLOCK ();
2741
2742 return result;
2743}
2744
2745/* If FILEPATH can be opened, store the name of the directory component
2746 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2747 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2748static int
2749find_file_callback (filename, data1, data2)
2750 char *filename;
2751 lt_ptr data1;
2752 lt_ptr data2;
2753{
2754 char **pdir = (char **) data1;
2755 FILE **pfile = (FILE **) data2;
2756 int is_done = 0;
2757
2758 assert (filename && *filename);
2759 assert (pdir);
2760 assert (pfile);
2761
2762 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2763 {
2764 char *dirend = strrchr (filename, '/');
2765
2766 if (dirend > filename)
2767 *dirend = LT_EOS_CHAR;
2768
2769 LT_DLGNUNET_free (*pdir);
2770 *pdir = lt_estrdup (filename);
2771 is_done = (*pdir == 0) ? -1 : 1;
2772 }
2773
2774 return is_done;
2775}
2776
2777static FILE *
2778find_file (search_path, base_name, pdir)
2779 const char *search_path;
2780 const char *base_name;
2781 char **pdir;
2782{
2783 FILE *file = 0;
2784
2785 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2786
2787 return file;
2788}
2789
2790static int
2791find_handle_callback (filename, data, ignored)
2792 char *filename;
2793 lt_ptr data;
2794 lt_ptr ignored;
2795{
2796 lt_dlhandle *handle = (lt_dlhandle *) data;
2797 int notfound = access (filename, R_OK);
2798
2799 /* Bail out if file cannot be read... */
2800 if (notfound)
2801 return 0;
2802
2803 /* Try to dlopen the file, but do not continue searching in any
2804 case. */
2805 if (tryall_dlopen (handle, filename) != 0)
2806 *handle = 0;
2807
2808 return 1;
2809}
2810
2811/* If HANDLE was found return it, otherwise return 0. If HANDLE was
2812 found but could not be opened, *HANDLE will be set to 0. */
2813static lt_dlhandle *
2814find_handle (search_path, base_name, handle)
2815 const char *search_path;
2816 const char *base_name;
2817 lt_dlhandle *handle;
2818{
2819 if (!search_path)
2820 return 0;
2821
2822 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2823 handle, 0))
2824 return 0;
2825
2826 return handle;
2827}
2828
2829static int
2830load_deplibs (handle, deplibs)
2831 lt_dlhandle handle;
2832 char *deplibs;
2833{
2834#if LTDL_DLOPEN_DEPLIBS
2835 char *p, *save_search_path = 0;
2836 int depcount = 0;
2837 int i;
2838 char **names = 0;
2839#endif
2840 int errors = 0;
2841
2842 handle->depcount = 0;
2843
2844#if LTDL_DLOPEN_DEPLIBS
2845 if (!deplibs)
2846 {
2847 return errors;
2848 }
2849 ++errors;
2850
2851 LT_DLGNUNET_mutex_lock ();
2852 if (user_search_path)
2853 {
2854 save_search_path = lt_estrdup (user_search_path);
2855 if (!save_search_path)
2856 goto cleanup;
2857 }
2858
2859 /* extract search paths and count deplibs */
2860 p = deplibs;
2861 while (*p)
2862 {
2863 if (!isspace ((int) *p))
2864 {
2865 char *end = p + 1;
2866 while (*end && !isspace ((int) *end))
2867 {
2868 ++end;
2869 }
2870
2871 if (strncmp (p, "-L", 2) == 0 || strncmp (p, "-R", 2) == 0)
2872 {
2873 char save = *end;
2874 *end = 0; /* set a temporary string terminator */
2875 if (lt_dladdsearchdir (p + 2))
2876 {
2877 goto cleanup;
2878 }
2879 *end = save;
2880 }
2881 else
2882 {
2883 ++depcount;
2884 }
2885
2886 p = end;
2887 }
2888 else
2889 {
2890 ++p;
2891 }
2892 }
2893
2894 /* restore the old search path */
2895 LT_DLGNUNET_free (user_search_path);
2896 user_search_path = save_search_path;
2897
2898 LT_DLMUTEX_UNLOCK ();
2899
2900 if (!depcount)
2901 {
2902 errors = 0;
2903 goto cleanup;
2904 }
2905
2906 names = LT_EGNUNET_malloc (char *, depcount * sizeof (char *));
2907 if (!names)
2908 goto cleanup;
2909
2910 /* now only extract the actual deplibs */
2911 depcount = 0;
2912 p = deplibs;
2913 while (*p)
2914 {
2915 if (isspace ((int) *p))
2916 {
2917 ++p;
2918 }
2919 else
2920 {
2921 char *end = p + 1;
2922 while (*end && !isspace ((int) *end))
2923 {
2924 ++end;
2925 }
2926
2927 if (strncmp (p, "-L", 2) != 0 && strncmp (p, "-R", 2) != 0)
2928 {
2929 char *name;
2930 char save = *end;
2931 *end = 0; /* set a temporary string terminator */
2932 if (strncmp (p, "-l", 2) == 0)
2933 {
2934 size_t name_len = 3 + /* "lib" */ LT_STRLEN (p + 2);
2935 name = LT_EGNUNET_malloc (char, 1 + name_len);
2936 if (name)
2937 sprintf (name, "lib%s", p + 2);
2938 }
2939 else
2940 name = lt_estrdup (p);
2941
2942 if (!name)
2943 goto cleanup_names;
2944
2945 names[depcount++] = name;
2946 *end = save;
2947 }
2948 p = end;
2949 }
2950 }
2951
2952 /* load the deplibs (in reverse order)
2953 At this stage, don't worry if the deplibs do not load correctly,
2954 they may already be statically linked into the loading application
2955 for instance. There will be a more enlightening error message
2956 later on if the loaded module cannot resolve all of its symbols. */
2957 if (depcount)
2958 {
2959 int j = 0;
2960
2961 handle->deplibs =
2962 (lt_dlhandle *) LT_EGNUNET_malloc (lt_dlhandle *, depcount);
2963 if (!handle->deplibs)
2964 goto cleanup;
2965
2966 for (i = 0; i < depcount; ++i)
2967 {
2968 handle->deplibs[j] = lt_dlopenext (names[depcount - 1 - i]);
2969 if (handle->deplibs[j])
2970 {
2971 ++j;
2972 }
2973 }
2974
2975 handle->depcount = j; /* Number of successfully loaded deplibs */
2976 errors = 0;
2977 }
2978
2979cleanup_names:
2980 for (i = 0; i < depcount; ++i)
2981 {
2982 LT_DLGNUNET_free (names[i]);
2983 }
2984
2985cleanup:
2986 LT_DLGNUNET_free (names);
2987#endif
2988
2989 return errors;
2990}
2991
2992static int
2993unload_deplibs (handle)
2994 lt_dlhandle handle;
2995{
2996 int i;
2997 int errors = 0;
2998
2999 if (handle->depcount)
3000 {
3001 for (i = 0; i < handle->depcount; ++i)
3002 {
3003 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
3004 {
3005 errors += lt_dlclose (handle->deplibs[i]);
3006 }
3007 }
3008 }
3009
3010 return errors;
3011}
3012
3013static int
3014trim (dest, str)
3015 char **dest;
3016 const char *str;
3017{
3018 /* remove the leading and trailing "'" from str
3019 and store the result in dest */
3020 const char *end = strrchr (str, '\'');
3021 size_t len = LT_STRLEN (str);
3022 char *tmp;
3023
3024 LT_DLGNUNET_free (*dest);
3025
3026 if (len > 3 && str[0] == '\'')
3027 {
3028 tmp = LT_EGNUNET_malloc (char, end - str);
3029 if (!tmp)
3030 return 1;
3031
3032 strncpy (tmp, &str[1], (end - str) - 1);
3033 tmp[len - 3] = LT_EOS_CHAR;
3034 *dest = tmp;
3035 }
3036 else
3037 {
3038 *dest = 0;
3039 }
3040
3041 return 0;
3042}
3043
3044static int
3045free_vars (dlname, oldname, libdir, deplibs)
3046 char *dlname;
3047 char *oldname;
3048 char *libdir;
3049 char *deplibs;
3050{
3051 LT_DLGNUNET_free (dlname);
3052 LT_DLGNUNET_free (oldname);
3053 LT_DLGNUNET_free (libdir);
3054 LT_DLGNUNET_free (deplibs);
3055
3056 return 0;
3057}
3058
3059static int
3060try_dlopen (phandle, filename)
3061 lt_dlhandle *phandle;
3062 const char *filename;
3063{
3064 const char *ext = 0;
3065 const char *saved_error = 0;
3066 char *canonical = 0;
3067 char *base_name = 0;
3068 char *dir = 0;
3069 char *name = 0;
3070 int errors = 0;
3071 lt_dlhandle newhandle;
3072
3073 assert (phandle);
3074 assert (*phandle == 0);
3075
3076 LT_DLMUTEX_GETERROR (saved_error);
3077
3078 /* dlopen self? */
3079 if (!filename)
3080 {
3081 *phandle =
3082 (lt_dlhandle) LT_EGNUNET_malloc (struct lt_dlhandle_struct, 1);
3083 if (*phandle == 0)
3084 return 1;
3085
3086 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3087 newhandle = *phandle;
3088
3089 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3090 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3091
3092 if (tryall_dlopen (&newhandle, 0) != 0)
3093 {
3094 LT_DLGNUNET_free (*phandle);
3095 return 1;
3096 }
3097
3098 goto register_handle;
3099 }
3100
3101 assert (filename && *filename);
3102
3103 /* Doing this immediately allows internal functions to safely
3104 assume only canonicalized paths are passed. */
3105 if (canonicalize_path (filename, &canonical) != 0)
3106 {
3107 ++errors;
3108 goto cleanup;
3109 }
3110
3111 /* If the canonical module name is a path (relative or absolute)
3112 then split it into a directory part and a name part. */
3113 base_name = strrchr (canonical, '/');
3114 if (base_name)
3115 {
3116 size_t dirlen = (1 + base_name) - canonical;
3117
3118 dir = LT_EGNUNET_malloc (char, 1 + dirlen);
3119 if (!dir)
3120 {
3121 ++errors;
3122 goto cleanup;
3123 }
3124
3125 strncpy (dir, canonical, dirlen);
3126 dir[dirlen] = LT_EOS_CHAR;
3127
3128 ++base_name;
3129 }
3130 else
3131 base_name = canonical;
3132
3133 assert (base_name && *base_name);
3134
3135 /* Check whether we are opening a libtool module (.la extension). */
3136 ext = strrchr (base_name, '.');
3137 if (ext && strcmp (ext, archive_ext) == 0)
3138 {
3139 /* this seems to be a libtool module */
3140 FILE *file = 0;
3141 char *dlname = 0;
3142 char *old_name = 0;
3143 char *libdir = 0;
3144 char *deplibs = 0;
3145 char *line = 0;
3146 size_t line_len;
3147
3148 /* if we can't find the installed flag, it is probably an
3149 installed libtool archive, produced with an old version
3150 of libtool */
3151 int installed = 1;
3152
3153 /* extract the module name from the file name */
3154 name = LT_EGNUNET_malloc (char, ext - base_name + 1);
3155 if (!name)
3156 {
3157 ++errors;
3158 goto cleanup;
3159 }
3160
3161 /* canonicalize the module name */
3162 {
3163 size_t i;
3164 for (i = 0; i < ext - base_name; ++i)
3165 {
3166 if (isalnum ((int) (base_name[i])))
3167 {
3168 name[i] = base_name[i];
3169 }
3170 else
3171 {
3172 name[i] = '_';
3173 }
3174 }
3175 name[ext - base_name] = LT_EOS_CHAR;
3176 }
3177
3178 /* Now try to open the .la file. If there is no directory name
3179 component, try to find it first in user_search_path and then other
3180 prescribed paths. Otherwise (or in any case if the module was not
3181 yet found) try opening just the module name as passed. */
3182 if (!dir)
3183 {
3184 const char *search_path;
3185
3186 LT_DLGNUNET_mutex_lock ();
3187 search_path = user_search_path;
3188 if (search_path)
3189 file = find_file (user_search_path, base_name, &dir);
3190 LT_DLMUTEX_UNLOCK ();
3191
3192 if (!file)
3193 {
3194 search_path = getenv (LTDL_SEARCHPATH_VAR);
3195 if (search_path)
3196 file = find_file (search_path, base_name, &dir);
3197 }
3198
3199#ifdef LTDL_SHLIBPATH_VAR
3200 if (!file)
3201 {
3202 search_path = getenv (LTDL_SHLIBPATH_VAR);
3203 if (search_path)
3204 file = find_file (search_path, base_name, &dir);
3205 }
3206#endif
3207#ifdef LTDL_SYSSEARCHPATH
3208 if (!file && sys_search_path)
3209 {
3210 file = find_file (sys_search_path, base_name, &dir);
3211 }
3212#endif
3213 }
3214 if (!file)
3215 {
3216 file = fopen (filename, LT_READTEXT_MODE);
3217 }
3218
3219 /* If we didn't find the file by now, it really isn't there. Set
3220 the status flag, and bail out. */
3221 if (!file)
3222 {
3223 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3224 ++errors;
3225 goto cleanup;
3226 }
3227
3228 line_len = LT_FILENAME_MAX;
3229 line = LT_EGNUNET_malloc (char, line_len);
3230 if (!line)
3231 {
3232 fclose (file);
3233 ++errors;
3234 goto cleanup;
3235 }
3236
3237 /* read the .la file */
3238 while (!feof (file))
3239 {
3240 if (!fgets (line, (int) line_len, file))
3241 {
3242 break;
3243 }
3244
3245 /* Handle the case where we occasionally need to read a line
3246 that is longer than the initial buffer size. */
3247 while ((line[LT_STRLEN (line) - 1] != '\n') && (!feof (file)))
3248 {
3249 line = LT_DLREALLOC (char, line, line_len * 2);
3250 if (!fgets (&line[line_len - 1], (int) line_len + 1, file))
3251 {
3252 break;
3253 }
3254 line_len *= 2;
3255 }
3256
3257 if (line[0] == '\n' || line[0] == '#')
3258 {
3259 continue;
3260 }
3261
3262#undef STR_DLNAME
3263#define STR_DLNAME "dlname="
3264 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3265 {
3266 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3267 }
3268
3269#undef STR_OLD_LIBRARY
3270#define STR_OLD_LIBRARY "old_library="
3271 else if (strncmp (line, STR_OLD_LIBRARY,
3272 sizeof (STR_OLD_LIBRARY) - 1) == 0)
3273 {
3274 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3275 }
3276#undef STR_LIBDIR
3277#define STR_LIBDIR "libdir="
3278 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3279 {
3280 errors += trim (&libdir, &line[sizeof (STR_LIBDIR) - 1]);
3281 }
3282
3283#undef STR_DL_DEPLIBS
3284#define STR_DL_DEPLIBS "dependency_libs="
3285 else if (strncmp (line, STR_DL_DEPLIBS,
3286 sizeof (STR_DL_DEPLIBS) - 1) == 0)
3287 {
3288 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3289 }
3290 else if (strcmp (line, "installed=yes\n") == 0)
3291 {
3292 installed = 1;
3293 }
3294 else if (strcmp (line, "installed=no\n") == 0)
3295 {
3296 installed = 0;
3297 }
3298
3299#undef STR_LIBRARY_NAMES
3300#define STR_LIBRARY_NAMES "library_names="
3301 else if (!dlname && strncmp (line, STR_LIBRARY_NAMES,
3302 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3303 {
3304 char *last_libname;
3305 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3306 if (!errors
3307 && dlname && (last_libname = strrchr (dlname, ' ')) != 0)
3308 {
3309 last_libname = lt_estrdup (last_libname + 1);
3310 if (!last_libname)
3311 {
3312 ++errors;
3313 goto cleanup;
3314 }
3315 LT_DLMEM_REASSIGN (dlname, last_libname);
3316 }
3317 }
3318
3319 if (errors)
3320 break;
3321 }
3322
3323 fclose (file);
3324 LT_DLGNUNET_free (line);
3325
3326 /* allocate the handle */
3327 *phandle =
3328 (lt_dlhandle) LT_EGNUNET_malloc (struct lt_dlhandle_struct, 1);
3329 if (*phandle == 0)
3330 ++errors;
3331
3332 if (errors)
3333 {
3334 free_vars (dlname, old_name, libdir, deplibs);
3335 LT_DLGNUNET_free (*phandle);
3336 goto cleanup;
3337 }
3338
3339 assert (*phandle);
3340
3341 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3342 if (load_deplibs (*phandle, deplibs) == 0)
3343 {
3344 newhandle = *phandle;
3345 /* find_module may replace newhandle */
3346 if (find_module
3347 (&newhandle, dir, libdir, dlname, old_name, installed))
3348 {
3349 unload_deplibs (*phandle);
3350 ++errors;
3351 }
3352 }
3353 else
3354 {
3355 ++errors;
3356 }
3357
3358 free_vars (dlname, old_name, libdir, deplibs);
3359 if (errors)
3360 {
3361 LT_DLGNUNET_free (*phandle);
3362 goto cleanup;
3363 }
3364
3365 if (*phandle != newhandle)
3366 {
3367 unload_deplibs (*phandle);
3368 }
3369 }
3370 else
3371 {
3372 /* not a libtool module */
3373 *phandle =
3374 (lt_dlhandle) LT_EGNUNET_malloc (struct lt_dlhandle_struct, 1);
3375 if (*phandle == 0)
3376 {
3377 ++errors;
3378 goto cleanup;
3379 }
3380
3381 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3382 newhandle = *phandle;
3383
3384 /* If the module has no directory name component, try to find it
3385 first in user_search_path and then other prescribed paths.
3386 Otherwise (or in any case if the module was not yet found) try
3387 opening just the module name as passed. */
3388 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3389 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3390 &newhandle)
3391#ifdef LTDL_SHLIBPATH_VAR
3392 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3393 &newhandle)
3394#endif
3395#ifdef LTDL_SYSSEARCHPATH
3396 && !find_handle (sys_search_path, base_name, &newhandle)
3397#endif
3398 )))
3399 {
3400 if (tryall_dlopen (&newhandle, filename) != 0)
3401 {
3402 newhandle = NULL;
3403 }
3404 }
3405
3406 if (!newhandle)
3407 {
3408 LT_DLGNUNET_free (*phandle);
3409 ++errors;
3410 goto cleanup;
3411 }
3412 }
3413
3414register_handle:
3415 LT_DLMEM_REASSIGN (*phandle, newhandle);
3416
3417 if ((*phandle)->info.ref_count == 0)
3418 {
3419 (*phandle)->info.ref_count = 1;
3420 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3421
3422 LT_DLGNUNET_mutex_lock ();
3423 (*phandle)->next = handles;
3424 handles = *phandle;
3425 LT_DLMUTEX_UNLOCK ();
3426 }
3427
3428 LT_DLMUTEX_SETERROR (saved_error);
3429
3430cleanup:
3431 LT_DLGNUNET_free (dir);
3432 LT_DLGNUNET_free (name);
3433 LT_DLGNUNET_free (canonical);
3434
3435 return errors;
3436}
3437
3438lt_dlhandle
3439lt_dlopen (filename)
3440 const char *filename;
3441{
3442 lt_dlhandle handle = 0;
3443
3444 /* Just incase we missed a code path in try_dlopen() that reports
3445 an error, but forgets to reset handle... */
3446 if (try_dlopen (&handle, filename) != 0)
3447 return 0;
3448
3449 return handle;
3450}
3451
3452/* If the last error messge store was `FILE_NOT_FOUND', then return
3453 non-zero. */
3454static int
3455file_not_found ()
3456{
3457 const char *error = 0;
3458
3459 LT_DLMUTEX_GETERROR (error);
3460 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3461 return 1;
3462
3463 return 0;
3464}
3465
3466/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3467 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3468 and if a file is still not found try again with SHLIB_EXT appended
3469 instead. */
3470lt_dlhandle
3471lt_dlopenext (filename)
3472 const char *filename;
3473{
3474 lt_dlhandle handle = 0;
3475 char *tmp = 0;
3476 char *ext = 0;
3477 size_t len;
3478 int errors = 0;
3479
3480 if (!filename)
3481 {
3482 return lt_dlopen (filename);
3483 }
3484
3485 assert (filename);
3486
3487 len = LT_STRLEN (filename);
3488 ext = strrchr (filename, '.');
3489
3490 /* If FILENAME already bears a suitable extension, there is no need
3491 to try appending additional extensions. */
3492 if (ext && ((strcmp (ext, archive_ext) == 0)
3493#ifdef LTDL_SHLIB_EXT
3494 || (strcmp (ext, shlib_ext) == 0)
3495#endif
3496 ))
3497 {
3498 return lt_dlopen (filename);
3499 }
3500
3501 /* First try appending ARCHIVE_EXT. */
3502 tmp = LT_EGNUNET_malloc (char, len + LT_STRLEN (archive_ext) + 1);
3503 if (!tmp)
3504 return 0;
3505
3506 strcpy (tmp, filename);
3507 strcat (tmp, archive_ext);
3508 errors = try_dlopen (&handle, tmp);
3509
3510 /* If we found FILENAME, stop searching -- whether we were able to
3511 load the file as a module or not. If the file exists but loading
3512 failed, it is better to return an error message here than to
3513 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3514 in the module search path. */
3515 if (handle || ((errors > 0) && !file_not_found ()))
3516 {
3517 LT_DLGNUNET_free (tmp);
3518 return handle;
3519 }
3520
3521#ifdef LTDL_SHLIB_EXT
3522 /* Try appending SHLIB_EXT. */
3523 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3524 {
3525 LT_DLGNUNET_free (tmp);
3526 tmp = LT_EGNUNET_malloc (char, len + LT_STRLEN (shlib_ext) + 1);
3527 if (!tmp)
3528 return 0;
3529
3530 strcpy (tmp, filename);
3531 }
3532 else
3533 {
3534 tmp[len] = LT_EOS_CHAR;
3535 }
3536
3537 strcat (tmp, shlib_ext);
3538 errors = try_dlopen (&handle, tmp);
3539
3540 /* As before, if the file was found but loading failed, return now
3541 with the current error message. */
3542 if (handle || ((errors > 0) && !file_not_found ()))
3543 {
3544 LT_DLGNUNET_free (tmp);
3545 return handle;
3546 }
3547#endif
3548
3549 /* Still here? Then we really did fail to locate any of the file
3550 names we tried. */
3551 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3552 LT_DLGNUNET_free (tmp);
3553 return 0;
3554}
3555
3556
3557static int
3558lt_argz_insert (pargz, pargz_len, before, entry)
3559 char **pargz;
3560 size_t *pargz_len;
3561 char *before;
3562 const char *entry;
3563{
3564 error_t error;
3565
3566 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3567 {
3568 switch (error)
3569 {
3570 case ENOMEM:
3571 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3572 break;
3573 default:
3574 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3575 break;
3576 }
3577 return 1;
3578 }
3579
3580 return 0;
3581}
3582
3583static int
3584lt_argz_insertinorder (pargz, pargz_len, entry)
3585 char **pargz;
3586 size_t *pargz_len;
3587 const char *entry;
3588{
3589 char *before = 0;
3590
3591 assert (pargz);
3592 assert (pargz_len);
3593 assert (entry && *entry);
3594
3595 if (*pargz)
3596 while ((before = argz_next (*pargz, *pargz_len, before)))
3597 {
3598 int cmp = strcmp (entry, before);
3599
3600 if (cmp < 0)
3601 break;
3602 if (cmp == 0)
3603 return 0; /* No duplicates! */
3604 }
3605
3606 return lt_argz_insert (pargz, pargz_len, before, entry);
3607}
3608
3609static int
3610lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3611 char **pargz;
3612 size_t *pargz_len;
3613 const char *dirnam;
3614 struct dirent *dp;
3615{
3616 char *buf = 0;
3617 size_t buf_len = 0;
3618 char *end = 0;
3619 size_t end_offset = 0;
3620 size_t dir_len = 0;
3621 int errors = 0;
3622
3623 assert (pargz);
3624 assert (pargz_len);
3625 assert (dp);
3626
3627 dir_len = LT_STRLEN (dirnam);
3628 end = dp->d_name + LT_D_NAMLEN (dp);
3629
3630 /* Ignore version numbers. */
3631 {
3632 char *p;
3633 for (p = end; p - 1 > dp->d_name; --p)
3634 if (strchr (".0123456789", p[-1]) == 0)
3635 break;
3636
3637 if (*p == '.')
3638 end = p;
3639 }
3640
3641 /* Ignore filename extension. */
3642 {
3643 char *p;
3644 for (p = end - 1; p > dp->d_name; --p)
3645 if (*p == '.')
3646 {
3647 end = p;
3648 break;
3649 }
3650 }
3651
3652 /* Prepend the directory name. */
3653 end_offset = end - dp->d_name;
3654 buf_len = dir_len + 1 + end_offset;
3655 buf = LT_EGNUNET_malloc (char, 1 + buf_len);
3656 if (!buf)
3657 return ++errors;
3658
3659 assert (buf);
3660
3661 strcpy (buf, dirnam);
3662 strcat (buf, "/");
3663 strncat (buf, dp->d_name, end_offset);
3664 buf[buf_len] = LT_EOS_CHAR;
3665
3666 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3667 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3668 ++errors;
3669
3670 LT_DLGNUNET_free (buf);
3671
3672 return errors;
3673}
3674
3675static int
3676list_files_by_dir (dirnam, pargz, pargz_len)
3677 const char *dirnam;
3678 char **pargz;
3679 size_t *pargz_len;
3680{
3681 DIR *dirp = 0;
3682 int errors = 0;
3683
3684 assert (dirnam && *dirnam);
3685 assert (pargz);
3686 assert (pargz_len);
3687 assert (dirnam[LT_STRLEN (dirnam) - 1] != '/');
3688
3689 dirp = opendir (dirnam);
3690 if (dirp)
3691 {
3692 struct dirent *dp = 0;
3693
3694 while ((dp = readdir (dirp)))
3695 if (dp->d_name[0] != '.')
3696 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3697 {
3698 ++errors;
3699 break;
3700 }
3701
3702 closedir (dirp);
3703 }
3704 else
3705 ++errors;
3706
3707 return errors;
3708}
3709
3710
3711/* If there are any files in DIRNAME, call the function passed in
3712 DATA1 (with the name of each file and DATA2 as arguments). */
3713static int
3714foreachfile_callback (dirname, data1, data2)
3715 char *dirname;
3716 lt_ptr data1;
3717 lt_ptr data2;
3718{
3719 int (*func) LT_PARAMS ((const char *filename, lt_ptr data))
3720 = (int (*)LT_PARAMS ((const char *filename, lt_ptr data))) data1;
3721
3722 int is_done = 0;
3723 char *argz = 0;
3724 size_t argz_len = 0;
3725
3726 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3727 goto cleanup;
3728 if (!argz)
3729 goto cleanup;
3730
3731 {
3732 char *filename = 0;
3733 while ((filename = argz_next (argz, argz_len, filename)))
3734 if ((is_done = (*func) (filename, data2)))
3735 break;
3736 }
3737
3738cleanup:
3739 LT_DLGNUNET_free (argz);
3740
3741 return is_done;
3742}
3743
3744
3745/* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3746 with DATA. The filenames passed to FUNC would be suitable for
3747 passing to lt_dlopenext. The extensions are stripped so that
3748 individual modules do not generate several entries (e.g. libfoo.la,
3749 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3750 then the same directories that lt_dlopen would search are examined. */
3751int
3752lt_dlforeachfile (search_path, func, data)
3753 const char *search_path;
3754 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3755 lt_ptr data;
3756{
3757 int is_done = 0;
3758
3759 if (search_path)
3760 {
3761 /* If a specific path was passed, search only the directories
3762 listed in it. */
3763 is_done = foreach_dirinpath (search_path, 0,
3764 foreachfile_callback, func, data);
3765 }
3766 else
3767 {
3768 /* Otherwise search the default paths. */
3769 is_done = foreach_dirinpath (user_search_path, 0,
3770 foreachfile_callback, func, data);
3771 if (!is_done)
3772 {
3773 is_done = foreach_dirinpath (getenv ("LTDL_LIBRARY_PATH"), 0,
3774 foreachfile_callback, func, data);
3775 }
3776
3777#ifdef LTDL_SHLIBPATH_VAR
3778 if (!is_done)
3779 {
3780 is_done = foreach_dirinpath (getenv (LTDL_SHLIBPATH_VAR), 0,
3781 foreachfile_callback, func, data);
3782 }
3783#endif
3784#ifdef LTDL_SYSSEARCHPATH
3785 if (!is_done)
3786 {
3787 is_done = foreach_dirinpath (getenv (LTDL_SYSSEARCHPATH), 0,
3788 foreachfile_callback, func, data);
3789 }
3790#endif
3791 }
3792
3793 return is_done;
3794}
3795
3796int
3797lt_dlclose (handle)
3798 lt_dlhandle handle;
3799{
3800 lt_dlhandle cur, last;
3801 int errors = 0;
3802
3803 LT_DLGNUNET_mutex_lock ();
3804
3805 /* check whether the handle is valid */
3806 last = cur = handles;
3807 while (cur && handle != cur)
3808 {
3809 last = cur;
3810 cur = cur->next;
3811 }
3812
3813 if (!cur)
3814 {
3815 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3816 ++errors;
3817 goto done;
3818 }
3819
3820 handle->info.ref_count--;
3821
3822 /* Note that even with resident modules, we must track the ref_count
3823 correctly incase the user decides to reset the residency flag
3824 later (even though the API makes no provision for that at the
3825 moment). */
3826 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3827 {
3828 lt_user_data data = handle->loader->dlloader_data;
3829
3830 if (handle != handles)
3831 {
3832 last->next = handle->next;
3833 }
3834 else
3835 {
3836 handles = handle->next;
3837 }
3838
3839 errors += handle->loader->module_close (data, handle->module);
3840 errors += unload_deplibs (handle);
3841
3842 /* It is up to the callers to free the data itself. */
3843 LT_DLGNUNET_free (handle->caller_data);
3844
3845 LT_DLGNUNET_free (handle->info.filename);
3846 LT_DLGNUNET_free (handle->info.name);
3847 LT_DLGNUNET_free (handle);
3848
3849 goto done;
3850 }
3851
3852 if (LT_DLIS_RESIDENT (handle))
3853 {
3854 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3855 ++errors;
3856 }
3857
3858done:
3859 LT_DLMUTEX_UNLOCK ();
3860
3861 return errors;
3862}
3863
3864lt_ptr
3865lt_dlsym (handle, symbol)
3866 lt_dlhandle handle;
3867 const char *symbol;
3868{
3869 size_t lensym;
3870 char lsym[LT_SYMBOL_LENGTH];
3871 char *sym;
3872 lt_ptr address;
3873 lt_user_data data;
3874
3875 if (!handle)
3876 {
3877 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3878 return 0;
3879 }
3880
3881 if (!symbol)
3882 {
3883 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3884 return 0;
3885 }
3886
3887 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3888 + LT_STRLEN (handle->info.name);
3889
3890 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3891 {
3892 sym = lsym;
3893 }
3894 else
3895 {
3896 sym = LT_EGNUNET_malloc (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3897 if (!sym)
3898 {
3899 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3900 return 0;
3901 }
3902 }
3903
3904 data = handle->loader->dlloader_data;
3905 if (handle->info.name)
3906 {
3907 const char *saved_error;
3908
3909 LT_DLMUTEX_GETERROR (saved_error);
3910
3911 /* this is a libtool module */
3912 if (handle->loader->sym_prefix)
3913 {
3914 strcpy (sym, handle->loader->sym_prefix);
3915 strcat (sym, handle->info.name);
3916 }
3917 else
3918 {
3919 strcpy (sym, handle->info.name);
3920 }
3921
3922 strcat (sym, "_LTX_");
3923 strcat (sym, symbol);
3924
3925 /* try "modulename_LTX_symbol" */
3926 address = handle->loader->find_sym (data, handle->module, sym);
3927 if (address)
3928 {
3929 if (sym != lsym)
3930 {
3931 LT_DLGNUNET_free (sym);
3932 }
3933 return address;
3934 }
3935 LT_DLMUTEX_SETERROR (saved_error);
3936 }
3937
3938 /* otherwise try "symbol" */
3939 if (handle->loader->sym_prefix)
3940 {
3941 strcpy (sym, handle->loader->sym_prefix);
3942 strcat (sym, symbol);
3943 }
3944 else
3945 {
3946 strcpy (sym, symbol);
3947 }
3948
3949 address = handle->loader->find_sym (data, handle->module, sym);
3950 if (sym != lsym)
3951 {
3952 LT_DLGNUNET_free (sym);
3953 }
3954
3955 return address;
3956}
3957
3958const char *
3959lt_dlerror ()
3960{
3961 const char *error;
3962
3963 LT_DLMUTEX_GETERROR (error);
3964 LT_DLMUTEX_SETERROR (0);
3965
3966 return error ? error : NULL;
3967}
3968
3969static int
3970lt_dlpath_insertdir (ppath, before, dir)
3971 char **ppath;
3972 char *before;
3973 const char *dir;
3974{
3975 int errors = 0;
3976 char *canonical = 0;
3977 char *argz = 0;
3978 size_t argz_len = 0;
3979
3980 assert (ppath);
3981 assert (dir && *dir);
3982
3983 if (canonicalize_path (dir, &canonical) != 0)
3984 {
3985 ++errors;
3986 goto cleanup;
3987 }
3988
3989 assert (canonical && *canonical);
3990
3991 /* If *PPATH is empty, set it to DIR. */
3992 if (*ppath == 0)
3993 {
3994 assert (!before); /* BEFORE cannot be set without PPATH. */
3995 assert (dir); /* Without DIR, don't call this function! */
3996
3997 *ppath = lt_estrdup (dir);
3998 if (*ppath == 0)
3999 ++errors;
4000
4001 return errors;
4002 }
4003
4004 assert (ppath && *ppath);
4005
4006 if (argzize_path (*ppath, &argz, &argz_len) != 0)
4007 {
4008 ++errors;
4009 goto cleanup;
4010 }
4011
4012 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
4013 if *PPATH is already canonicalized, and hence does not change length
4014 with respect to ARGZ. We canonicalize each entry as it is added to
4015 the search path, and don't call this function with (uncanonicalized)
4016 user paths, so this is a fair assumption. */
4017 if (before)
4018 {
4019 assert (*ppath <= before);
4020 assert (before - *ppath <= strlen (*ppath));
4021
4022 before = before - *ppath + argz;
4023 }
4024
4025 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
4026 {
4027 ++errors;
4028 goto cleanup;
4029 }
4030
4031 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4032 LT_DLMEM_REASSIGN (*ppath, argz);
4033
4034cleanup:
4035 LT_DLGNUNET_free (canonical);
4036 LT_DLGNUNET_free (argz);
4037
4038 return errors;
4039}
4040
4041int
4042lt_dladdsearchdir (search_dir)
4043 const char *search_dir;
4044{
4045 int errors = 0;
4046
4047 if (search_dir && *search_dir)
4048 {
4049 LT_DLGNUNET_mutex_lock ();
4050 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4051 ++errors;
4052 LT_DLMUTEX_UNLOCK ();
4053 }
4054
4055 return errors;
4056}
4057
4058int
4059lt_dlinsertsearchdir (before, search_dir)
4060 const char *before;
4061 const char *search_dir;
4062{
4063 int errors = 0;
4064
4065 if (before)
4066 {
4067 LT_DLGNUNET_mutex_lock ();
4068 if ((before < user_search_path)
4069 || (before >= user_search_path + LT_STRLEN (user_search_path)))
4070 {
4071 LT_DLMUTEX_UNLOCK ();
4072 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4073 return 1;
4074 }
4075 LT_DLMUTEX_UNLOCK ();
4076 }
4077
4078 if (search_dir && *search_dir)
4079 {
4080 LT_DLGNUNET_mutex_lock ();
4081 if (lt_dlpath_insertdir (&user_search_path,
4082 (char *) before, search_dir) != 0)
4083 {
4084 ++errors;
4085 }
4086 LT_DLMUTEX_UNLOCK ();
4087 }
4088
4089 return errors;
4090}
4091
4092int
4093lt_dlsetsearchpath (search_path)
4094 const char *search_path;
4095{
4096 int errors = 0;
4097
4098 LT_DLGNUNET_mutex_lock ();
4099 LT_DLGNUNET_free (user_search_path);
4100 LT_DLMUTEX_UNLOCK ();
4101
4102 if (!search_path || !LT_STRLEN (search_path))
4103 {
4104 return errors;
4105 }
4106
4107 LT_DLGNUNET_mutex_lock ();
4108 if (canonicalize_path (search_path, &user_search_path) != 0)
4109 ++errors;
4110 LT_DLMUTEX_UNLOCK ();
4111
4112 return errors;
4113}
4114
4115const char *
4116lt_dlgetsearchpath ()
4117{
4118 const char *saved_path;
4119
4120 LT_DLGNUNET_mutex_lock ();
4121 saved_path = user_search_path;
4122 LT_DLMUTEX_UNLOCK ();
4123
4124 return saved_path;
4125}
4126
4127int
4128lt_dlmakeresident (handle)
4129 lt_dlhandle handle;
4130{
4131 int errors = 0;
4132
4133 if (!handle)
4134 {
4135 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4136 ++errors;
4137 }
4138 else
4139 {
4140 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4141 }
4142
4143 return errors;
4144}
4145
4146int
4147lt_dlisresident (handle)
4148 lt_dlhandle handle;
4149{
4150 if (!handle)
4151 {
4152 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4153 return -1;
4154 }
4155
4156 return LT_DLIS_RESIDENT (handle);
4157}
4158
4159
4160
4161
4162/* --- MODULE INFORMATION --- */
4163
4164const lt_dlinfo *
4165lt_dlgetinfo (handle)
4166 lt_dlhandle handle;
4167{
4168 if (!handle)
4169 {
4170 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4171 return 0;
4172 }
4173
4174 return &(handle->info);
4175}
4176
4177lt_dlhandle
4178lt_dlhandle_next (place)
4179 lt_dlhandle place;
4180{
4181 return place ? place->next : handles;
4182}
4183
4184int
4185lt_dlforeach (func, data)
4186 int (*func) LT_PARAMS ((lt_dlhandle handle, lt_ptr data));
4187 lt_ptr data;
4188{
4189 int errors = 0;
4190 lt_dlhandle cur;
4191
4192 LT_DLGNUNET_mutex_lock ();
4193
4194 cur = handles;
4195 while (cur)
4196 {
4197 lt_dlhandle tmp = cur;
4198
4199 cur = cur->next;
4200 if ((*func) (tmp, data))
4201 {
4202 ++errors;
4203 break;
4204 }
4205 }
4206
4207 LT_DLMUTEX_UNLOCK ();
4208
4209 return errors;
4210}
4211
4212lt_dlcaller_id
4213lt_dlcaller_register ()
4214{
4215 static lt_dlcaller_id last_caller_id = 0;
4216 int result;
4217
4218 LT_DLGNUNET_mutex_lock ();
4219 result = ++last_caller_id;
4220 LT_DLMUTEX_UNLOCK ();
4221
4222 return result;
4223}
4224
4225lt_ptr
4226lt_dlcaller_set_data (key, handle, data)
4227 lt_dlcaller_id key;
4228 lt_dlhandle handle;
4229 lt_ptr data;
4230{
4231 int n_elements = 0;
4232 lt_ptr stale = (lt_ptr) 0;
4233 int i;
4234
4235 /* This needs to be locked so that the caller data can be updated
4236 simultaneously by different threads. */
4237 LT_DLGNUNET_mutex_lock ();
4238
4239 if (handle->caller_data)
4240 while (handle->caller_data[n_elements].key)
4241 ++n_elements;
4242
4243 for (i = 0; i < n_elements; ++i)
4244 {
4245 if (handle->caller_data[i].key == key)
4246 {
4247 stale = handle->caller_data[i].data;
4248 break;
4249 }
4250 }
4251
4252 /* Ensure that there is enough room in this handle's caller_data
4253 array to accept a new element (and an empty end marker). */
4254 if (i == n_elements)
4255 {
4256 lt_caller_data *temp
4257 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2 + n_elements);
4258
4259 if (!temp)
4260 {
4261 stale = 0;
4262 goto done;
4263 }
4264
4265 handle->caller_data = temp;
4266
4267 /* We only need this if we needed to allocate a new caller_data. */
4268 handle->caller_data[i].key = key;
4269 handle->caller_data[1 + i].key = 0;
4270 }
4271
4272 handle->caller_data[i].data = data;
4273
4274done:
4275 LT_DLMUTEX_UNLOCK ();
4276
4277 return stale;
4278}
4279
4280lt_ptr
4281lt_dlcaller_get_data (key, handle)
4282 lt_dlcaller_id key;
4283 lt_dlhandle handle;
4284{
4285 lt_ptr result = (lt_ptr) 0;
4286
4287 /* This needs to be locked so that the caller data isn't updated by
4288 another thread part way through this function. */
4289 LT_DLGNUNET_mutex_lock ();
4290
4291 /* Locate the index of the element with a matching KEY. */
4292 {
4293 int i;
4294 for (i = 0; handle->caller_data[i].key; ++i)
4295 {
4296 if (handle->caller_data[i].key == key)
4297 {
4298 result = handle->caller_data[i].data;
4299 break;
4300 }
4301 }
4302 }
4303
4304 LT_DLMUTEX_UNLOCK ();
4305
4306 return result;
4307}
4308
4309
4310
4311/* --- USER MODULE LOADER API --- */
4312
4313
4314int
4315lt_dlloader_add (place, dlloader, loader_name)
4316 lt_dlloader *place;
4317 const struct lt_user_dlloader *dlloader;
4318 const char *loader_name;
4319{
4320 int errors = 0;
4321 lt_dlloader *node = 0, *ptr = 0;
4322
4323 if ((dlloader == 0) /* diagnose null parameters */
4324 || (dlloader->module_open == 0)
4325 || (dlloader->module_close == 0) || (dlloader->find_sym == 0))
4326 {
4327 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4328 return 1;
4329 }
4330
4331 /* Create a new dlloader node with copies of the user callbacks. */
4332 node = LT_EGNUNET_malloc (lt_dlloader, 1);
4333 if (!node)
4334 return 1;
4335
4336 node->next = 0;
4337 node->loader_name = loader_name;
4338 node->sym_prefix = dlloader->sym_prefix;
4339 node->dlloader_exit = dlloader->dlloader_exit;
4340 node->module_open = dlloader->module_open;
4341 node->module_close = dlloader->module_close;
4342 node->find_sym = dlloader->find_sym;
4343 node->dlloader_data = dlloader->dlloader_data;
4344
4345 LT_DLGNUNET_mutex_lock ();
4346 if (!loaders)
4347 {
4348 /* If there are no loaders, NODE becomes the list! */
4349 loaders = node;
4350 }
4351 else if (!place)
4352 {
4353 /* If PLACE is not set, add NODE to the end of the
4354 LOADERS list. */
4355 for (ptr = loaders; ptr->next; ptr = ptr->next)
4356 {
4357 /*NOWORK*/;
4358 }
4359
4360 ptr->next = node;
4361 }
4362 else if (loaders == place)
4363 {
4364 /* If PLACE is the first loader, NODE goes first. */
4365 node->next = place;
4366 loaders = node;
4367 }
4368 else
4369 {
4370 /* Find the node immediately preceding PLACE. */
4371 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4372 {
4373 /*NOWORK*/;
4374 }
4375
4376 if (ptr->next != place)
4377 {
4378 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4379 ++errors;
4380 }
4381 else
4382 {
4383 /* Insert NODE between PTR and PLACE. */
4384 node->next = place;
4385 ptr->next = node;
4386 }
4387 }
4388
4389 LT_DLMUTEX_UNLOCK ();
4390
4391 return errors;
4392}
4393
4394int
4395lt_dlloader_remove (loader_name)
4396 const char *loader_name;
4397{
4398 lt_dlloader *place = lt_dlloader_find (loader_name);
4399 lt_dlhandle handle;
4400 int errors = 0;
4401
4402 if (!place)
4403 {
4404 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4405 return 1;
4406 }
4407
4408 LT_DLGNUNET_mutex_lock ();
4409
4410 /* Fail if there are any open modules which use this loader. */
4411 for (handle = handles; handle; handle = handle->next)
4412 {
4413 if (handle->loader == place)
4414 {
4415 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4416 ++errors;
4417 goto done;
4418 }
4419 }
4420
4421 if (place == loaders)
4422 {
4423 /* PLACE is the first loader in the list. */
4424 loaders = loaders->next;
4425 }
4426 else
4427 {
4428 /* Find the loader before the one being removed. */
4429 lt_dlloader *prev;
4430 for (prev = loaders; prev->next; prev = prev->next)
4431 {
4432 if (!strcmp (prev->next->loader_name, loader_name))
4433 {
4434 break;
4435 }
4436 }
4437
4438 place = prev->next;
4439 prev->next = prev->next->next;
4440 }
4441
4442 if (place->dlloader_exit)
4443 {
4444 errors = place->dlloader_exit (place->dlloader_data);
4445 }
4446
4447 LT_DLGNUNET_free (place);
4448
4449done:
4450 LT_DLMUTEX_UNLOCK ();
4451
4452 return errors;
4453}
4454
4455lt_dlloader *
4456lt_dlloader_next (place)
4457 lt_dlloader *place;
4458{
4459 lt_dlloader *next;
4460
4461 LT_DLGNUNET_mutex_lock ();
4462 next = place ? place->next : loaders;
4463 LT_DLMUTEX_UNLOCK ();
4464
4465 return next;
4466}
4467
4468const char *
4469lt_dlloader_name (place)
4470 lt_dlloader *place;
4471{
4472 const char *name = 0;
4473
4474 if (place)
4475 {
4476 LT_DLGNUNET_mutex_lock ();
4477 name = place ? place->loader_name : 0;
4478 LT_DLMUTEX_UNLOCK ();
4479 }
4480 else
4481 {
4482 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4483 }
4484
4485 return name;
4486}
4487
4488lt_user_data *
4489lt_dlloader_data (place)
4490 lt_dlloader *place;
4491{
4492 lt_user_data *data = 0;
4493
4494 if (place)
4495 {
4496 LT_DLGNUNET_mutex_lock ();
4497 data = place ? &(place->dlloader_data) : 0;
4498 LT_DLMUTEX_UNLOCK ();
4499 }
4500 else
4501 {
4502 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4503 }
4504
4505 return data;
4506}
4507
4508lt_dlloader *
4509lt_dlloader_find (loader_name)
4510 const char *loader_name;
4511{
4512 lt_dlloader *place = 0;
4513
4514 LT_DLGNUNET_mutex_lock ();
4515 for (place = loaders; place; place = place->next)
4516 {
4517 if (strcmp (place->loader_name, loader_name) == 0)
4518 {
4519 break;
4520 }
4521 }
4522 LT_DLMUTEX_UNLOCK ();
4523
4524 return place;
4525}
diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h
deleted file mode 100644
index b64b5b89..00000000
--- a/libltdl/ltdl.h
+++ /dev/null
@@ -1,350 +0,0 @@
1/* ltdl.h -- generic dlopen functions
2 Copyright (C) 1998-2000 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
5
6This library is free software; you can redistribute it and/or
7modify it under the terms of the GNU Lesser General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11As a special exception to the GNU Lesser General Public License,
12if you distribute this file as part of a program or library that
13is built using GNU libtool, you may include it under the same
14distribution terms that you use for the rest of that program.
15
16This library is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public
22License along with this library; if not, write to the Free
23Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2402111-1307 USA
25*/
26
27/* Only include this header file once. */
28#ifndef LTDL_H
29#define LTDL_H 1
30
31#include <sys/types.h> /* for size_t declaration */
32
33
34/* --- MACROS FOR PORTABILITY --- */
35
36
37/* Saves on those hard to debug '\0' typos.... */
38#define LT_EOS_CHAR '\0'
39
40/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations,
41 so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at
42 the end of C declarations. */
43#ifdef __cplusplus
44# define LT_BEGIN_C_DECLS extern "C" {
45# define LT_END_C_DECLS }
46#else
47# define LT_BEGIN_C_DECLS /* empty */
48# define LT_END_C_DECLS /* empty */
49#endif
50
51LT_BEGIN_C_DECLS
52/* LT_PARAMS is a macro used to wrap function prototypes, so that compilers
53 that don't understand ANSI C prototypes still work, and ANSI C
54 compilers can issue warnings about type mismatches. */
55#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
56# define LT_PARAMS(protos) protos
57# define lt_ptr void*
58#else
59# define LT_PARAMS(protos) ()
60# define lt_ptr char*
61#endif
62/* LT_STMT_START/END are used to create macros which expand to a
63 a single compound statement in a portable way. */
64#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
65# define LT_STMT_START (void)(
66# define LT_STMT_END )
67#else
68# if (defined (sun) || defined (__sun__))
69# define LT_STMT_START if (1)
70# define LT_STMT_END else (void)0
71# else
72# define LT_STMT_START do
73# define LT_STMT_END while (0)
74# endif
75#endif
76/* LT_CONC creates a new concatenated symbol for the compiler
77 in a portable way. */
78#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER)
79# define LT_CONC(s,t) s##t
80#else
81# define LT_CONC(s,t) s/**/t
82#endif
83/* LT_STRLEN can be used safely on NULL pointers. */
84#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0)
85 /* --- WINDOWS SUPPORT --- */
86/* Canonicalise Windows and Cygwin recognition macros. */
87#ifdef __CYGWIN32__
88# ifndef __CYGWIN__
89# define __CYGWIN__ __CYGWIN32__
90# endif
91#endif
92#if defined(_WIN32) || defined(WIN32)
93# ifndef __WINDOWS__
94# ifdef _WIN32
95# define __WINDOWS__ _WIN32
96# else
97# ifdef WIN32
98# define __WINDOWS__ WIN32
99# endif
100# endif
101# endif
102#endif
103#ifdef __WINDOWS__
104# ifndef __CYGWIN__
105/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
106 separator when it is set. */
107# define LT_DIRSEP_CHAR '\\'
108# define LT_PATHSEP_CHAR ';'
109# endif
110#endif
111#ifndef LT_PATHSEP_CHAR
112# define LT_PATHSEP_CHAR ':'
113#endif
114/* DLL building support on win32 hosts; mostly to workaround their
115 ridiculous implementation of data symbol exporting. */
116#ifndef LT_SCOPE
117# ifdef __WINDOWS__
118# ifdef DLL_EXPORT /* defined by libtool (if required) */
119# define LT_SCOPE __declspec(dllexport)
120# endif
121# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
122# define LT_SCOPE extern __declspec(dllimport)
123# endif
124# endif
125# ifndef LT_SCOPE /* static linking or !__WINDOWS__ */
126# define LT_SCOPE extern
127# endif
128#endif
129#if defined(_MSC_VER) /* Visual Studio */
130# define R_OK 4
131#endif
132 /* --- DYNAMIC MODULE LOADING API --- */
133typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */
134
135/* Initialisation and finalisation functions for libltdl. */
136LT_SCOPE int lt_dlinit LT_PARAMS ((void));
137LT_SCOPE int lt_dlexit LT_PARAMS ((void));
138
139/* Module search path manipulation. */
140LT_SCOPE int lt_dladdsearchdir LT_PARAMS ((const char *search_dir));
141LT_SCOPE int lt_dlinsertsearchdir LT_PARAMS ((const char *before,
142 const char *search_dir));
143LT_SCOPE int lt_dlsetsearchpath LT_PARAMS ((const char *search_path));
144LT_SCOPE const char *lt_dlgetsearchpath LT_PARAMS ((void));
145LT_SCOPE int lt_dlforeachfile LT_PARAMS ((const char *search_path,
146 int (*func) (const char *filename,
147 lt_ptr data),
148 lt_ptr data));
149
150/* Portable libltdl versions of the system dlopen() API. */
151LT_SCOPE lt_dlhandle lt_dlopen LT_PARAMS ((const char *filename));
152LT_SCOPE lt_dlhandle lt_dlopenext LT_PARAMS ((const char *filename));
153LT_SCOPE lt_ptr lt_dlsym LT_PARAMS ((lt_dlhandle handle, const char *name));
154LT_SCOPE const char *lt_dlerror LT_PARAMS ((void));
155LT_SCOPE int lt_dlclose LT_PARAMS ((lt_dlhandle handle));
156
157/* Module residency management. */
158LT_SCOPE int lt_dlmakeresident LT_PARAMS ((lt_dlhandle handle));
159LT_SCOPE int lt_dlisresident LT_PARAMS ((lt_dlhandle handle));
160
161
162
163
164/* --- GNUNET_Mutex LOCKING --- */
165
166
167typedef void lt_dlmutex_lock LT_PARAMS ((void));
168typedef void lt_dlmutex_unlock LT_PARAMS ((void));
169typedef void lt_dlmutex_seterror LT_PARAMS ((const char *errmsg));
170typedef const char *lt_dlmutex_geterror LT_PARAMS ((void));
171
172LT_SCOPE int lt_dlmutex_register LT_PARAMS ((lt_dlmutex_lock * lock,
173 lt_dlmutex_unlock * unlock,
174 lt_dlmutex_seterror * seterror,
175 lt_dlmutex_geterror * geterror));
176
177
178
179
180/* --- MEMORY HANDLING --- */
181
182
183/* By default, the realloc function pointer is set to our internal
184 realloc implementation which iself uses lt_dlmalloc and lt_dlfree.
185 libltdl relies on a featureful realloc, but if you are sure yours
186 has the right semantics then you can assign it directly. Generally,
187 it is safe to assign just a malloc() and a free() function. */
188LT_SCOPE
189lt_ptr (*lt_dlmalloc)
190LT_PARAMS ((size_t size));
191 LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS ((lt_ptr ptr, size_t size));
192 LT_SCOPE void (*lt_dlfree) LT_PARAMS ((lt_ptr ptr));
193
194
195
196
197/* --- PRELOADED MODULE SUPPORT --- */
198
199
200/* A preopened symbol. Arrays of this type comprise the exported
201 symbols for a dlpreopened module. */
202 typedef struct
203 {
204 const char *name;
205 lt_ptr address;
206 } lt_dlsymlist;
207
208 LT_SCOPE int lt_dlpreload LT_PARAMS ((const lt_dlsymlist * preloaded));
209 LT_SCOPE int lt_dlpreload_default
210 LT_PARAMS ((const lt_dlsymlist * preloaded));
211
212#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \
213 extern const lt_dlsymlist lt_preloaded_symbols[]; \
214 lt_dlpreload_default(lt_preloaded_symbols); \
215 }LT_STMT_END
216
217
218
219
220/* --- MODULE INFORMATION --- */
221
222
223/* Read only information pertaining to a loaded module. */
224 typedef struct
225 {
226 char *filename; /* file name */
227 char *name; /* module name */
228 int ref_count; /* number of times lt_dlopened minus
229 number of times lt_dlclosed. */
230 } lt_dlinfo;
231
232 LT_SCOPE const lt_dlinfo *lt_dlgetinfo LT_PARAMS ((lt_dlhandle handle));
233 LT_SCOPE lt_dlhandle lt_dlhandle_next LT_PARAMS ((lt_dlhandle place));
234 LT_SCOPE int lt_dlforeach
235 LT_PARAMS ((int (*func) (lt_dlhandle handle, lt_ptr data),
236 lt_ptr data));
237
238/* Associating user data with loaded modules. */
239 typedef unsigned lt_dlcaller_id;
240
241 LT_SCOPE lt_dlcaller_id lt_dlcaller_register LT_PARAMS ((void));
242 LT_SCOPE lt_ptr lt_dlcaller_set_data LT_PARAMS ((lt_dlcaller_id key,
243 lt_dlhandle handle,
244 lt_ptr data));
245 LT_SCOPE lt_ptr lt_dlcaller_get_data LT_PARAMS ((lt_dlcaller_id key,
246 lt_dlhandle handle));
247
248
249
250/* --- USER MODULE LOADER API --- */
251
252
253 typedef struct lt_dlloader lt_dlloader;
254 typedef lt_ptr lt_user_data;
255 typedef lt_ptr lt_module;
256
257/* Function pointer types for creating user defined module loaders. */
258 typedef lt_module lt_module_open LT_PARAMS ((lt_user_data loader_data,
259 const char *filename));
260 typedef int lt_module_close LT_PARAMS ((lt_user_data loader_data,
261 lt_module handle));
262 typedef lt_ptr lt_find_sym LT_PARAMS ((lt_user_data loader_data,
263 lt_module handle,
264 const char *symbol));
265 typedef int lt_dlloader_exit LT_PARAMS ((lt_user_data loader_data));
266
267 struct lt_user_dlloader
268 {
269 const char *sym_prefix;
270 lt_module_open *module_open;
271 lt_module_close *module_close;
272 lt_find_sym *find_sym;
273 lt_dlloader_exit *dlloader_exit;
274 lt_user_data dlloader_data;
275 };
276
277 LT_SCOPE lt_dlloader *lt_dlloader_next LT_PARAMS ((lt_dlloader * place));
278 LT_SCOPE lt_dlloader *lt_dlloader_find
279 LT_PARAMS ((const char *loader_name));
280 LT_SCOPE const char *lt_dlloader_name LT_PARAMS ((lt_dlloader * place));
281 LT_SCOPE lt_user_data *lt_dlloader_data
282 LT_PARAMS ((lt_dlloader * place));
283 LT_SCOPE int lt_dlloader_add
284 LT_PARAMS ((lt_dlloader * place,
285 const struct lt_user_dlloader * dlloader,
286 const char *loader_name));
287 LT_SCOPE int lt_dlloader_remove LT_PARAMS ((const char *loader_name));
288
289
290
291/* --- ERROR MESSAGE HANDLING --- */
292
293
294/* Defining error strings alongside their symbolic names in a macro in
295 this way allows us to expand the macro in different contexts with
296 confidence that the enumeration of symbolic names will map correctly
297 onto the table of error strings. */
298#define lt_dlerror_table \
299 LT_ERROR(UNKNOWN, "unknown error") \
300 LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \
301 LT_ERROR(INVALID_LOADER, "invalid loader") \
302 LT_ERROR(INIT_LOADER, "loader initialization failed") \
303 LT_ERROR(REMOVE_LOADER, "loader removal failed") \
304 LT_ERROR(FILE_NOT_FOUND, "file not found") \
305 LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \
306 LT_ERROR(NO_SYMBOLS, "no symbols defined") \
307 LT_ERROR(CANNOT_OPEN, "can't open the module") \
308 LT_ERROR(CANNOT_CLOSE, "can't close the module") \
309 LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \
310 LT_ERROR(NO_MEMORY, "not enough memory") \
311 LT_ERROR(INVALID_HANDLE, "invalid module handle") \
312 LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \
313 LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
314 LT_ERROR(SHUTDOWN, "library already shutdown") \
315 LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \
316 LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \
317 LT_ERROR(INVALID_POSITION, "invalid search path insert position")
318
319/* Enumerate the symbolic error names. */
320 enum
321 {
322#define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name),
323 lt_dlerror_table
324#undef LT_ERROR
325 LT_ERROR_MAX
326 };
327
328/* These functions are only useful from inside custom module loaders. */
329 LT_SCOPE int lt_dladderror LT_PARAMS ((const char *diagnostic));
330 LT_SCOPE int lt_dlseterror LT_PARAMS ((int errorcode));
331
332
333
334
335/* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */
336
337
338#ifdef LT_NON_POSIX_NAMESPACE
339# define lt_ptr_t lt_ptr
340# define lt_module_t lt_module
341# define lt_module_open_t lt_module_open
342# define lt_module_close_t lt_module_close
343# define lt_find_sym_t lt_find_sym
344# define lt_dlloader_exit_t lt_dlloader_exit
345# define lt_dlloader_t lt_dlloader
346# define lt_dlloader_data_t lt_user_data
347#endif
348
349LT_END_C_DECLS
350#endif /* !LTDL_H */
diff --git a/ltmain.sh b/ltmain.sh
index b2f25d99..0bf38482 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -43,7 +43,7 @@ EXIT_FAILURE=1
43 43
44PROGRAM=ltmain.sh 44PROGRAM=ltmain.sh
45PACKAGE=libtool 45PACKAGE=libtool
46VERSION="1.5.26 Debian 1.5.26-2" 46VERSION="1.5.26 Debian 1.5.26-4"
47TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)" 47TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)"
48 48
49# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). 49# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).