Annotation of parser3/src/sql/pgsql/libltdl/ltdl.c, revision 1.1

1.1     ! parser      1: /* ltdl.c -- system independent dlopen wrapper
        !             2:    Copyright (C) 1998-1999 Free Software Foundation, Inc.
        !             3:    Originally by Thomas Tanner <tanner@ffii.org>
        !             4:    This file is part of GNU Libtool.
        !             5: 
        !             6: This library is free software; you can redistribute it and/or
        !             7: modify it under the terms of the GNU Library General Public
        !             8: License as published by the Free Software Foundation; either
        !             9: version 2 of the License, or (at your option) any later version.
        !            10: 
        !            11: As a special exception to the GNU Library General Public License,
        !            12: if you distribute this file as part of a program that uses GNU libtool
        !            13: to create libraries and programs, you may include it under the same
        !            14: distribution terms that you use for the rest of that program.
        !            15: 
        !            16: This library is distributed in the hope that it will be useful,
        !            17: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            18: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            19: Library General Public License for more details.
        !            20: 
        !            21: You should have received a copy of the GNU Library General Public
        !            22: License along with this library; if not, write to the Free Software
        !            23: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
        !            24: 02111-1307  USA
        !            25: */
        !            26: 
        !            27: #define _LTDL_COMPILE_
        !            28: 
        !            29: #include "config.h"
        !            30: 
        !            31: #if HAVE_STRING_H
        !            32: #include <string.h>
        !            33: #endif
        !            34: 
        !            35: #if HAVE_STRINGS_H
        !            36: #include <strings.h>
        !            37: #endif
        !            38: 
        !            39: #if HAVE_CTYPE_H
        !            40: #include <ctype.h>
        !            41: #endif
        !            42: 
        !            43: #if HAVE_MALLOC_H
        !            44: #include <malloc.h>
        !            45: #endif
        !            46: 
        !            47: #if HAVE_MEMORY_H
        !            48: #include <memory.h>
        !            49: #endif
        !            50: 
        !            51: #if HAVE_STDLIB_H
        !            52: #include <stdlib.h>
        !            53: #endif
        !            54: 
        !            55: #if HAVE_STDIO_H
        !            56: #include <stdio.h>
        !            57: #endif
        !            58: 
        !            59: #include "ltdl.h"
        !            60: 
        !            61: /* max. filename length */
        !            62: #ifndef LTDL_FILENAME_MAX
        !            63: #define LTDL_FILENAME_MAX 1024
        !            64: #endif
        !            65: 
        !            66: #undef LTDL_READTEXT_MODE
        !            67: /* fopen() mode flags for reading a text file */
        !            68: #ifdef _WIN32
        !            69: #define LTDL_READTEXT_MODE "rt"
        !            70: #else
        !            71: #define LTDL_READTEXT_MODE "r"
        !            72: #endif
        !            73: 
        !            74: #undef LTDL_SYMBOL_LENGTH
        !            75: /* This is the maximum symbol size that won't require malloc/free */
        !            76: #define LTDL_SYMBOL_LENGTH     128
        !            77: 
        !            78: #undef LTDL_SYMBOL_OVERHEAD
        !            79: /* This accounts for the _LTX_ separator */
        !            80: #define LTDL_SYMBOL_OVERHEAD   5
        !            81: 
        !            82: static const char objdir[] = LTDL_OBJDIR;
        !            83: #ifdef LTDL_SHLIB_EXT
        !            84: static const char shlib_ext[] = LTDL_SHLIB_EXT;
        !            85: #endif
        !            86: 
        !            87: static const char unknown_error[] = "unknown error";
        !            88: static const char dlopen_not_supported_error[] = "dlopen support not available";
        !            89: static const char file_not_found_error[] = "file not found";
        !            90: static const char no_symbols_error[] = "no symbols defined";
        !            91: static const char cannot_open_error[] = "can't open the module";
        !            92: static const char cannot_close_error[] = "can't close the module";
        !            93: static const char symbol_error[] = "symbol not found";
        !            94: static const char memory_error[] = "not enough memory";
        !            95: static const char invalid_handle_error[] = "invalid handle";
        !            96: static const char buffer_overflow_error[] = "internal buffer overflow";
        !            97: static const char shutdown_error[] = "library already shutdown";
        !            98: 
        !            99: #ifndef HAVE_PRELOADED_SYMBOLS
        !           100: /* If libtool won't define it, we'd better do */
        !           101: const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
        !           102: #endif
        !           103: 
        !           104: static const char *last_error = 0;
        !           105: 
        !           106: lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
        !           107: void    (*lt_dlfree)  LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
        !           108: 
        !           109: typedef struct lt_dltype_t {
        !           110:        struct lt_dltype_t *next;
        !           111:        const char *sym_prefix; /* prefix for symbols */
        !           112:        int (*mod_init) LTDL_PARAMS((void));
        !           113:        int (*mod_exit) LTDL_PARAMS((void));
        !           114:        int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
        !           115:        int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
        !           116:        lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
        !           117: } lt_dltype_t;
        !           118: 
        !           119: #define LTDL_TYPE_TOP 0
        !           120: 
        !           121: typedef        struct lt_dlhandle_t {
        !           122:        struct lt_dlhandle_t *next;
        !           123:        lt_dltype_t *type;      /* dlopening interface */
        !           124:        char    *filename;      /* file name */
        !           125:        char    *name;          /* module name */
        !           126:        int     usage;          /* usage */
        !           127:        int     depcount;       /* number of dependencies */
        !           128:        lt_dlhandle *deplibs;   /* dependencies */
        !           129:        lt_ptr_t handle;        /* system handle */
        !           130:        lt_ptr_t system;        /* system specific data */
        !           131: } lt_dlhandle_t;
        !           132: 
        !           133: #undef strdup
        !           134: #define strdup xstrdup
        !           135: 
        !           136: static inline char *
        !           137: strdup(str)
        !           138:        const char *str;
        !           139: {
        !           140:        char *tmp;
        !           141: 
        !           142:        if (!str)
        !           143:                return 0;
        !           144:        tmp = (char*) lt_dlmalloc(strlen(str)+1);
        !           145:        if (tmp)
        !           146:                strcpy(tmp, str);
        !           147:        return tmp;
        !           148: }
        !           149: 
        !           150: #if ! HAVE_STRCHR
        !           151: 
        !           152: # if HAVE_INDEX
        !           153: 
        !           154: #  define strchr index
        !           155: 
        !           156: # else
        !           157: 
        !           158: #  define strchr xstrchr
        !           159: 
        !           160: static inline const char*
        !           161: strchr(str, ch)
        !           162:        const char *str;
        !           163:        int ch;
        !           164: {
        !           165:        const char *p;
        !           166: 
        !           167:        for (p = str; *p != (char)ch && *p != '\0'; p++)
        !           168:                /*NOWORK*/;
        !           169: 
        !           170:        return (*p == (char)ch) ? p : 0;
        !           171: }
        !           172: 
        !           173: # endif
        !           174: 
        !           175: #endif
        !           176: 
        !           177: #if ! HAVE_STRRCHR
        !           178: 
        !           179: # if HAVE_RINDEX
        !           180: 
        !           181: #  define strrchr rindex
        !           182: 
        !           183: # else
        !           184: 
        !           185: #  define strrchr xstrrchr
        !           186: 
        !           187: static inline const char*
        !           188: strrchr(str, ch)
        !           189:        const char *str;
        !           190:        int ch;
        !           191: {
        !           192:        const char *p;
        !           193: 
        !           194:        for (p = str; *p != '\0'; p++)
        !           195:                /*NOWORK*/;
        !           196: 
        !           197:        while (*p != (char)ch && p >= str)
        !           198:                p--;
        !           199: 
        !           200:        return (*p == (char)ch) ? p : 0;
        !           201: }
        !           202: 
        !           203: # endif
        !           204: 
        !           205: #endif
        !           206: 
        !           207: #if HAVE_LIBDL
        !           208: 
        !           209: /* dynamic linking with dlopen/dlsym */
        !           210: 
        !           211: #if HAVE_DLFCN_H
        !           212: # include <dlfcn.h>
        !           213: #endif
        !           214: 
        !           215: #ifdef RTLD_GLOBAL
        !           216: # define LTDL_GLOBAL   RTLD_GLOBAL
        !           217: #else
        !           218: # ifdef DL_GLOBAL
        !           219: #  define LTDL_GLOBAL  DL_GLOBAL
        !           220: # else
        !           221: #  define LTDL_GLOBAL  0
        !           222: # endif
        !           223: #endif
        !           224: 
        !           225: /* We may have to define LTDL_LAZY_OR_NOW in the command line if we
        !           226:    find out it does not work in some platform. */
        !           227: #ifndef LTDL_LAZY_OR_NOW
        !           228: # ifdef RTLD_LAZY
        !           229: #  define LTDL_LAZY_OR_NOW     RTLD_LAZY
        !           230: # else
        !           231: #  ifdef DL_LAZY
        !           232: #   define LTDL_LAZY_OR_NOW    DL_LAZY
        !           233: #  else
        !           234: #   ifdef RTLD_NOW
        !           235: #    define LTDL_LAZY_OR_NOW   RTLD_NOW
        !           236: #   else
        !           237: #    ifdef DL_NOW
        !           238: #     define LTDL_LAZY_OR_NOW  DL_NOW
        !           239: #    else
        !           240: #     define LTDL_LAZY_OR_NOW  0
        !           241: #    endif
        !           242: #   endif
        !           243: #  endif
        !           244: # endif
        !           245: #endif
        !           246: 
        !           247: static int
        !           248: sys_dl_init LTDL_PARAMS((void))
        !           249: {
        !           250:        return 0;
        !           251: }
        !           252: 
        !           253: static int
        !           254: sys_dl_exit LTDL_PARAMS((void))
        !           255: {
        !           256:        return 0;
        !           257: }
        !           258: 
        !           259: static int
        !           260: sys_dl_open (handle, filename)
        !           261:        lt_dlhandle handle;
        !           262:        const char *filename;
        !           263: {
        !           264:        handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
        !           265:        if (!handle->handle) {
        !           266: #if HAVE_DLERROR
        !           267:                last_error = dlerror();
        !           268: #else
        !           269:                last_error = cannot_open_error;
        !           270: #endif
        !           271:                return 1;
        !           272:        }
        !           273:        return 0;
        !           274: }
        !           275: 
        !           276: static int
        !           277: sys_dl_close (handle)
        !           278:        lt_dlhandle handle;
        !           279: {
        !           280:        if (dlclose(handle->handle) != 0) {
        !           281: #if HAVE_DLERROR
        !           282:                last_error = dlerror();
        !           283: #else
        !           284:                last_error = cannot_close_error;
        !           285: #endif
        !           286:                return 1;
        !           287:        }
        !           288:        return 0;
        !           289: }
        !           290: 
        !           291: static lt_ptr_t
        !           292: sys_dl_sym (handle, symbol)
        !           293:        lt_dlhandle handle;
        !           294:        const char *symbol;
        !           295: {
        !           296:        lt_ptr_t address = dlsym(handle->handle, symbol);
        !           297:        
        !           298:        if (!address)
        !           299: #if HAVE_DLERROR
        !           300:                last_error = dlerror();
        !           301: #else
        !           302:                last_error = symbol_error;
        !           303: #endif
        !           304:        return address;
        !           305: }
        !           306: 
        !           307: static
        !           308: lt_dltype_t
        !           309: #ifdef NEED_USCORE
        !           310: sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
        !           311:        sys_dl_open, sys_dl_close, sys_dl_sym };
        !           312: #else
        !           313: sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
        !           314:        sys_dl_open, sys_dl_close, sys_dl_sym };
        !           315: #endif
        !           316: 
        !           317: #undef LTDL_TYPE_TOP
        !           318: #define LTDL_TYPE_TOP &sys_dl
        !           319: 
        !           320: #endif
        !           321: 
        !           322: #if HAVE_SHL_LOAD
        !           323: 
        !           324: /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
        !           325: 
        !           326: #ifdef HAVE_DL_H
        !           327: #include <dl.h>
        !           328: #endif
        !           329: 
        !           330: /* some flags are missing on some systems, so we provide
        !           331:  * harmless defaults.
        !           332:  *
        !           333:  * Mandatory:
        !           334:  * BIND_IMMEDIATE  - Resolve symbol references when the library is loaded.
        !           335:  * BIND_DEFERRED   - Delay code symbol resolution until actual reference.
        !           336:  *
        !           337:  * Optionally:
        !           338:  * BIND_FIRST     - Place the library at the head of the symbol search order.
        !           339:  * BIND_NONFATAL   - The default BIND_IMMEDIATE behavior is to treat all unsatisfied
        !           340:  *                  symbols as fatal.  This flag allows binding of unsatisfied code
        !           341:  *                  symbols to be deferred until use.
        !           342:  *                  [Perl: For certain libraries, like DCE, deferred binding often
        !           343:  *                  causes run time problems.  Adding BIND_NONFATAL to BIND_IMMEDIATE
        !           344:  *                  still allows unresolved references in situations like this.]
        !           345:  * BIND_NOSTART           - Do not call the initializer for the shared library when the
        !           346:  *                  library is loaded, nor on a future call to shl_unload().
        !           347:  * BIND_VERBOSE           - Print verbose messages concerning possible unsatisfied symbols.
        !           348:  *
        !           349:  * hp9000s700/hp9000s800:
        !           350:  * BIND_RESTRICTED - Restrict symbols visible by the library to those present at
        !           351:  *                  library load time.
        !           352:  * DYNAMIC_PATH           - Allow the loader to dynamically search for the library specified
        !           353:  *                  by the path argument.
        !           354:  */
        !           355: 
        !           356: #ifndef        DYNAMIC_PATH
        !           357: #define        DYNAMIC_PATH    0
        !           358: #endif /* DYNAMIC_PATH */
        !           359: #ifndef        BIND_RESTRICTED
        !           360: #define        BIND_RESTRICTED 0
        !           361: #endif /* BIND_RESTRICTED */
        !           362: 
        !           363: #define        LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
        !           364: 
        !           365: static int
        !           366: sys_shl_init LTDL_PARAMS((void))
        !           367: {
        !           368:        return 0;
        !           369: }
        !           370: 
        !           371: static int
        !           372: sys_shl_exit LTDL_PARAMS((void))
        !           373: {
        !           374:        return 0;
        !           375: }
        !           376: 
        !           377: static int
        !           378: sys_shl_open (handle, filename)
        !           379:        lt_dlhandle handle;
        !           380:        const char *filename;
        !           381: {
        !           382:        handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
        !           383:        if (!handle->handle) {
        !           384:                last_error = cannot_open_error;
        !           385:                return 1;
        !           386:        }
        !           387:        return 0;
        !           388: }
        !           389: 
        !           390: static int
        !           391: sys_shl_close (handle)
        !           392:        lt_dlhandle handle;
        !           393: {
        !           394:        if (shl_unload((shl_t) (handle->handle)) != 0) {
        !           395:                last_error = cannot_close_error;
        !           396:                return 1;
        !           397:        }
        !           398:        return 0;
        !           399: }
        !           400: 
        !           401: static lt_ptr_t
        !           402: sys_shl_sym (handle, symbol)
        !           403:        lt_dlhandle handle;
        !           404:        const char *symbol;
        !           405: {
        !           406:        lt_ptr_t address;
        !           407: 
        !           408:        if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
        !           409:            symbol, TYPE_UNDEFINED, &address) == 0)
        !           410:                if (address)
        !           411:                        return address;
        !           412:        last_error = symbol_error;
        !           413:        return 0;
        !           414: }
        !           415: 
        !           416: static
        !           417: lt_dltype_t
        !           418: sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
        !           419:        sys_shl_open, sys_shl_close, sys_shl_sym };
        !           420: 
        !           421: #undef LTDL_TYPE_TOP
        !           422: #define LTDL_TYPE_TOP &sys_shl
        !           423: 
        !           424: #endif
        !           425: 
        !           426: #if HAVE_DLD
        !           427: 
        !           428: /* dynamic linking with dld */
        !           429: 
        !           430: #if HAVE_DLD_H
        !           431: #include <dld.h>
        !           432: #endif
        !           433: 
        !           434: static int
        !           435: sys_dld_init LTDL_PARAMS((void))
        !           436: {
        !           437:        return 0;
        !           438: }
        !           439: 
        !           440: static int
        !           441: sys_dld_exit LTDL_PARAMS((void))
        !           442: {
        !           443:        return 0;
        !           444: }
        !           445: 
        !           446: static int
        !           447: sys_dld_open (handle, filename)
        !           448:        lt_dlhandle handle;
        !           449:        const char *filename;
        !           450: {
        !           451:        handle->handle = strdup(filename);
        !           452:        if (!handle->handle) {
        !           453:                last_error = memory_error;
        !           454:                return 1;
        !           455:        }
        !           456:        if (dld_link(filename) != 0) {
        !           457:                last_error = cannot_open_error;
        !           458:                lt_dlfree(handle->handle);
        !           459:                return 1;
        !           460:        }
        !           461:        return 0;
        !           462: }
        !           463: 
        !           464: static int
        !           465: sys_dld_close (handle)
        !           466:        lt_dlhandle handle;
        !           467: {
        !           468:        if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
        !           469:                last_error = cannot_close_error;
        !           470:                return 1;
        !           471:        }
        !           472:        lt_dlfree(handle->filename);
        !           473:        return 0;
        !           474: }
        !           475: 
        !           476: static lt_ptr_t
        !           477: sys_dld_sym (handle, symbol)
        !           478:        lt_dlhandle handle;
        !           479:        const char *symbol;
        !           480: {
        !           481:        lt_ptr_t address = dld_get_func(symbol);
        !           482:        
        !           483:        if (!address)
        !           484:                last_error = symbol_error;
        !           485:        return address;
        !           486: }
        !           487: 
        !           488: static
        !           489: lt_dltype_t
        !           490: sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
        !           491:        sys_dld_open, sys_dld_close, sys_dld_sym };
        !           492: 
        !           493: #undef LTDL_TYPE_TOP
        !           494: #define LTDL_TYPE_TOP &sys_dld
        !           495: 
        !           496: #endif
        !           497: 
        !           498: #ifdef _WIN32
        !           499: 
        !           500: /* dynamic linking for Win32 */
        !           501: 
        !           502: #include <windows.h>
        !           503: 
        !           504: static int
        !           505: sys_wll_init LTDL_PARAMS((void))
        !           506: {
        !           507:        return 0;
        !           508: }
        !           509: 
        !           510: static int
        !           511: sys_wll_exit LTDL_PARAMS((void))
        !           512: {
        !           513:        return 0;
        !           514: }
        !           515: 
        !           516: /* Forward declaration; required to implement handle search below. */
        !           517: static lt_dlhandle handles;
        !           518: 
        !           519: static int
        !           520: sys_wll_open (handle, filename)
        !           521:        lt_dlhandle handle;
        !           522:        const char *filename;
        !           523: {
        !           524:        lt_dlhandle cur;
        !           525:        char *searchname = NULL;
        !           526:        char *ext = strrchr(filename, '.');
        !           527: 
        !           528:        if (ext) {
        !           529:                /* FILENAME already has an extension. */
        !           530:                searchname = strdup(filename);
        !           531:        } else {
        !           532:                /* Append a `.' to stop Windows from adding an
        !           533:                   implicit `.dll' extension. */
        !           534:                searchname = (char*)lt_dlmalloc(2+ strlen(filename));
        !           535:                strcpy(searchname, filename);
        !           536:                strcat(searchname, ".");
        !           537:        }
        !           538:     
        !           539:        handle->handle = LoadLibrary(searchname);
        !           540:        lt_dlfree(searchname);
        !           541:        
        !           542:        /* libltdl expects this function to fail if it is unable
        !           543:           to physically load the library.  Sadly, LoadLibrary
        !           544:           will search the loaded libraries for a match and return
        !           545:           one of them if the path search load fails.
        !           546: 
        !           547:           We check whether LoadLibrary is returning a handle to
        !           548:           an already loaded module, and simulate failure if we
        !           549:           find one. */
        !           550:        cur = handles;
        !           551:        while (cur) {
        !           552:                if (!cur->handle) {
        !           553:                        cur = 0;
        !           554:                        break;
        !           555:                }
        !           556:                if (cur->handle == handle->handle)
        !           557:                        break;
        !           558:                cur = cur->next;
        !           559:        }
        !           560: 
        !           561:        if (cur || !handle->handle) {
        !           562:                last_error = cannot_open_error;
        !           563:                return 1;
        !           564:        }
        !           565: 
        !           566:        return 0;
        !           567: }
        !           568: 
        !           569: static int
        !           570: sys_wll_close (handle)
        !           571:        lt_dlhandle handle;
        !           572: {
        !           573:        if (FreeLibrary(handle->handle) == 0) {
        !           574:                last_error = cannot_close_error;
        !           575:                return 1;
        !           576:        }
        !           577:        return 0;
        !           578: }
        !           579: 
        !           580: static lt_ptr_t
        !           581: sys_wll_sym (handle, symbol)
        !           582:        lt_dlhandle handle;
        !           583:        const char *symbol;
        !           584: {
        !           585:        lt_ptr_t address = GetProcAddress(handle->handle, symbol);
        !           586:        
        !           587:        if (!address)
        !           588:                last_error = symbol_error;
        !           589:        return address;
        !           590: }
        !           591: 
        !           592: static
        !           593: lt_dltype_t
        !           594: sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
        !           595:        sys_wll_open, sys_wll_close, sys_wll_sym };
        !           596: 
        !           597: #undef LTDL_TYPE_TOP
        !           598: #define LTDL_TYPE_TOP &sys_wll
        !           599: 
        !           600: #endif
        !           601: 
        !           602: #ifdef __BEOS__
        !           603: 
        !           604: /* dynamic linking for BeOS */
        !           605: 
        !           606: #include <kernel/image.h>
        !           607: 
        !           608: static int
        !           609: sys_bedl_init LTDL_PARAMS((void))
        !           610: {
        !           611:        return 0;
        !           612: }
        !           613: 
        !           614: static int
        !           615: sys_bedl_exit LTDL_PARAMS((void))
        !           616: {
        !           617:        return 0;
        !           618: }
        !           619: 
        !           620: static int
        !           621: sys_bedl_open (handle, filename)
        !           622:        lt_dlhandle handle;
        !           623:        const char *filename;
        !           624: {
        !           625:        image_id image = 0;
        !           626:        
        !           627:        if (filename) {
        !           628:                image = load_add_on(filename);
        !           629:        } else {
        !           630:                image_info info; 
        !           631:                int32 cookie = 0; 
        !           632:                if (get_next_image_info(0, &cookie, &info) == B_OK)
        !           633:                        image = load_add_on(info.name);
        !           634:        }
        !           635:        if (image <= 0) {
        !           636:                last_error = cannot_open_error;
        !           637:                return 1;
        !           638:        }
        !           639:        handle->handle = (void*) image;
        !           640:        return 0;
        !           641: }
        !           642: 
        !           643: static int
        !           644: sys_bedl_close (handle)
        !           645:        lt_dlhandle handle;
        !           646: {
        !           647:        if (unload_add_on((image_id)handle->handle) != B_OK) {
        !           648:                last_error = cannot_close_error;
        !           649:                return 1;
        !           650:        }
        !           651:        return 0;
        !           652: }
        !           653: 
        !           654: static lt_ptr_t
        !           655: sys_bedl_sym (handle, symbol)
        !           656:        lt_dlhandle handle;
        !           657:        const char *symbol;
        !           658: {
        !           659:        lt_ptr_t address = 0;
        !           660:        image_id image = (image_id)handle->handle;
        !           661:    
        !           662:        if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
        !           663:                &address) != B_OK) {
        !           664:                last_error = symbol_error;
        !           665:                return 0;
        !           666:        }
        !           667:        return address;
        !           668: }
        !           669: 
        !           670: static
        !           671: lt_dltype_t
        !           672: sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
        !           673:        sys_bedl_open, sys_bedl_close, sys_bedl_sym };
        !           674: 
        !           675: #undef LTDL_TYPE_TOP
        !           676: #define LTDL_TYPE_TOP &sys_bedl
        !           677: 
        !           678: #endif
        !           679: 
        !           680: /* emulate dynamic linking using preloaded_symbols */
        !           681: 
        !           682: typedef struct lt_dlsymlists_t {
        !           683:        struct lt_dlsymlists_t *next;
        !           684:        const lt_dlsymlist *syms;
        !           685: } lt_dlsymlists_t;
        !           686: 
        !           687: static const lt_dlsymlist *default_preloaded_symbols = 0;
        !           688: static lt_dlsymlists_t *preloaded_symbols = 0;
        !           689: 
        !           690: static int
        !           691: presym_init LTDL_PARAMS((void))
        !           692: {
        !           693:        preloaded_symbols = 0;
        !           694:        if (default_preloaded_symbols)
        !           695:                return lt_dlpreload(default_preloaded_symbols);
        !           696:        return 0;
        !           697: }
        !           698: 
        !           699: static int
        !           700: presym_free_symlists LTDL_PARAMS((void))
        !           701: {
        !           702:        lt_dlsymlists_t *lists = preloaded_symbols;
        !           703:        
        !           704:        while (lists) {
        !           705:                lt_dlsymlists_t *tmp = lists;
        !           706:                
        !           707:                lists = lists->next;
        !           708:                lt_dlfree(tmp);
        !           709:        }
        !           710:        preloaded_symbols = 0;
        !           711:        return 0;
        !           712: }
        !           713: 
        !           714: static int
        !           715: presym_exit LTDL_PARAMS((void))
        !           716: {
        !           717:        presym_free_symlists();
        !           718:        return 0;
        !           719: }
        !           720: 
        !           721: static int
        !           722: presym_add_symlist (preloaded)
        !           723:        const lt_dlsymlist *preloaded;
        !           724: {
        !           725:        lt_dlsymlists_t *tmp;
        !           726:        lt_dlsymlists_t *lists = preloaded_symbols;
        !           727:        
        !           728:        while (lists) {
        !           729:                if (lists->syms == preloaded)
        !           730:                        return 0;
        !           731:                lists = lists->next;
        !           732:        }
        !           733: 
        !           734:        tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
        !           735:        if (!tmp) {
        !           736:                last_error = memory_error;
        !           737:                return 1;
        !           738:        }
        !           739:        tmp->syms = preloaded;
        !           740:        tmp->next = 0;
        !           741:        if (!preloaded_symbols)
        !           742:                preloaded_symbols = tmp;
        !           743:        else {
        !           744:                /* append to the end */
        !           745:                lists = preloaded_symbols;
        !           746:                while (lists->next)
        !           747:                        lists = lists->next;
        !           748:                lists->next = tmp;
        !           749:        }
        !           750:        return 0;
        !           751: }
        !           752: 
        !           753: static int
        !           754: presym_open (handle, filename)
        !           755:        lt_dlhandle handle;
        !           756:        const char *filename;
        !           757: {
        !           758:        lt_dlsymlists_t *lists = preloaded_symbols;
        !           759: 
        !           760:        if (!lists) {
        !           761:                last_error = no_symbols_error;
        !           762:                return 1;
        !           763:        }
        !           764:        if (!filename)
        !           765:                filename = "@PROGRAM@";
        !           766:        while (lists) {
        !           767:                const lt_dlsymlist *syms = lists->syms;
        !           768:        
        !           769:                while (syms->name) {
        !           770:                        if (!syms->address &&
        !           771:                            strcmp(syms->name, filename) == 0) {
        !           772:                                handle->handle = (lt_ptr_t) syms;
        !           773:                                return 0;
        !           774:                        }
        !           775:                        syms++;
        !           776:                }
        !           777:                lists = lists->next;
        !           778:        }
        !           779:        last_error = file_not_found_error;
        !           780:        return 1;
        !           781: }
        !           782: 
        !           783: static int
        !           784: presym_close (handle)
        !           785:        lt_dlhandle handle;
        !           786: {
        !           787:        /* Just to silence gcc -Wall */
        !           788:        handle = 0;
        !           789:        return 0;
        !           790: }
        !           791: 
        !           792: static lt_ptr_t
        !           793: presym_sym (handle, symbol)
        !           794:        lt_dlhandle handle;
        !           795:        const char *symbol;
        !           796: {
        !           797:        lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
        !           798: 
        !           799:        syms++;
        !           800:        while (syms->address) {
        !           801:                if (strcmp(syms->name, symbol) == 0)
        !           802:                        return syms->address;
        !           803:                syms++;
        !           804:        }
        !           805:        last_error = symbol_error;
        !           806:        return 0;
        !           807: }
        !           808: 
        !           809: static
        !           810: lt_dltype_t
        !           811: presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
        !           812:           presym_open, presym_close, presym_sym };
        !           813: 
        !           814: #undef LTDL_TYPE_TOP
        !           815: #define LTDL_TYPE_TOP &presym
        !           816: 
        !           817: static char *user_search_path = 0;
        !           818: static lt_dlhandle handles = 0;
        !           819: static int initialized = 0;
        !           820: 
        !           821: static lt_dltype_t *types = LTDL_TYPE_TOP;
        !           822: #undef LTDL_TYPE_TOP
        !           823: 
        !           824: int
        !           825: lt_dlinit LTDL_PARAMS((void))
        !           826: {
        !           827:        /* initialize libltdl */
        !           828:        lt_dltype_t **type = &types;
        !           829:        int typecount = 0;
        !           830: 
        !           831:        if (initialized) {      /* Initialize only at first call. */
        !           832:                initialized++;
        !           833:                return 0;
        !           834:        }
        !           835:        handles = 0;
        !           836:        user_search_path = 0; /* empty search path */
        !           837: 
        !           838:        while (*type) {
        !           839:                if ((*type)->mod_init())
        !           840:                        *type = (*type)->next; /* Remove it from the list */
        !           841:                else {
        !           842:                        type = &(*type)->next; /* Keep it */
        !           843:                        typecount++;
        !           844:                }
        !           845:        }
        !           846:        if (typecount == 0) {
        !           847:                last_error = dlopen_not_supported_error;
        !           848:                return 1;
        !           849:        }
        !           850:        last_error = 0;
        !           851:        initialized = 1;
        !           852:        return 0;
        !           853: }
        !           854: 
        !           855: int
        !           856: lt_dlpreload (preloaded)
        !           857:        const lt_dlsymlist *preloaded;
        !           858: {
        !           859:        if (preloaded)
        !           860:                return presym_add_symlist(preloaded);
        !           861:        presym_free_symlists();
        !           862:        if (default_preloaded_symbols)
        !           863:                return lt_dlpreload(default_preloaded_symbols);
        !           864:        return 0;
        !           865: }
        !           866: 
        !           867: int
        !           868: lt_dlpreload_default (preloaded)
        !           869:        const lt_dlsymlist *preloaded;
        !           870: {
        !           871:        default_preloaded_symbols = preloaded;
        !           872:        return 0;
        !           873: }
        !           874: 
        !           875: int
        !           876: lt_dlexit LTDL_PARAMS((void))
        !           877: {
        !           878:        /* shut down libltdl */
        !           879:        lt_dltype_t *type = types;
        !           880:        int     errors;
        !           881:        
        !           882:        if (!initialized) {
        !           883:                last_error = shutdown_error;
        !           884:                return 1;
        !           885:        }
        !           886:        if (initialized != 1) { /* shut down only at last call. */
        !           887:                initialized--;
        !           888:                return 0;
        !           889:        }
        !           890:        /* close all modules */
        !           891:        errors = 0;
        !           892:        while (handles) {
        !           893:                /* FIXME: what if a module depends on another one? */
        !           894:                if (lt_dlclose(handles))
        !           895:                        errors++;
        !           896:        }
        !           897:        initialized = 0;
        !           898:        while (type) {
        !           899:                if (type->mod_exit())
        !           900:                        errors++;
        !           901:                type = type->next;
        !           902:        }
        !           903:        return errors;
        !           904: }
        !           905: 
        !           906: static int
        !           907: tryall_dlopen (handle, filename)
        !           908:        lt_dlhandle *handle;
        !           909:        const char *filename;
        !           910: {
        !           911:        lt_dlhandle cur;
        !           912:        lt_dltype_t *type = types;
        !           913:        const char *saved_error = last_error;
        !           914:        
        !           915:        /* check whether the module was already opened */
        !           916:        cur = handles;
        !           917:        while (cur) {
        !           918:                if (!cur->filename && !filename)
        !           919:                        break;
        !           920:                if (cur->filename && filename && 
        !           921:                    strcmp(cur->filename, filename) == 0)
        !           922:                        break;
        !           923:                cur = cur->next;
        !           924:        }
        !           925:        if (cur) {
        !           926:                cur->usage++;
        !           927:                *handle = cur;
        !           928:                return 0;
        !           929:        }
        !           930:        
        !           931:        cur = *handle;
        !           932:        if (filename) {
        !           933:                cur->filename = strdup(filename);
        !           934:                if (!cur->filename) {
        !           935:                        last_error = memory_error;
        !           936:                        return 1;
        !           937:                }
        !           938:        } else
        !           939:                cur->filename = 0;
        !           940:        while (type) {
        !           941:                if (type->lib_open(cur, filename) == 0)
        !           942:                        break;
        !           943:                type = type->next;
        !           944:        }
        !           945:        if (!type) {
        !           946:                if (cur->filename)
        !           947:                        lt_dlfree(cur->filename);
        !           948:                return 1;
        !           949:        }
        !           950:        cur->type = type;
        !           951:        last_error = saved_error;
        !           952:        return 0;
        !           953: }
        !           954: 
        !           955: static int
        !           956: find_module (handle, dir, libdir, dlname, old_name, installed)
        !           957:        lt_dlhandle *handle;
        !           958:        const char *dir;
        !           959:        const char *libdir;
        !           960:        const char *dlname;
        !           961:        const char *old_name;
        !           962:        int installed;
        !           963: {
        !           964:        int     error;
        !           965:        char    *filename;
        !           966:        /* try to open the old library first; if it was dlpreopened, 
        !           967:           we want the preopened version of it, even if a dlopenable
        !           968:           module is available */
        !           969:        if (old_name && tryall_dlopen(handle, old_name) == 0)
        !           970:                return 0;
        !           971:        /* try to open the dynamic library */
        !           972:        if (dlname) {
        !           973:                /* try to open the installed module */
        !           974:                if (installed && libdir) {
        !           975:                        filename = (char*)
        !           976:                                lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
        !           977:                        if (!filename) {
        !           978:                                last_error = memory_error;
        !           979:                                return 1;
        !           980:                        }
        !           981:                        strcpy(filename, libdir);
        !           982:                        strcat(filename, "/");
        !           983:                        strcat(filename, dlname);
        !           984:                        error = tryall_dlopen(handle, filename) == 0;
        !           985:                        lt_dlfree(filename);
        !           986:                        if (error)
        !           987:                                return 0;
        !           988:                }
        !           989:                /* try to open the not-installed module */
        !           990:                if (!installed) {
        !           991:                        filename = (char*)
        !           992:                                lt_dlmalloc((dir ? strlen(dir) : 0)
        !           993:                                       + strlen(objdir) + strlen(dlname) + 1);
        !           994:                        if (!filename) {
        !           995:                                last_error = memory_error;
        !           996:                                return 1;
        !           997:                        }
        !           998:                        if (dir)
        !           999:                                strcpy(filename, dir);
        !          1000:                        else
        !          1001:                                *filename = 0;
        !          1002:                        strcat(filename, objdir);
        !          1003:                        strcat(filename, dlname);
        !          1004: 
        !          1005:                        error = tryall_dlopen(handle, filename) == 0;
        !          1006:                        lt_dlfree(filename);
        !          1007:                        if (error)
        !          1008:                                return 0;
        !          1009:                }
        !          1010:                /* hmm, maybe it was moved to another directory */
        !          1011:                {
        !          1012:                        filename = (char*)
        !          1013:                                lt_dlmalloc((dir ? strlen(dir) : 0)
        !          1014:                                       + strlen(dlname) + 1);
        !          1015:                        if (dir)
        !          1016:                                strcpy(filename, dir);
        !          1017:                        else
        !          1018:                                *filename = 0;
        !          1019:                        strcat(filename, dlname);
        !          1020:                        error = tryall_dlopen(handle, filename) == 0;
        !          1021:                        lt_dlfree(filename);
        !          1022:                        if (error)
        !          1023:                                return 0;
        !          1024:                }
        !          1025:        }
        !          1026:        last_error = file_not_found_error;
        !          1027:        return 1;
        !          1028: }
        !          1029: 
        !          1030: static lt_ptr_t
        !          1031: find_file (basename, search_path, pdir, handle)
        !          1032:        const char *basename;
        !          1033:        const char *search_path;
        !          1034:        char **pdir;
        !          1035:        lt_dlhandle *handle;
        !          1036: {
        !          1037:        /* when handle != NULL search a library, otherwise a file */
        !          1038:        /* return NULL on failure, otherwise the file/handle */
        !          1039: 
        !          1040:        char    *filename = 0;
        !          1041:        int     filenamesize = 0;
        !          1042:        const char *next = search_path;
        !          1043:        int     lenbase = strlen(basename);
        !          1044:        
        !          1045:        if (!next || !*next) {
        !          1046:                last_error = file_not_found_error;
        !          1047:                return 0;
        !          1048:        }
        !          1049:        while (next) {
        !          1050:                int lendir;
        !          1051:                const char *cur = next;
        !          1052: 
        !          1053:                next = strchr(cur, ':');
        !          1054:                if (!next)
        !          1055:                        next = cur + strlen(cur);
        !          1056:                lendir = next - cur;
        !          1057:                if (*next == ':')
        !          1058:                        ++next;
        !          1059:                else
        !          1060:                        next = 0;
        !          1061:                if (lendir == 0)
        !          1062:                        continue;
        !          1063:                if (lendir + 1 + lenbase >= filenamesize) {
        !          1064:                        if (filename)
        !          1065:                                lt_dlfree(filename);
        !          1066:                        filenamesize = lendir + 1 + lenbase + 1;
        !          1067:                        filename = (char*) lt_dlmalloc(filenamesize);
        !          1068:                        if (!filename) {
        !          1069:                                last_error = memory_error;
        !          1070:                                return 0;
        !          1071:                        }
        !          1072:                }
        !          1073:                strncpy(filename, cur, lendir);
        !          1074:                if (filename[lendir-1] != '/')
        !          1075:                        filename[lendir++] = '/';
        !          1076:                strcpy(filename+lendir, basename);
        !          1077:                if (handle) {
        !          1078:                        if (tryall_dlopen(handle, filename) == 0) {
        !          1079:                                lt_dlfree(filename);
        !          1080:                                return (lt_ptr_t) handle;
        !          1081:                        }
        !          1082:                } else {
        !          1083:                        FILE *file = fopen(filename, LTDL_READTEXT_MODE);
        !          1084:                        if (file) {
        !          1085:                                if (*pdir)
        !          1086:                                        lt_dlfree(*pdir);
        !          1087:                                filename[lendir] = '\0';
        !          1088:                                *pdir = strdup(filename);
        !          1089:                                if (!*pdir) {
        !          1090:                                        /* We could have even avoided the
        !          1091:                                           strdup, but there would be some
        !          1092:                                           memory overhead. */
        !          1093:                                        *pdir = filename;
        !          1094:                                } else
        !          1095:                                        lt_dlfree(filename);
        !          1096:                                return (lt_ptr_t) file;
        !          1097:                        }
        !          1098:                }
        !          1099:        }
        !          1100:        if (filename)
        !          1101:                lt_dlfree(filename);
        !          1102:        last_error = file_not_found_error;
        !          1103:        return 0;
        !          1104: }
        !          1105: 
        !          1106: static int
        !          1107: load_deplibs(handle, deplibs)
        !          1108:        lt_dlhandle handle;
        !          1109:        const char *deplibs;
        !          1110: {
        !          1111:        /* FIXME: load deplibs */
        !          1112:        handle->depcount = 0;
        !          1113:        handle->deplibs = 0;
        !          1114:        /* Just to silence gcc -Wall */
        !          1115:        deplibs = 0;
        !          1116:        return 0;
        !          1117: }
        !          1118: 
        !          1119: static int
        !          1120: unload_deplibs(handle)
        !          1121:        lt_dlhandle handle;
        !          1122: {
        !          1123:        /* FIXME: unload deplibs */
        !          1124:        /* Just to silence gcc -Wall */
        !          1125:        handle = 0;
        !          1126:        return 0;
        !          1127: }
        !          1128: 
        !          1129: static inline int
        !          1130: trim (dest, str)
        !          1131:        char **dest;
        !          1132:        const char *str;
        !          1133: {
        !          1134:        /* remove the leading and trailing "'" from str 
        !          1135:           and store the result in dest */
        !          1136:        char *tmp;
        !          1137:        const char *end = strrchr(str, '\'');
        !          1138:        int len = strlen(str);
        !          1139: 
        !          1140:        if (*dest)
        !          1141:                lt_dlfree(*dest);
        !          1142:        if (len > 3 && str[0] == '\'') {
        !          1143:                tmp = (char*) lt_dlmalloc(end - str);
        !          1144:                if (!tmp) {
        !          1145:                        last_error = memory_error;
        !          1146:                        return 1;
        !          1147:                }
        !          1148:                strncpy(tmp, &str[1], (end - str) - 1);
        !          1149:                tmp[len-3] = '\0';
        !          1150:                *dest = tmp;
        !          1151:        } else
        !          1152:                *dest = 0;
        !          1153:        return 0;
        !          1154: }
        !          1155: 
        !          1156: static inline int
        !          1157: free_vars(dir, name, dlname, oldname, libdir, deplibs)
        !          1158:        char *dir;
        !          1159:        char *name;
        !          1160:        char *dlname;
        !          1161:        char *oldname;
        !          1162:        char *libdir;
        !          1163:        char *deplibs;
        !          1164: {
        !          1165:        if (dir)
        !          1166:                lt_dlfree(dir);
        !          1167:        if (name)
        !          1168:                lt_dlfree(name);
        !          1169:        if (dlname)
        !          1170:                lt_dlfree(dlname);
        !          1171:        if (oldname)
        !          1172:                lt_dlfree(oldname);
        !          1173:        if (libdir)
        !          1174:                lt_dlfree(libdir);
        !          1175:        if (deplibs)
        !          1176:                lt_dlfree(deplibs);
        !          1177:        return 0;
        !          1178: }
        !          1179: 
        !          1180: lt_dlhandle
        !          1181: lt_dlopen (filename)
        !          1182:        const char *filename;
        !          1183: {
        !          1184:        lt_dlhandle handle, newhandle;
        !          1185:        const char *basename, *ext;
        !          1186:        const char *saved_error = last_error;
        !          1187:        char    *dir = 0, *name = 0;
        !          1188:        
        !          1189:        if (!filename) {
        !          1190:                handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
        !          1191:                if (!handle) {
        !          1192:                        last_error = memory_error;
        !          1193:                        return 0;
        !          1194:                }
        !          1195:                handle->usage = 0;
        !          1196:                handle->depcount = 0;
        !          1197:                handle->deplibs = 0;
        !          1198:                newhandle = handle;
        !          1199:                if (tryall_dlopen(&newhandle, 0) != 0) {
        !          1200:                        lt_dlfree(handle);
        !          1201:                        return 0;
        !          1202:                }
        !          1203:                goto register_handle;
        !          1204:        }
        !          1205:        basename = strrchr(filename, '/');
        !          1206:        if (basename) {
        !          1207:                basename++;
        !          1208:                dir = (char*) lt_dlmalloc(basename - filename + 1);
        !          1209:                if (!dir) {
        !          1210:                        last_error = memory_error;
        !          1211:                        return 0;
        !          1212:                }
        !          1213:                strncpy(dir, filename, basename - filename);
        !          1214:                dir[basename - filename] = '\0';
        !          1215:        } else
        !          1216:                basename = filename;
        !          1217:        /* check whether we open a libtool module (.la extension) */
        !          1218:        ext = strrchr(basename, '.');
        !          1219:        if (ext && strcmp(ext, ".la") == 0) {
        !          1220:                /* this seems to be a libtool module */
        !          1221:                FILE    *file;
        !          1222:                int     i;
        !          1223:                char    *dlname = 0, *old_name = 0;
        !          1224:                char    *libdir = 0, *deplibs = 0;
        !          1225:                char    *line;
        !          1226:                int     error = 0;
        !          1227:                /* if we can't find the installed flag, it is probably an
        !          1228:                   installed libtool archive, produced with an old version
        !          1229:                   of libtool */
        !          1230:                int     installed = 1; 
        !          1231: 
        !          1232:                /* extract the module name from the file name */
        !          1233:                name = (char*) lt_dlmalloc(ext - basename + 1);
        !          1234:                if (!name) {
        !          1235:                        last_error = memory_error;
        !          1236:                        if (dir)
        !          1237:                                lt_dlfree(dir);
        !          1238:                        return 0;
        !          1239:                }
        !          1240:                /* canonicalize the module name */
        !          1241:                for (i = 0; i < ext - basename; i++)
        !          1242:                        if (isalnum((int)(basename[i])))
        !          1243:                                name[i] = basename[i];
        !          1244:                        else
        !          1245:                                name[i] = '_';
        !          1246:                name[ext - basename] = '\0';
        !          1247:                /* now try to open the .la file */
        !          1248:                file = fopen(filename, LTDL_READTEXT_MODE);
        !          1249:                if (!file)
        !          1250:                        last_error = file_not_found_error;
        !          1251:                if (!file && !dir) {
        !          1252:                        /* try other directories */
        !          1253:                        file = (FILE*) find_file(basename, 
        !          1254:                                                 user_search_path,
        !          1255:                                                 &dir, 0);
        !          1256:                        if (!file)
        !          1257:                                file = (FILE*) find_file(basename,
        !          1258:                                                 getenv("LTDL_LIBRARY_PATH"),
        !          1259:                                                 &dir, 0);
        !          1260: #ifdef LTDL_SHLIBPATH_VAR
        !          1261:                        if (!file)
        !          1262:                                file = (FILE*) find_file(basename,
        !          1263:                                                 getenv(LTDL_SHLIBPATH_VAR),
        !          1264:                                                 &dir, 0);
        !          1265: #endif
        !          1266:                }
        !          1267:                if (!file) {
        !          1268:                        if (name)
        !          1269:                                lt_dlfree(name);
        !          1270:                        if (dir)
        !          1271:                                lt_dlfree(dir);
        !          1272:                        return 0;
        !          1273:                }
        !          1274:                line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
        !          1275:                if (!line) {
        !          1276:                        fclose(file);
        !          1277:                        last_error = memory_error;
        !          1278:                        return 0;
        !          1279:                }
        !          1280:                /* read the .la file */
        !          1281:                while (!feof(file)) {
        !          1282:                        if (!fgets(line, LTDL_FILENAME_MAX, file))
        !          1283:                                break;
        !          1284:                        if (line[0] == '\n' || line[0] == '#')
        !          1285:                                continue;
        !          1286: #                      undef  STR_DLNAME
        !          1287: #                      define STR_DLNAME       "dlname="
        !          1288:                        if (strncmp(line, STR_DLNAME,
        !          1289:                                sizeof(STR_DLNAME) - 1) == 0)
        !          1290:                                error = trim(&dlname,
        !          1291:                                        &line[sizeof(STR_DLNAME) - 1]);
        !          1292:                        else
        !          1293: #                      undef  STR_OLD_LIBRARY
        !          1294: #                      define STR_OLD_LIBRARY  "old_library="
        !          1295:                        if (strncmp(line, STR_OLD_LIBRARY,
        !          1296:                                sizeof(STR_OLD_LIBRARY) - 1) == 0)
        !          1297:                                error = trim(&old_name,
        !          1298:                                        &line[sizeof(STR_OLD_LIBRARY) - 1]);
        !          1299:                        else
        !          1300: #                      undef  STR_LIBDIR
        !          1301: #                      define STR_LIBDIR       "libdir="
        !          1302:                        if (strncmp(line, STR_LIBDIR,
        !          1303:                                sizeof(STR_LIBDIR) - 1) == 0)
        !          1304:                                error = trim(&libdir,
        !          1305:                                        &line[sizeof(STR_LIBDIR) - 1]);
        !          1306:                        else
        !          1307: #                      undef  STR_DL_DEPLIBS
        !          1308: #                      define STR_DL_DEPLIBS   "dl_dependency_libs="
        !          1309:                        if (strncmp(line, STR_DL_DEPLIBS,
        !          1310:                                sizeof(STR_DL_DEPLIBS) - 1) == 0)
        !          1311:                                error = trim(&deplibs,
        !          1312:                                        &line[sizeof(STR_DL_DEPLIBS) - 1]);
        !          1313:                        else
        !          1314:                        if (strcmp(line, "installed=yes\n") == 0)
        !          1315:                                installed = 1;
        !          1316:                        else
        !          1317:                        if (strcmp(line, "installed=no\n") == 0)
        !          1318:                                installed = 0;
        !          1319:                        if (error)
        !          1320:                                break;
        !          1321:                }
        !          1322:                fclose(file);
        !          1323:                lt_dlfree(line);
        !          1324:                /* allocate the handle */
        !          1325:                handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
        !          1326:                if (!handle || error) {
        !          1327:                        if (handle)
        !          1328:                                lt_dlfree(handle);
        !          1329:                        if (!error)
        !          1330:                                last_error = memory_error;
        !          1331:                        free_vars(name, dir, dlname, old_name, libdir, deplibs);
        !          1332:                        return 0;
        !          1333:                }
        !          1334:                handle->usage = 0;
        !          1335:                if (load_deplibs(handle, deplibs) == 0) {
        !          1336:                        newhandle = handle;
        !          1337:                        /* find_module may replace newhandle */
        !          1338:                        if (find_module(&newhandle, dir, libdir, 
        !          1339:                                        dlname, old_name, installed)) {
        !          1340:                                unload_deplibs(handle);
        !          1341:                                error = 1;
        !          1342:                        }
        !          1343:                } else
        !          1344:                        error = 1;
        !          1345:                if (error) {
        !          1346:                        lt_dlfree(handle);
        !          1347:                        free_vars(name, dir, dlname, old_name, libdir, deplibs);
        !          1348:                        return 0;
        !          1349:                }
        !          1350:                if (handle != newhandle) {
        !          1351:                        unload_deplibs(handle);
        !          1352:                }
        !          1353:        } else {
        !          1354:                /* not a libtool module */
        !          1355:                handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
        !          1356:                if (!handle) {
        !          1357:                        last_error = memory_error;
        !          1358:                        if (dir)
        !          1359:                                lt_dlfree(dir);
        !          1360:                        return 0;
        !          1361:                }
        !          1362:                handle->usage = 0;
        !          1363:                /* non-libtool modules don't have dependencies */
        !          1364:                handle->depcount = 0;
        !          1365:                handle->deplibs = 0;
        !          1366:                newhandle = handle;
        !          1367:                if (tryall_dlopen(&newhandle, filename)
        !          1368:                    && (dir
        !          1369:                        || (!find_file(basename, user_search_path,
        !          1370:                                          0, &newhandle)
        !          1371:                            && !find_file(basename,
        !          1372:                                          getenv("LTDL_LIBRARY_PATH"),
        !          1373:                                          0, &newhandle)
        !          1374: #ifdef LTDL_SHLIBPATH_VAR
        !          1375:                            && !find_file(basename,
        !          1376:                                          getenv(LTDL_SHLIBPATH_VAR),
        !          1377:                                          0, &newhandle)
        !          1378: #endif
        !          1379:                                ))) {
        !          1380:                        lt_dlfree(handle);
        !          1381:                        if (dir)
        !          1382:                                lt_dlfree(dir);
        !          1383:                        return 0;
        !          1384:                }
        !          1385:        }
        !          1386: register_handle:
        !          1387:        if (newhandle != handle) {
        !          1388:                lt_dlfree(handle);
        !          1389:                handle = newhandle;
        !          1390:        }
        !          1391:        if (!handle->usage) {
        !          1392:                handle->usage = 1;
        !          1393:                handle->name = name;
        !          1394:                handle->next = handles;
        !          1395:                handles = handle;
        !          1396:        } else if (name)
        !          1397:                lt_dlfree(name);
        !          1398:        if (dir)
        !          1399:                lt_dlfree(dir);
        !          1400:        last_error = saved_error;
        !          1401:        return handle;
        !          1402: }
        !          1403: 
        !          1404: lt_dlhandle
        !          1405: lt_dlopenext (filename)
        !          1406:        const char *filename;
        !          1407: {
        !          1408:        lt_dlhandle handle;
        !          1409:        char    *tmp;
        !          1410:        int     len;
        !          1411:        const char *saved_error = last_error;
        !          1412:        
        !          1413:        if (!filename)
        !          1414:                return lt_dlopen(filename);
        !          1415:        len = strlen(filename);
        !          1416:        if (!len) {
        !          1417:                last_error = file_not_found_error;
        !          1418:                return 0;
        !          1419:        }
        !          1420:        /* try the normal file name */
        !          1421:        handle = lt_dlopen(filename);
        !          1422:        if (handle)
        !          1423:                return handle;
        !          1424:        /* try "filename.la" */
        !          1425:        tmp = (char*) lt_dlmalloc(len+4);
        !          1426:        if (!tmp) {
        !          1427:                last_error = memory_error;
        !          1428:                return 0;
        !          1429:        }
        !          1430:        strcpy(tmp, filename);
        !          1431:        strcat(tmp, ".la");
        !          1432:        handle = lt_dlopen(tmp);
        !          1433:        if (handle) {
        !          1434:                last_error = saved_error;
        !          1435:                lt_dlfree(tmp);
        !          1436:                return handle;
        !          1437:        }
        !          1438: #ifdef LTDL_SHLIB_EXT
        !          1439:        /* try "filename.EXT" */
        !          1440:        if (strlen(shlib_ext) > 3) {
        !          1441:                lt_dlfree(tmp);
        !          1442:                tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
        !          1443:                if (!tmp) {
        !          1444:                        last_error = memory_error;
        !          1445:                        return 0;
        !          1446:                }
        !          1447:                strcpy(tmp, filename);
        !          1448:        } else
        !          1449:                tmp[len] = '\0';
        !          1450:        strcat(tmp, shlib_ext);
        !          1451:        handle = lt_dlopen(tmp);
        !          1452:        if (handle) {
        !          1453:                last_error = saved_error;
        !          1454:                lt_dlfree(tmp);
        !          1455:                return handle;
        !          1456:        }
        !          1457: #endif 
        !          1458:        last_error = file_not_found_error;
        !          1459:        lt_dlfree(tmp);
        !          1460:        return 0;
        !          1461: }
        !          1462: 
        !          1463: int
        !          1464: lt_dlclose (handle)
        !          1465:        lt_dlhandle handle;
        !          1466: {
        !          1467:        lt_dlhandle cur, last;
        !          1468:        
        !          1469:        /* check whether the handle is valid */
        !          1470:        last = cur = handles;
        !          1471:        while (cur && handle != cur) {
        !          1472:                last = cur;
        !          1473:                cur = cur->next;
        !          1474:        }
        !          1475:        if (!cur) {
        !          1476:                last_error = invalid_handle_error;
        !          1477:                return 1;
        !          1478:        }
        !          1479:        handle->usage--;
        !          1480:        if (!handle->usage) {
        !          1481:                int     error;
        !          1482:        
        !          1483:                if (handle != handles)
        !          1484:                        last->next = handle->next;
        !          1485:                else
        !          1486:                        handles = handle->next;
        !          1487:                error = handle->type->lib_close(handle);
        !          1488:                error += unload_deplibs(handle);
        !          1489:                if (handle->filename)
        !          1490:                        lt_dlfree(handle->filename);
        !          1491:                if (handle->name)
        !          1492:                        lt_dlfree(handle->name);
        !          1493:                lt_dlfree(handle);
        !          1494:                return error;
        !          1495:        }
        !          1496:        return 0;
        !          1497: }
        !          1498: 
        !          1499: lt_ptr_t
        !          1500: lt_dlsym (handle, symbol)
        !          1501:        lt_dlhandle handle;
        !          1502:        const char *symbol;
        !          1503: {
        !          1504:        int     lensym;
        !          1505:        char    lsym[LTDL_SYMBOL_LENGTH];
        !          1506:        char    *sym;
        !          1507:        lt_ptr_t address;
        !          1508: 
        !          1509:        if (!handle) {
        !          1510:                last_error = invalid_handle_error;
        !          1511:                return 0;
        !          1512:        }
        !          1513:        if (!symbol) {
        !          1514:                last_error = symbol_error;
        !          1515:                return 0;
        !          1516:        }
        !          1517:        lensym = strlen(symbol);
        !          1518:        if (handle->type->sym_prefix)
        !          1519:                lensym += strlen(handle->type->sym_prefix);
        !          1520:        if (handle->name)
        !          1521:                lensym += strlen(handle->name);
        !          1522:        if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
        !          1523:                sym = lsym;
        !          1524:        else
        !          1525:                sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
        !          1526:        if (!sym) {
        !          1527:                last_error = buffer_overflow_error;
        !          1528:                return 0;
        !          1529:        }
        !          1530:        if (handle->name) {
        !          1531:                const char *saved_error = last_error;
        !          1532:                
        !          1533:                /* this is a libtool module */
        !          1534:                if (handle->type->sym_prefix) {
        !          1535:                        strcpy(sym, handle->type->sym_prefix);
        !          1536:                        strcat(sym, handle->name);
        !          1537:                } else
        !          1538:                        strcpy(sym, handle->name);
        !          1539:                strcat(sym, "_LTX_");
        !          1540:                strcat(sym, symbol);
        !          1541:                /* try "modulename_LTX_symbol" */
        !          1542:                address = handle->type->find_sym(handle, sym);
        !          1543:                if (address) {
        !          1544:                        if (sym != lsym)
        !          1545:                                lt_dlfree(sym);
        !          1546:                        return address;
        !          1547:                }
        !          1548:                last_error = saved_error;
        !          1549:        }
        !          1550:        /* otherwise try "symbol" */
        !          1551:        if (handle->type->sym_prefix) {
        !          1552:                strcpy(sym, handle->type->sym_prefix);
        !          1553:                strcat(sym, symbol);
        !          1554:        } else
        !          1555:                strcpy(sym, symbol);
        !          1556:        address = handle->type->find_sym(handle, sym);
        !          1557:        if (sym != lsym)
        !          1558:                lt_dlfree(sym);
        !          1559:        return address;
        !          1560: }
        !          1561: 
        !          1562: const char *
        !          1563: lt_dlerror LTDL_PARAMS((void))
        !          1564: {
        !          1565:        const char *error = last_error;
        !          1566:        
        !          1567:        last_error = 0;
        !          1568:        return error;
        !          1569: }
        !          1570: 
        !          1571: int
        !          1572: lt_dladdsearchdir (search_dir)
        !          1573:        const char *search_dir;
        !          1574: {
        !          1575:        if (!search_dir || !strlen(search_dir))
        !          1576:                return 0;
        !          1577:        if (!user_search_path) {
        !          1578:                user_search_path = strdup(search_dir);
        !          1579:                if (!user_search_path) {
        !          1580:                        last_error = memory_error;
        !          1581:                        return 1;
        !          1582:                }
        !          1583:        } else {
        !          1584:                char    *new_search_path = (char*)
        !          1585:                        lt_dlmalloc(strlen(user_search_path) + 
        !          1586:                                strlen(search_dir) + 2); /* ':' + '\0' == 2 */
        !          1587:                if (!new_search_path) {
        !          1588:                        last_error = memory_error;
        !          1589:                        return 1;
        !          1590:                }
        !          1591:                strcpy(new_search_path, user_search_path);
        !          1592:                strcat(new_search_path, ":");
        !          1593:                strcat(new_search_path, search_dir);
        !          1594:                lt_dlfree(user_search_path);
        !          1595:                user_search_path = new_search_path;
        !          1596:        }
        !          1597:        return 0;
        !          1598: }
        !          1599: 
        !          1600: int
        !          1601: lt_dlsetsearchpath (search_path)
        !          1602:        const char *search_path;
        !          1603: {
        !          1604:        if (user_search_path)
        !          1605:                lt_dlfree(user_search_path);
        !          1606:        user_search_path = 0; /* reset the search path */
        !          1607:        if (!search_path || !strlen(search_path))
        !          1608:                return 0;
        !          1609:        user_search_path = strdup(search_path);
        !          1610:        if (!user_search_path)
        !          1611:                return 1;
        !          1612:        return 0;
        !          1613: }
        !          1614: 
        !          1615: const char *
        !          1616: lt_dlgetsearchpath LTDL_PARAMS((void))
        !          1617: {
        !          1618:        return user_search_path;
        !          1619: }

E-mail: