Annotation of sql/pgsql/libltdl/ltdl.c, revision 1.1.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: