2001-05-23 15:26:42 +02:00
/*
* PROGRAM : JRD Access Method
* MODULE : flu . c
* DESCRIPTION : Function Lookup Code
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy
* of the License at http : //www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* " AS IS " basis , WITHOUT WARRANTY OF ANY KIND , either express
* or implied . See the License for the specific language governing
* rights and limitations under the License .
*
* The Original Code was created by Inprise Corporation
* and its predecessors . Portions created by Inprise Corporation are
* Copyright ( C ) Inprise Corporation .
*
* All Rights Reserved .
* Contributor ( s ) : ______________________________________ .
2002-02-16 03:21:35 +01:00
*
* 2002.02 .15 Sean Leyne - Code Cleanup , removed obsolete " EPSON " define
*
2001-05-23 15:26:42 +02:00
*/
/*
2002-02-16 03:21:35 +01:00
$ Id : flu . cpp , v 1.6 2002 - 02 - 16 02 : 21 : 27 seanleyne Exp $
2001-05-23 15:26:42 +02:00
*/
2001-07-29 19:42:23 +02:00
# include "firebird.h"
# include <string>
using namespace std ;
2001-05-23 15:26:42 +02:00
# include "../jrd/common.h"
# include "../jrd/flu.h"
# include "../jrd/gdsassert.h"
# ifdef SHLIB_DEFS
// TMN: Why the ... declare this one in the middle of a buch of includes?!
extern " C " {
# define FUNCTIONS_entrypoint (*_libgds_FUNCTIONS_entrypoint)
}
# endif
# include "../jrd/flu_proto.h"
# include "../jrd/gds_proto.h"
# include "../jrd/dls_proto.h"
# include <string.h>
/* VMS Specific Stuff */
# ifdef VMS
# include <descrip.h>
# include <ssdef.h>
static int condition_handler ( int * , int * , int * ) ;
# endif
/* HP-UX specific stuff */
# if (defined HP700 || defined HP10)
# include <dl.h>
# include <shl.h>
# include <unistd.h>
# include <libgen.h>
# define IB_UDF_DIR "UDF / "
# endif
# ifdef HM300
# define _A_OUT_INCLUDED
# include <dl.h>
# include <shl.h>
# endif
2002-02-16 03:21:35 +01:00
/* SGI, UNIXWARE, M88K, DECOSF specific stuff */
2001-05-23 15:26:42 +02:00
2002-02-16 03:21:35 +01:00
# if (defined SOLARIS || defined sgi || defined M88K || defined UNIXWARE || defined NCR3000 || defined DECOSF || defined SCO_EV || defined linux || defined AIX_PPC)
2001-05-23 15:26:42 +02:00
# include <dlfcn.h>
# define DYNAMIC_SHARED_LIBRARIES
# include <unistd.h>
# include <libgen.h>
# define IB_UDF_DIR "UDF / "
# endif
2001-07-12 07:46:06 +02:00
# ifdef DARWIN
# include <unistd.h>
# include <mach-o/dyld.h>
# define IB_UDF_DIR "UDF / "
# endif
2001-05-23 15:26:42 +02:00
# if defined FREEBSD || defined NETBSD
# include <dlfcn.h>
# define DYNAMIC_SHARED_LIBRARIES
# include <unistd.h>
# define IB_UDF_DIR "UDF / "
2001-07-12 07:46:06 +02:00
# endif
# if defined FREEBSD || defined NETBSD || defined DARWIN
2001-05-23 15:26:42 +02:00
/*
* Define our own dirname ( ) , because we don ' t have a syscall for it .
* ! ! WARNING ! ! WARNING ! ! WARNING ! !
* I ' m hoping that the use of static result is OK here , and justify
* its use by noting that A ) we ' re not using threads , and B ) callers
* don ' t seem to hang onto the result for very long . Since none of
* its callers ever have to clean up anyway , I ' m assuming that real
* syscall versions do it the same way , except that they probably offer
* thread - safeness as well .
*/
const char * dirname ( const char * fname )
{
static char result [ 512 ] ;
int i = 0 ;
int last = 0 ;
if ( strlen ( fname ) = = 0 )
return " . " ;
strcpy ( result , fname ) ;
2001-05-24 16:54:26 +02:00
while ( * fname )
{
2001-05-23 15:26:42 +02:00
i + + ;
if ( * fname = = ' / ' )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
last = i ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
fname + + ;
}
2001-05-24 16:54:26 +02:00
if ( last = = 0 )
{
2001-05-23 15:26:42 +02:00
last = 1 ;
result [ 0 ] = ' . ' ;
}
result [ last ] = ' \0 ' ;
return result ;
}
# endif
2001-05-24 16:54:26 +02:00
static void terminate_at_space ( char * psz )
{
while ( * psz & & * psz ! = ' ' )
{
+ + psz ;
}
if ( * psz ) {
* psz = ' \0 ' ;
}
}
2001-05-23 15:26:42 +02:00
/* DG specific stuff */
# ifdef DGUX
# include <sys/stat.h>
# include <sys/types.h>
# define NON_DL_COMPATIBLE
# ifndef NON_DL_COMPATIBLE
# include <dlfcn.h>
# endif
# endif
/* Windows NT stuff */
# ifdef WIN_NT
2001-12-24 03:51:06 +01:00
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# define NOUSER
# define NOGDI
# define NOCRYPT
# define NOMCX
# define NOIME
# ifndef NOMSG
# define NOMSG
# endif
# define NOSERVICE
2001-05-23 15:26:42 +02:00
# include <windows.h>
# include <stdlib.h>
# include <io.h>
# define IB_UDF_DIR "UDF\\"
/* Where is the international character set module found? */
# define IB_INTL_DIR "intl\\"
# endif
extern " C " {
/* Where is the international character set module found? */
# ifndef IB_INTL_DIR
# define IB_INTL_DIR "intl / "
# endif
static MOD FLU_modules = 0 ; /* External function/filter modules */
/* prototypes for private functions */
static MOD search_for_module ( TEXT * , TEXT * ) ;
# ifdef WIN_NT
static void adjust_loadlib_name ( TEXT * , TEXT * ) ;
# endif
MOD FLU_lookup_module ( TEXT * module )
{
/**************************************
*
* F L U _ l o o k u p _ m o d u l e
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup external function module descriptor .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-24 16:54:26 +02:00
# ifndef WIN_NT
terminate_at_space ( module ) ;
2001-05-23 15:26:42 +02:00
# endif
2001-05-24 16:54:26 +02:00
const USHORT length = strlen ( module ) ;
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
for ( MOD mod = FLU_modules ; mod ; mod = mod - > mod_next )
{
2001-05-23 15:26:42 +02:00
if ( mod - > mod_length = = length & & ! strcmp ( mod - > mod_name , module ) )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
return mod ;
2001-05-24 16:54:26 +02:00
}
}
2001-05-23 15:26:42 +02:00
return 0 ;
}
void FLU_unregister_module ( MOD module )
{
/**************************************
*
* F L U _ u n r e g i s t e r _ m o d u l e
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Unregister interest in an external function module .
* Unload module if it ' s uninteresting .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
MOD * mod ;
2001-07-12 07:46:06 +02:00
# ifdef DARWIN
2002-02-16 03:21:35 +01:00
NSSymbol symbol ;
2001-07-12 07:46:06 +02:00
void ( * fini ) ( void ) ;
# endif
2001-05-23 15:26:42 +02:00
/* Module is in-use by other databases.*/
if ( - - module - > mod_use_count > 0 )
return ;
/* Unlink from list of active modules, unload it, and release memory. */
for ( mod = & FLU_modules ; * mod ; mod = & ( * mod ) - > mod_next )
2001-05-24 16:54:26 +02:00
{
if ( * mod = = module )
{
2001-05-23 15:26:42 +02:00
* mod = module - > mod_next ;
break ;
}
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
# if (defined HP700 || defined HP10)
shl_unload ( module - > mod_handle ) ;
# endif
# if defined(SOLARIS) || defined(LINUX) || defined(FREEBSD) || defined(NETBSD) || defined (AIX_PPC)
dlclose ( module - > mod_handle ) ;
# endif
# ifdef WIN_NT
FreeLibrary ( module - > mod_handle ) ;
# endif
2001-07-12 07:46:06 +02:00
# ifdef DARWIN
/* Make sure the fini function gets called, if there is one */
symbol = NSLookupSymbolInModule ( module - > mod_handle , " __fini " ) ;
if ( symbol ! = NULL )
{
fini = ( void ( * ) ( void ) ) NSAddressOfSymbol ( symbol ) ;
fini ( ) ;
2002-02-16 03:21:35 +01:00
}
2001-07-12 07:46:06 +02:00
NSUnLinkModule ( module - > mod_handle , 0 ) ;
# endif
2001-05-23 15:26:42 +02:00
gds__free ( module ) ;
}
# ifdef VMS
# define LOOKUP
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name , TEXT * ib_path_env_var )
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( V M S )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
TEXT * p ;
struct dsc $ descriptor mod_desc , nam_desc ;
TEXT absolute_module [ MAXPATHLEN ] ;
if ( function = FUNCTIONS_entrypoint ( module , name ) )
return function ;
if ( ib_path_env_var = = NULL )
strcpy ( absolute_module , module ) ;
else
if ( ! gds__validate_lib_path
( module , ib_path_env_var , absolute_module ,
sizeof ( absolute_module ) ) ) return NULL ;
REPLACE THIS COMPILER ERROR WITH CODE TO VERIFY THAT THE MODULE IS FOUND
EITHER IN $ INTERBASE : UDF , or $ INTERBASE : intl ,
OR IN ONE OF THE DIRECTORIES NAMED IN EXTERNAL_FUNCTION_DIRECTORY
LINES IN ISC_CONFIG . for ( p = absolute_module ; * p & & * p ! = ' ' ; p + + ) ;
ISC_make_desc ( absolute_module , & mod_desc , p - absolute_module ) ;
2001-05-24 16:54:26 +02:00
p = name ;
while ( * p & & * p ! = ' ' )
{
+ + p ;
}
2001-05-23 15:26:42 +02:00
ISC_make_desc ( name , & nam_desc , p - name ) ;
VAXC $ ESTABLISH ( condition_handler ) ;
if ( ! ( lib $ find_image_symbol ( & mod_desc , & nam_desc , & function , NULL ) & 1 ) )
return NULL ;
return function ;
}
# endif
/*
The commented # if which immediately follows has been replaced .
The OLD_AIX and OLD_AIX_PPC # if has been added to disable the
code segment for current AIX builds .
*/
/*
# if (defined AIX || defined AIX_PPC)
*/
# if (defined OLD_AIX || defined OLD_AIX_PPC)
# define LOOKUP
2001-05-24 16:54:26 +02:00
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name ,
TEXT * ib_path_env_var )
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( A I X )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
TEXT * p ;
TEXT absolute_module [ MAXPATHLEN ] ;
2001-05-24 16:54:26 +02:00
function = FUNCTIONS_entrypoint ( module , name ) ;
if ( function )
{
2001-05-23 15:26:42 +02:00
return function ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
terminate_at_space ( module ) ;
2001-05-23 15:26:42 +02:00
if ( ib_path_env_var = = NULL )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
strcpy ( absolute_module , module ) ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
else
2001-05-24 16:54:26 +02:00
{
if ( ! gds__validate_lib_path ( module ,
ib_path_env_var ,
absolute_module ,
sizeof ( absolute_module ) ) )
{
return NULL ;
}
}
2001-05-23 15:26:42 +02:00
REPLACE THIS COMPILER ERROR WITH CODE TO VERIFY THAT THE MODULE IS FOUND
EITHER IN $ INTERBASE / UDF , OR $ INTERBASE / intl ,
OR IN ONE OF THE DIRECTORIES NAMED IN EXTERNAL_FUNCTION_DIRECTORY
LINES IN ISC_CONFIG . function = load ( absolute_module , 0 , NULL ) ;
return function ;
}
# endif
# if (defined HP700 || defined HP10)
# define LOOKUP
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name , TEXT * ib_path_env_var )
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( H P 9 0 0 0 s 7 0 0 )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
TEXT * p ;
2001-05-24 16:54:26 +02:00
function = FUNCTIONS_entrypoint ( module , name ) ;
if ( function )
{
2001-05-23 15:26:42 +02:00
return function ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
terminate_at_space ( module ) ;
terminate_at_space ( name ) ;
2001-05-23 15:26:42 +02:00
if ( ! * module | | ! * name )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
// Check if external function module has already been loaded
MOD mod = FLU_lookup_module ( module ) ;
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
if ( ! mod )
{
TEXT absolute_module [ MAXPATHLEN ] ;
2001-05-23 15:26:42 +02:00
# ifdef EXT_LIB_PATH
if ( ib_path_env_var = = NULL )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
strcpy ( absolute_module , module ) ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
else
2001-05-24 16:54:26 +02:00
{
if ( ! gds__validate_lib_path ( module ,
ib_path_env_var ,
absolute_module ,
sizeof ( absolute_module ) ) )
{
return NULL ;
}
}
2001-05-23 15:26:42 +02:00
# else
strcpy ( absolute_module , module ) ;
# endif /* EXT_LIB_PATH */
2001-05-24 16:54:26 +02:00
const USHORT length = strlen ( absolute_module ) ;
2001-05-23 15:26:42 +02:00
2002-02-16 03:21:35 +01:00
/* call search_for_module with the supplied name,
2001-05-23 15:26:42 +02:00
and if unsuccessful , then with < name > . sl . */
mod = search_for_module ( absolute_module , name ) ;
2001-05-24 16:54:26 +02:00
if ( ! mod )
{
2001-05-23 15:26:42 +02:00
strcat ( absolute_module , " .sl " ) ;
mod = search_for_module ( absolute_module , name ) ;
}
if ( ! mod )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
assert ( mod - > mod_handle ) ; /* assert that we found the module */
mod - > mod_use_count = 0 ;
mod - > mod_length = length ;
strcpy ( mod - > mod_name , module ) ;
mod - > mod_next = FLU_modules ;
FLU_modules = mod ;
}
+ + mod - > mod_use_count ;
if ( shl_findsym ( & mod - > mod_handle , name , TYPE_PROCEDURE , & function ) )
return NULL ;
return function ;
}
static MOD search_for_module ( TEXT * module , TEXT * name )
{
/**************************************
*
* s e a r c h _ f o r _ m o d u l e ( H P 9 0 0 0 s 7 0 0 )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Look for a module ( as named in a ' DECLARE EXTERNAL FUNCTION '
* statement .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
MOD mod ;
char * dirp ;
TEXT ib_lib_path [ MAXPATHLEN ] ;
TEXT absolute_module [ MAXPATHLEN ] ;
FDLS * dir_list ;
BOOLEAN found_module ;
strcpy ( absolute_module , module ) ;
if ( ! ( mod = ( MOD ) gds__alloc ( sizeof ( struct mod ) +
strlen ( absolute_module ) ) ) ) return NULL ;
dirp = dirname ( absolute_module ) ;
2001-05-24 16:54:26 +02:00
if ( ( ' . ' = = dirp [ 0 ] ) & & ( ' \0 ' = = dirp [ 1 ] ) )
{
2001-05-23 15:26:42 +02:00
/* We have a simple module name, without a directory. */
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
strncat ( ib_lib_path , module , MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! access ( ib_lib_path , R_OK | X_OK ) )
{
2001-05-23 15:26:42 +02:00
/* Module is in the default UDF directory: load it. */
2001-05-24 16:54:26 +02:00
if ( ! ( mod - > mod_handle = shl_load ( ib_lib_path , BIND_DEFERRED , 0 ) ) )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! access ( ib_lib_path , R_OK | X_OK ) )
{
2001-05-23 15:26:42 +02:00
/* Module is in the international character set directory:
load it . */
2001-05-24 16:54:26 +02:00
mod - > mod_handle = shl_load ( ib_lib_path , BIND_DEFERRED , 0 ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
/* The module is not in a default directory, so ...
* use the EXTERNAL_FUNCTION_DIRECTORY lines from isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
found_module = FALSE ;
2001-05-24 16:54:26 +02:00
while ( dir_list & & ! found_module )
{
2001-05-23 15:26:42 +02:00
strcpy ( ib_lib_path , dir_list - > fdls_directory ) ;
strcat ( ib_lib_path , " / " ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! access ( ib_lib_path , R_OK | X_OK ) )
{
mod - > mod_handle = shl_load ( ib_lib_path ,
BIND_DEFERRED , 0 ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
found_module = TRUE ;
}
dir_list = dir_list - > fdls_next ;
}
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
} /* else module is not in the INTL directory */
} /* else module is not in the default UDF directory, so ... */
} /* if dirname is "." */
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
/* The module name includes a directory path.
* The directory must be the standard UDF directory , or the
2001-05-24 16:54:26 +02:00
* standard international directory , or listed in
2001-05-23 15:26:42 +02:00
* an EXTERNAL_FUNCTION_DIRECTORY line in isc_config ,
* and the module must be accessible in that directory .
*/
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
ib_lib_path [ strlen ( ib_lib_path ) - 1 ] = ' \0 ' ; /* drop trailing "/" */
found_module = ! strcmp ( ib_lib_path , dirp ) ;
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
ib_lib_path [ strlen ( ib_lib_path ) - 1 ] = ' \0 ' ; /* drop trailing / */
found_module = ! strcmp ( ib_lib_path , dirp ) ;
}
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
/* It's not the default directory, so try the ones listed
* in EXTERNAL_FUNCTION_DIRECTORY lines in isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
2001-05-24 16:54:26 +02:00
while ( dir_list & & ! found_module )
{
2001-05-23 15:26:42 +02:00
if ( ! strcmp ( dir_list - > fdls_directory , dirp ) )
found_module = TRUE ;
dir_list = dir_list - > fdls_next ;
}
}
if ( found_module )
found_module = ( ! access ( module , R_OK | X_OK ) ) & &
( 0 ! = ( mod - > mod_handle = shl_load ( module , BIND_DEFERRED , 0 ) ) ) ;
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
} /* else module name includes a directory path, so ... */
return mod ;
}
# endif
# ifdef HM300
# define LOOKUP
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name , TEXT * ib_path_env_var )
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( H P 9 0 0 0 s 3 0 0 )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
shl_t handle ;
TEXT buffer [ 256 ] ;
TEXT absolute_module [ MAXPATHLEN ] ;
if ( function = FUNCTIONS_entrypoint ( module , name ) )
return function ;
2001-05-24 16:54:26 +02:00
terminate_at_space ( module ) ;
TEXT * p = buffer ;
2001-05-23 15:26:42 +02:00
* p + + = ' _ ' ;
for ( ; ( * p = * name ) & & * name ! = ' ' ; p + + , name + + ) ;
* p = 0 ;
if ( ib_path_env_var = = NULL )
strcpy ( absolute_module , module ) ;
else
if ( ! gds__validate_lib_path
( module , ib_path_env_var , absolute_module ,
sizeof ( absolute_module ) ) ) return NULL ;
REPLACE THIS COMPILER ERROR WITH CODE TO VERIFY THAT THE MODULE IS FOUND
EITHER IN $ INTERBASE / UDF , OR $ INTERBASE / intl ,
OR IN ONE OF THE DIRECTORIES NAMED IN EXTERNAL_FUNCTION_DIRECTORY
LINES IN
2001-05-24 16:54:26 +02:00
ISC_CONFIG .
if ( ! ( handle = shl_load ( absolute_module , BIND_DEFERRED , 0L ) ) | |
shl_findsym ( & handle , buffer , TYPE_PROCEDURE , & function ) )
2001-05-23 15:26:42 +02:00
return NULL ;
return function ;
}
# endif
# ifdef DYNAMIC_SHARED_LIBRARIES
# define LOOKUP
2001-05-24 16:54:26 +02:00
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name ,
TEXT * ib_path_env_var )
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( SVR4 including SOLARIS )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
TEXT * p ;
2001-05-24 16:54:26 +02:00
function = FUNCTIONS_entrypoint ( module , name ) ;
if ( function )
{
2001-05-23 15:26:42 +02:00
return function ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
# ifdef NON_DL_COMPATIBLE
return NULL ;
# else
2001-05-24 16:54:26 +02:00
terminate_at_space ( module ) ;
terminate_at_space ( name ) ;
2001-05-23 15:26:42 +02:00
if ( ! * module | | ! * name )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
// Check if external function module has already been loaded
MOD mod = FLU_lookup_module ( module ) ;
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
if ( ! mod )
{
TEXT absolute_module [ MAXPATHLEN ] ;
2001-05-23 15:26:42 +02:00
# ifdef EXT_LIB_PATH
if ( ib_path_env_var = = NULL )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
strcpy ( absolute_module , module ) ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
else
2001-05-24 16:54:26 +02:00
{
if ( ! gds__validate_lib_path ( module ,
ib_path_env_var ,
absolute_module ,
sizeof ( absolute_module ) ) )
{
return NULL ;
}
}
2001-05-23 15:26:42 +02:00
# else
strcpy ( absolute_module , module ) ;
# endif /* EXT_LIB_PATH */
2001-05-24 16:54:26 +02:00
const USHORT length = strlen ( absolute_module ) ;
2001-05-23 15:26:42 +02:00
2002-02-16 03:21:35 +01:00
/* call search_for_module with the supplied name,
2001-05-23 15:26:42 +02:00
and if unsuccessful , then with < name > . so . */
mod = search_for_module ( absolute_module , name ) ;
2001-07-29 19:42:23 +02:00
if ( ! mod ) {
2001-05-23 15:26:42 +02:00
strcat ( absolute_module , " .so " ) ;
mod = search_for_module ( absolute_module , name ) ;
}
2001-07-29 19:42:23 +02:00
2002-02-16 03:21:35 +01:00
if ( ! mod ) { // Start looking for "libxxxx.so" module names
2001-07-29 19:42:23 +02:00
string moduleName = " lib " ;
moduleName + = ( const char * ) absolute_module ;
mod = search_for_module ( ( TEXT * ) moduleName . c_str ( ) , name ) ;
}
if ( ! mod ) {
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
assert ( mod - > mod_handle ) ; /* assert that we found the module */
mod - > mod_use_count = 0 ;
mod - > mod_length = length ;
strcpy ( mod - > mod_name , module ) ;
mod - > mod_next = FLU_modules ;
FLU_modules = mod ;
}
+ + mod - > mod_use_count ;
2001-07-29 19:42:23 +02:00
return ( FPTR_INT ) dlsym ( mod - > mod_handle , name ) ;
2001-05-23 15:26:42 +02:00
# endif /* NON_DL_COMPATIBLE */
}
static MOD search_for_module ( TEXT * module , TEXT * name )
{
/**************************************
*
* s e a r c h _ f o r _ m o d u l e ( SVR4 including SOLARIS )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Look for a module ( as named in a ' DECLARE EXTERNAL FUNCTION '
* statement .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
TEXT ib_lib_path [ MAXPATHLEN ] ;
TEXT absolute_module [ MAXPATHLEN ] ; /* for _access() ??? */
FDLS * dir_list ;
BOOLEAN found_module ;
strcpy ( absolute_module , module ) ;
2001-05-24 16:54:26 +02:00
MOD mod = ( MOD ) gds__alloc ( sizeof ( struct mod ) + strlen ( absolute_module ) ) ;
if ( ! mod )
{
return NULL ;
}
char * dirp = dirname ( absolute_module ) ;
if ( ( ' . ' = = dirp [ 0 ] ) & & ( ' \0 ' = = dirp [ 1 ] ) )
{
2001-05-23 15:26:42 +02:00
/* We have a simple module name without a directory. */
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
strncat ( ib_lib_path , module , MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! access ( ib_lib_path , R_OK ) )
{
2001-05-23 15:26:42 +02:00
/* Module is in the standard UDF directory: load it. */
2001-05-24 16:54:26 +02:00
if ( ! ( mod - > mod_handle = dlopen ( ib_lib_path , RTLD_LAZY ) ) )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! access ( ib_lib_path , R_OK ) )
{
2001-05-23 15:26:42 +02:00
/* Module is in the default directory: load it. */
2001-05-24 16:54:26 +02:00
mod - > mod_handle = dlopen ( ib_lib_path , RTLD_LAZY ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
/* The module is not in the default directory, so ...
* use the EXTERNAL_FUNCTION_DIRECTORY lines from isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
found_module = FALSE ;
2001-05-24 16:54:26 +02:00
while ( dir_list & & ! found_module )
{
2001-05-23 15:26:42 +02:00
strcpy ( ib_lib_path , dir_list - > fdls_directory ) ;
strcat ( ib_lib_path , " / " ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! access ( ib_lib_path , R_OK ) )
{
mod - > mod_handle = dlopen ( ib_lib_path , RTLD_LAZY ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
found_module = TRUE ;
}
dir_list = dir_list - > fdls_next ;
}
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
} /* else module is not in the INTL directory */
} /* else module is not in the default directory, so ... */
} /* if *dirp is "." */
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
/* The module name includes a directory path.
* The directory must be the standard UDF directory , or the
* standard international directory , or listed in
* an EXTERNAL_FUNCTION_DIRECTORY line in isc_config ,
* and the module must be accessible in that directory .
*/
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
ib_lib_path [ strlen ( ib_lib_path ) - 1 ] = ' \0 ' ; /* drop trailing "/" */
2001-05-24 16:54:26 +02:00
2001-05-23 15:26:42 +02:00
found_module = ! strcmp ( ib_lib_path , dirp ) ;
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
ib_lib_path [ strlen ( ib_lib_path ) - 1 ] = ' \0 ' ; /* drop trailing / */
found_module = ! strcmp ( ib_lib_path , dirp ) ;
}
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
/* It's not the default directory, so try the ones listed
* in EXTERNAL_FUNCTION_DIRECTORY lines in isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
2001-05-24 16:54:26 +02:00
while ( dir_list & & ! found_module )
{
2001-05-23 15:26:42 +02:00
if ( ! strcmp ( dir_list - > fdls_directory , dirp ) )
found_module = TRUE ;
dir_list = dir_list - > fdls_next ;
}
}
if ( found_module )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
found_module = ( ! access ( module , R_OK ) ) & &
( 0 ! = ( mod - > mod_handle = dlopen ( module , RTLD_LAZY ) ) ) ;
2001-05-24 16:54:26 +02:00
}
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
} /* else module name includes a directory path, so ... */
return mod ;
}
# endif
# ifdef DGUX
# define LOOKUP
2001-05-24 16:54:26 +02:00
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name ,
TEXT * ib_path_env_var )
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( D G U X )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
TEXT * p ;
void * handle ;
struct stat stdbuf ;
TEXT absolute_module [ MAXPATHLEN ] ;
if ( function = FUNCTIONS_entrypoint ( module , name ) )
return function ;
# ifdef NON_DL_COMPATIBLE
return NULL ;
# else
2001-05-24 16:54:26 +02:00
terminate_at_space ( module ) ;
terminate_at_space ( name ) ;
2001-05-23 15:26:42 +02:00
if ( ! * module | | stat ( module , & stdbuf ) )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
if ( ib_path_env_var = = NULL )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
strcpy ( absolute_module , module ) ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
else
2001-05-24 16:54:26 +02:00
{
if ( ! gds__validate_lib_path ( module ,
ib_path_env_var ,
absolute_module ,
sizeof ( absolute_module ) ) )
{
return NULL ;
}
}
2001-05-23 15:26:42 +02:00
REPLACE THIS COMPILER ERROR WITH CODE TO VERIFY THAT THE MODULE IS FOUND
EITHER IN $ INTERBASE / UDF , OR $ INTERBASE / intl ,
OR IN ONE OF THE DIRECTORIES NAMED IN EXTERNAL_FUNCTION_DIRECTORY
LINES IN
2001-05-24 16:54:26 +02:00
ISC_CONFIG .
if ( ! ( handle = dlopen ( absolute_module , RTLD_LAZY ) ) )
return NULL ;
2001-05-23 15:26:42 +02:00
return dlsym ( handle , name ) ;
# endif
}
# endif
# ifdef WIN_NT
# define LOOKUP
2001-05-24 16:54:26 +02:00
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name ,
TEXT * ib_path_env_var )
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( W I N _ N T )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
2002-02-16 03:21:35 +01:00
* If ib_path_env_var is defined , make sure
2001-05-23 15:26:42 +02:00
* that the module is in the path defined
* by that environment variable .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
2001-05-24 16:54:26 +02:00
function = FUNCTIONS_entrypoint ( module , name ) ;
if ( function )
{
2001-05-23 15:26:42 +02:00
return function ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
terminate_at_space ( name ) ;
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
// Check if external function module has already been loaded
MOD mod = FLU_lookup_module ( module ) ;
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
if ( ! mod )
{
TEXT absolute_module [ MAXPATHLEN ] ; // for _access()
2001-05-23 15:26:42 +02:00
# ifdef EXT_LIB_PATH
if ( ib_path_env_var = = NULL )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
strcpy ( absolute_module , module ) ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
else
2001-05-24 16:54:26 +02:00
{
if ( ! gds__validate_lib_path ( module ,
ib_path_env_var ,
absolute_module ,
sizeof ( absolute_module ) ) )
{
return NULL ;
}
}
2001-05-23 15:26:42 +02:00
# else
strcpy ( absolute_module , module ) ;
# endif /* EXT_LIB_PATH */
2001-05-24 16:54:26 +02:00
const USHORT length = strlen ( absolute_module ) ;
2001-05-23 15:26:42 +02:00
/* call search_for_module with the supplied name, and if unsuccessful,
then with < name > . DLL ( if the name did not have a trailing " . " ) . */
mod = search_for_module ( absolute_module , name ) ;
2001-05-24 16:54:26 +02:00
if ( ! mod )
{
2001-05-23 15:26:42 +02:00
if ( ( absolute_module [ length - 1 ] ! = ' . ' ) & &
2001-05-24 16:54:26 +02:00
stricmp ( absolute_module + length - 4 , " .DLL " ) )
{
2001-05-23 15:26:42 +02:00
strcat ( absolute_module , " .DLL " ) ;
mod = search_for_module ( absolute_module , name ) ;
}
}
if ( ! mod )
2001-05-24 16:54:26 +02:00
{
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
assert ( mod - > mod_handle ) ; /* assert that we found the module */
mod - > mod_use_count = 0 ;
mod - > mod_length = length ;
strcpy ( mod - > mod_name , module ) ;
mod - > mod_next = FLU_modules ;
FLU_modules = mod ;
}
+ + mod - > mod_use_count ;
2001-05-24 16:54:26 +02:00
// The Borland compiler prefixes an '_' for functions compiled
// with the __cdecl calling convention.
// TMN: Doesn't all_ ompilers do that?
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
function = ( FPTR_INT ) GetProcAddress ( mod - > mod_handle , name ) ;
if ( ! function )
{
2001-05-23 15:26:42 +02:00
TEXT buffer [ 128 ] ;
2001-05-24 16:54:26 +02:00
buffer [ 0 ] = ' _ ' ;
strcpy ( & buffer [ 1 ] , name ) ;
2001-05-23 15:26:42 +02:00
function = ( FPTR_INT ) GetProcAddress ( mod - > mod_handle , buffer ) ;
}
return function ;
}
2001-05-24 16:54:26 +02:00
static MOD search_for_module ( TEXT * module , TEXT * name )
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* s e a r c h _ f o r _ m o d u l e ( W I N _ N T )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Look for a module ( as named in a ' DECLARE EXTERNAL FUNCTION '
* statement . Adjust for differences between behavior of
* _access ( ) and LoadLibrary ( ) w . r . t . implicit . DLL suffix .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-24 16:54:26 +02:00
/* We need different versions of the file name to pass to _access()
2001-05-23 15:26:42 +02:00
* and to LoadLibrary ( ) , because LoadLibrary ( ) implicitly appends
* . DLL to the supplied name and access does not . We need to control
* exactly what name is being used by each routine .
*/
TEXT ib_lib_path [ MAXPATHLEN ] ; /* for access() */
TEXT absolute_module [ MAXPATHLEN ] ; /* for _access() ??? */
TEXT loadlib_name [ MAXPATHLEN ] ; /* for LoadLibrary() */
TEXT drive_buf [ _MAX_DRIVE ] ;
TEXT dir_buf [ _MAX_DIR ] ;
FDLS * dir_list ;
BOOLEAN found_module ;
2001-05-24 16:54:26 +02:00
const USHORT length = strlen ( module ) ;
MOD mod = ( MOD ) gds__alloc ( sizeof ( struct mod ) + length ) ;
2001-05-23 15:26:42 +02:00
2001-05-24 16:54:26 +02:00
if ( ! mod )
{
2001-05-23 15:26:42 +02:00
return NULL ;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
/* Set absolute_module to the drive and directory prefix part of
module , like dirname ( ) under Unix . */
2001-05-24 16:54:26 +02:00
_splitpath ( module , drive_buf , dir_buf , 0 , 0 ) ;
2001-05-23 15:26:42 +02:00
strcpy ( absolute_module , drive_buf ) ;
strcat ( absolute_module , dir_buf ) ;
2001-05-24 16:54:26 +02:00
if ( 0 = = absolute_module [ 0 ] )
{
2001-05-23 15:26:42 +02:00
/* We have a simple module name without a directory. */
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
strncat ( ib_lib_path , module , MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
adjust_loadlib_name ( ib_lib_path , loadlib_name ) ;
2001-05-24 16:54:26 +02:00
if ( ! _access ( ib_lib_path , 4 /* read permission */ ) )
{
2001-05-23 15:26:42 +02:00
/* Module is in the default UDF directory: load it. */
2001-05-24 16:54:26 +02:00
mod - > mod_handle = LoadLibrary ( loadlib_name ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! _access ( ib_lib_path , 4 /* read permission */ ) )
{
2001-05-23 15:26:42 +02:00
/* Module is in the default international library: load it */
2001-05-24 16:54:26 +02:00
mod - > mod_handle = LoadLibrary ( ib_lib_path ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
/* The module is not in the default directory, so ...
* use the EXTERNAL_FUNCTION_DIRECTORY lines from isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
found_module = FALSE ;
2001-05-24 16:54:26 +02:00
while ( dir_list & & ! found_module )
{
2001-05-23 15:26:42 +02:00
strcpy ( ib_lib_path , dir_list - > fdls_directory ) ;
strcat ( ib_lib_path , " \\ " ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
2001-05-24 16:54:26 +02:00
if ( ! _access ( ib_lib_path , 4 /* read permission */ ) )
{
mod - > mod_handle = LoadLibrary ( ib_lib_path ) ;
if ( ! mod - > mod_handle )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
found_module = TRUE ;
}
dir_list = dir_list - > fdls_next ;
}
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
} /* else module is not in the INTL directory */
} /* else module is not in the default UDF directory, so ... */
} /* if path part of name is empty */
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
/* The module name includes a directory path.
* The directory must be either $ INTERBASE / UDF , or $ INTERBASE / intl
* or listed in an EXTERNAL_FUNCTION_DIRECTORY line in isc_config ,
* and the module must be accessible in that directory .
*/
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
found_module = ! stricmp ( ib_lib_path , absolute_module ) ;
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
found_module = ! stricmp ( ib_lib_path , absolute_module ) ;
}
2001-05-24 16:54:26 +02:00
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
/* It's not the default directory, so try the ones listed
* in EXTERNAL_FUNCTION_DIRECTORY lines in isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
2001-05-24 16:54:26 +02:00
while ( dir_list & & ! found_module )
{
2001-05-23 15:26:42 +02:00
if ( ! stricmp ( dir_list - > fdls_directory , absolute_module ) )
found_module = TRUE ;
dir_list = dir_list - > fdls_next ;
}
}
if ( found_module )
2001-05-24 16:54:26 +02:00
{
found_module =
( ! _access ( module , 4 /* read ok? */ ) ) & &
2001-05-23 15:26:42 +02:00
( 0 ! = ( mod - > mod_handle = LoadLibrary ( module ) ) ) ;
2001-05-24 16:54:26 +02:00
}
if ( ! found_module )
{
2001-05-23 15:26:42 +02:00
gds__free ( mod ) ;
return NULL ;
}
} /* else module name includes a directory path, so ... */
return mod ;
}
static void adjust_loadlib_name ( TEXT * access_path , TEXT * load_path )
{
/**************************************
*
* a d j u s t _ l o a d l i b _ n a m e ( W I N _ N T )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Look for a module ( as named in a ' DECLARE EXTERNAL FUNCTION '
* statement . Adjust for differences between behavior of
* _access ( ) and LoadLibrary ( ) w . r . t . implicit . DLL suffix .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-24 16:54:26 +02:00
const USHORT length = strlen ( access_path ) ;
2001-05-23 15:26:42 +02:00
strcpy ( load_path , access_path ) ;
/* Adjust the names to be passed to _access() and LoadLibrary(),
* so that they will refer to the same file , despite the implicit
* adjustments performed by LoadLibrary .
* Input _access ( ) arg LoadLibrary ( ) arg LoadLibrary ( ) uses . . .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* foo . foo foo . foo
* foo foo foo . foo
* foo . dll foo . dll foo . dll foo . dll
*/
2001-05-24 16:54:26 +02:00
if ( stricmp ( access_path + length - 4 , " .dll " ) )
{
if ( ' . ' = = access_path [ length - 1 ] )
{
2001-05-23 15:26:42 +02:00
access_path [ length - 1 ] = ' \0 ' ;
}
2001-05-24 16:54:26 +02:00
else
{
2001-05-23 15:26:42 +02:00
load_path [ length ] = ' . ' ;
load_path [ length + 1 ] = ' \0 ' ;
}
}
}
# endif
2001-07-12 07:46:06 +02:00
# ifdef DARWIN
# define LOOKUP
NSModule ISC_link_with_module ( TEXT * ) ;
FPTR_INT ISC_lookup_entrypoint (
TEXT * module ,
TEXT * name ,
TEXT * ib_path_env_var )
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( D A R W I N )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
FPTR_INT function ;
int lastSpace , i , len ;
MOD mod ;
TEXT absolute_module [ MAXPATHLEN ] ;
NSSymbol symbol ;
if ( function = FUNCTIONS_entrypoint ( module , name ) )
return function ;
/* Remove TRAILING spaces from path names; spaces within the path are valid */
for ( i = strlen ( module ) - 1 , lastSpace = 0 ; i > = 0 ; i - - )
if ( module [ i ] = = ' ' )
lastSpace = i ;
else
break ;
if ( module [ lastSpace ] = = ' ' )
module [ lastSpace ] = 0 ;
for ( i = strlen ( name ) - 1 , lastSpace = 0 ; i > = 0 ; i - - )
if ( name [ i ] = = ' ' )
lastSpace = i ;
else
break ;
if ( name [ lastSpace ] = = ' ' )
name [ lastSpace ] = 0 ;
if ( ! * module | | ! * name )
return NULL ;
/*printf("names truncated: %s, function %s.\n", module, name);*/
/* Check if external function module has already been loaded */
if ( ! ( mod = FLU_lookup_module ( module ) ) )
{
USHORT length ;
# ifdef EXT_LIB_PATH
if ( ib_path_env_var = = NULL )
strcpy ( absolute_module , module ) ;
else if ( ! gds__validate_lib_path ( module , ib_path_env_var , absolute_module , sizeof ( absolute_module ) ) )
return NULL ;
# else
strcpy ( absolute_module , module ) ;
# endif /* EXT_LIB_PATH */
length = strlen ( absolute_module ) ;
/* call search_for_module with the supplied name,
and if unsuccessful , then with < name > . so . */
mod = search_for_module ( absolute_module , name ) ;
if ( ! mod )
{
strcat ( absolute_module , " .so " ) ;
mod = search_for_module ( absolute_module , name ) ;
}
if ( ! mod )
{
/*printf("Couldn't find module: %s\n", absolute_module);*/
return NULL ;
}
assert ( mod - > mod_handle ) ; /* assert that we found the module */
mod - > mod_use_count = 0 ;
mod - > mod_length = length ;
strcpy ( mod - > mod_name , module ) ;
mod - > mod_next = FLU_modules ;
FLU_modules = mod ;
}
/* Look for the symbol and return a pointer to the function if found */
mod - > mod_use_count + + ;
symbol = NSLookupSymbolInModule ( mod - > mod_handle , name ) ;
if ( symbol = = NULL )
{
/*printf("Failed to find function: %s in module %s, trying _%s\n", name, module, name);*/
strcpy ( absolute_module , " _ " ) ;
strncat ( absolute_module , name , sizeof ( absolute_module ) - 2 ) ;
symbol = NSLookupSymbolInModule ( mod - > mod_handle , absolute_module ) ;
if ( symbol = = NULL )
{
/*printf("Failed to find symbol %s. Giving up.\n", absolute_module);*/
return NULL ;
}
}
return ( FPTR_INT ) NSAddressOfSymbol ( symbol ) ;
}
static MOD search_for_module ( TEXT * module ,
TEXT * name )
{
/**************************************
*
* s e a r c h _ f o r _ m o d u l e ( D A R W I N )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Look for a module ( as named in a ' DECLARE EXTERNAL FUNCTION '
* statement .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
MOD mod ;
char * dirp ;
TEXT ib_lib_path [ MAXPATHLEN ] ;
TEXT absolute_module [ MAXPATHLEN ] ; /* for _access() ??? */
FDLS * dir_list ;
BOOLEAN found_module ;
strcpy ( absolute_module , module ) ;
if ( ! ( mod = ( MOD ) gds__alloc ( sizeof ( struct mod ) +
strlen ( absolute_module ) ) ) )
return NULL ;
dirp = ( char * ) dirname ( absolute_module ) ;
if ( ( ' . ' = = dirp [ 0 ] ) & & ( ' \0 ' = = dirp [ 1 ] ) )
{
/* We have a simple module name without a directory. */
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
if ( ! access ( ib_lib_path , R_OK ) )
{
/* Module is in the standard UDF directory: load it. */
if ( ! ( mod - > mod_handle = ISC_link_with_module ( ib_lib_path ) ) )
{
gds__free ( mod ) ;
return NULL ;
}
}
else
{
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
/*printf("intl file: %s\n", ib_lib_path);*/
if ( ! access ( ib_lib_path , R_OK ) )
{
/* Module is in the default directory: load it. */
if ( ! ( mod - > mod_handle = ISC_link_with_module ( ib_lib_path ) ) )
{
gds__free ( mod ) ;
return NULL ;
}
}
else
{
/* The module is not in the default directory, so ...
* use the EXTERNAL_FUNCTION_DIRECTORY lines from isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
found_module = FALSE ;
while ( dir_list & & ! found_module )
{
strcpy ( ib_lib_path , dir_list - > fdls_directory ) ;
strcat ( ib_lib_path , " / " ) ;
strncat ( ib_lib_path , module ,
MAXPATHLEN - strlen ( ib_lib_path ) - 1 ) ;
if ( ! access ( ib_lib_path , R_OK ) )
{
if ( ! ( mod - > mod_handle = ISC_link_with_module ( ib_lib_path ) ) )
{
gds__free ( mod ) ;
return NULL ;
}
found_module = TRUE ;
}
dir_list = dir_list - > fdls_next ;
}
if ( ! found_module )
{
gds__free ( mod ) ;
return NULL ;
}
} /* else module is not in the INTL directory */
} /* else module is not in the default directory, so ... */
} /* if *dirp is "." */
else
{
/* The module name includes a directory path.
* The directory must be the standard UDF directory , or the
* standard international directory , or listed in
* an EXTERNAL_FUNCTION_DIRECTORY line in isc_config ,
* and the module must be accessible in that directory .
*/
gds__prefix ( ib_lib_path , IB_UDF_DIR ) ;
ib_lib_path [ strlen ( ib_lib_path ) - 1 ] = ' \0 ' ; /* drop trailing "/" */
found_module = ! strcmp ( ib_lib_path , dirp ) ;
if ( ! found_module )
{
gds__prefix ( ib_lib_path , IB_INTL_DIR ) ;
ib_lib_path [ strlen ( ib_lib_path ) - 1 ] = ' \0 ' ; /* drop trailing / */
found_module = ! strcmp ( ib_lib_path , dirp ) ;
}
if ( ! found_module )
{
/* It's not the default directory, so try the ones listed
* in EXTERNAL_FUNCTION_DIRECTORY lines in isc_config .
*/
dir_list = DLS_get_func_dirs ( ) ;
while ( dir_list & & ! found_module )
{
if ( ! strcmp ( dir_list - > fdls_directory , dirp ) )
found_module = TRUE ;
dir_list = dir_list - > fdls_next ;
}
}
if ( found_module )
found_module = ( ! access ( module , R_OK ) ) & &
( 0 ! = ( mod - > mod_handle = ISC_link_with_module ( module ) ) ) ;
if ( ! found_module )
{
gds__free ( mod ) ;
return NULL ;
}
} /* else module name includes a directory path, so ... */
return mod ;
}
NSModule ISC_link_with_module (
TEXT * fileName )
{
/**************************************
*
* I S C _ l i n k _ w i t h _ m o d u l e ( D A R W I N )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Given the file system path to a module , load it and link it into
* our address space . Assumes all security checks have been
* performed .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NSObjectFileImage image ;
NSObjectFileImageReturnCode retVal ;
NSModule mod_handle ;
NSSymbol initSym ;
void ( * init ) ( void ) ;
/* Create an object file image from the given path */
retVal = NSCreateObjectFileImageFromFile ( fileName , & image ) ;
if ( retVal ! = NSObjectFileImageSuccess )
{
switch ( retVal )
{
case NSObjectFileImageFailure :
/*printf("object file setup failure");*/
return NULL ;
case NSObjectFileImageInappropriateFile :
/*printf("not a Mach-O MH_BUNDLE file type");*/
return NULL ;
case NSObjectFileImageArch :
/*printf("no object for this architecture");*/
return NULL ;
case NSObjectFileImageFormat :
/*printf("bad object file format");*/
return NULL ;
case NSObjectFileImageAccess :
/*printf("can't read object file");*/
return NULL ;
default :
/*printf("unknown error from NSCreateObjectFileImageFromFile()");*/
return NULL ;
}
}
/* link the image */
mod_handle = NSLinkModule ( image , fileName , NSLINKMODULE_OPTION_PRIVATE ) ;
NSDestroyObjectFileImage ( image ) ;
if ( mod_handle = = NULL )
{
/*printf("NSLinkModule() failed for dlopen()");*/
return NULL ;
}
initSym = NSLookupSymbolInModule ( mod_handle , " __init " ) ;
if ( initSym ! = NULL )
{
init = ( void ( * ) ( void ) ) NSAddressOfSymbol ( initSym ) ;
init ( ) ;
}
return mod_handle ;
}
# endif
2001-05-23 15:26:42 +02:00
# ifndef LOOKUP
2001-05-24 16:54:26 +02:00
FPTR_INT ISC_lookup_entrypoint ( TEXT * module ,
TEXT * name ,
TEXT * ib_path_env_var )
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* I S C _ l o o k u p _ e n t r y p o i n t ( d e f a u l t )
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Lookup entrypoint of function .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-24 16:54:26 +02:00
FPTR_INT function = FUNCTIONS_entrypoint ( module , name ) ;
return function ;
2001-05-23 15:26:42 +02:00
}
# endif
# ifdef VMS
static int condition_handler ( int * sig , int * mech , int * enbl )
{
/**************************************
*
* c o n d i t i o n _ h a n d l e r
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Functional description
* Ignore signal from " lib$find_symbol " .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
return SS $ _CONTINUE ;
}
# endif
2002-02-16 03:21:35 +01:00
} // extern "C"