8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 20:03:03 +01:00
firebird-mirror/src/jrd/flu.cpp

338 lines
8.0 KiB
C++
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Access Method
* MODULE: flu.cpp
2001-05-23 15:26:42 +02:00
* 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
*
* 2002-02-23 Sean Leyne - Code Cleanup, removed old M88K and NCR3000 port
*
* 2002.10.27 Sean Leyne - Code Cleanup, removed obsolete "UNIXWARE" port
*
2002-10-29 03:45:09 +01:00
* 2002.10.28 Sean Leyne - Completed removal of obsolete "DGUX" port
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "DecOSF" port
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "SGI" port
* 2002.10.28 Sean Leyne - Completed removal of obsolete "HP700" port
2002-10-29 03:45:09 +01:00
*
2002-11-29 05:10:18 +01:00
* 2002.11.28 Sean Leyne - Code cleanup, removed obsolete "HM300" port
*
* 2003.04.12 Alex Peshkoff - Security code cleanup:
* 1. Drop EXT_LIB_PATH verification
* 2. Drop IB_UDF_DIR & IB_INTL_DIR support
* 3. Created common for all platforms search_for_module,
* using dir_list and PathUtils. Platform specific
* macros defined after ISC-lookup-entrypoint()
* for each platform.
*
* 2004.11.27 Alex Peshkoff - removed results of Borland's copyNpaste
* programming style. Almost all completely rewritten.
*
2001-05-23 15:26:42 +02:00
*/
#include "firebird.h"
#include "../common/config/config.h"
#include "../common/config/dir_list.h"
#include "../jrd/os/path_utils.h"
#include "../common/classes/init.h"
#include "../jrd/jrd.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/common.h"
#include "../jrd/flu.h"
#include "../jrd/gdsassert.h"
#include "../jrd/flu_proto.h"
#include "../jrd/gds_proto.h"
#include "../jrd/err_proto.h"
#include "gen/iberror.h"
2001-05-23 15:26:42 +02:00
#include <string.h>
2008-01-16 10:07:24 +01:00
#if (defined SOLARIS || defined SCO_EV || defined LINUX || defined AIX_PPC || defined FREEBSD || defined NETBSD || defined HPUX)
2001-05-23 15:26:42 +02:00
#define DYNAMIC_SHARED_LIBRARIES
#endif
using namespace Firebird;
2001-07-12 07:46:06 +02:00
namespace {
Firebird::InitInstance<Jrd::Module::LoadedModules> loadedModules;
Firebird::GlobalPtr<Firebird::Mutex> modulesMutex;
2001-05-23 15:26:42 +02:00
template <typename S>
void terminate_at_space(S& s, const char* psz)
2001-05-24 16:54:26 +02:00
{
const char *p = psz;
while (*p && *p != ' ')
2001-05-24 16:54:26 +02:00
{
++p;
2001-05-24 16:54:26 +02:00
}
s.assign(psz, p - psz);
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
// we have to keep prefix/suffix per-OS mechanism
// here to help dir_list correctly locate module
// in one of it's directories
2001-05-23 15:26:42 +02:00
enum ModKind {MOD_PREFIX, MOD_SUFFIX};
2008-05-10 05:44:57 +02:00
struct Libfix
{
ModKind kind;
const char* txt;
bool permanent;
};
2001-05-23 15:26:42 +02:00
2008-05-10 05:44:57 +02:00
const Libfix libfixes[] =
{
2001-05-23 15:26:42 +02:00
#ifdef WIN_NT
// to avoid implicit .dll suffix
{MOD_SUFFIX, ".", false},
2005-08-22 15:02:56 +02:00
{MOD_SUFFIX, ".DLL", false},
#endif
2001-05-23 15:26:42 +02:00
// always try to use module "as is"
{MOD_SUFFIX, "", false},
2001-05-23 15:26:42 +02:00
2007-06-11 16:21:33 +02:00
#ifdef HPUX
{MOD_SUFFIX, ".sl", true},
2001-05-23 15:26:42 +02:00
#endif
#ifdef DYNAMIC_SHARED_LIBRARIES
{MOD_SUFFIX, ".so", true},
{MOD_PREFIX, "lib", true},
2001-05-23 15:26:42 +02:00
#endif
2001-07-12 07:46:06 +02:00
#ifdef DARWIN
2007-06-11 16:21:33 +02:00
{MOD_SUFFIX, ".dylib", true},
2001-07-12 07:46:06 +02:00
#endif
};
2001-05-23 15:26:42 +02:00
// UDF/BLOB filter verifier
class UdfDirectoryList : public Firebird::DirectoryList
{
private:
2009-01-14 12:10:48 +01:00
const Firebird::PathName getConfigString() const
2008-05-10 05:44:57 +02:00
{
return Firebird::PathName(Config::getUdfAccess());
}
public:
2008-03-11 03:05:09 +01:00
explicit UdfDirectoryList(MemoryPool& p)
: DirectoryList(p)
2004-08-24 07:16:40 +02:00
{
initialize();
2004-08-24 07:16:40 +02:00
}
};
Firebird::InitInstance<UdfDirectoryList> iUdfDirectoryList;
2001-05-23 15:26:42 +02:00
}
namespace Jrd
2001-05-23 15:26:42 +02:00
{
2006-11-21 14:37:06 +01:00
bool Module::operator>(const Module &im) const
{
// we need it to sort on some key
return interMod > im.interMod;
}
Module::InternalModule* Module::scanModule(const Firebird::PathName& name)
2001-05-24 16:54:26 +02:00
{
typedef Module::InternalModule** itr;
for (itr it = loadedModules().begin(); it != loadedModules().end(); ++it)
{
if (**it == name)
{
return *it;
}
}
return 0;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2008-12-14 09:58:13 +01:00
FPTR_INT Module::lookup(const TEXT* module, const TEXT* name, DatabaseModules& interest)
2001-05-24 16:54:26 +02:00
{
FPTR_INT function = FUNCTIONS_entrypoint(module, name);
if (function)
2001-05-24 16:54:26 +02:00
{
return function;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
// Try to find loadable module
Module m = lookupModule(module, true);
if (! m)
{
return 0;
}
2001-05-23 15:26:42 +02:00
Firebird::string symbol;
terminate_at_space(symbol, name);
void* rc = m.lookupSymbol(symbol);
if (rc)
{
2008-03-29 14:24:22 +01:00
if (!interest.exist(m))
{
interest.add(m);
}
}
2001-05-23 15:26:42 +02:00
return (FPTR_INT)rc;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
2008-12-14 09:58:13 +01:00
FPTR_INT Module::lookup(const TEXT* module, const TEXT* name)
2001-05-24 16:54:26 +02:00
{
FPTR_INT function = FUNCTIONS_entrypoint(module, name);
if (function)
2001-05-24 16:54:26 +02:00
{
return function;
2001-05-23 15:26:42 +02:00
}
// Try to find loadable module
Module m = lookupModule(module, false);
if (! m)
2001-05-24 16:54:26 +02:00
{
return 0;
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
Firebird::string symbol;
terminate_at_space(symbol, name);
return (FPTR_INT)(m.lookupSymbol(symbol));
2001-05-23 15:26:42 +02:00
}
// flag 'udf' means pass name-path through UdfDirectoryList
Module Module::lookupModule(const char* name, bool udf)
{
Firebird::MutexLockGuard lg(modulesMutex);
Firebird::PathName initialModule;
terminate_at_space(initialModule, name);
2001-05-23 15:26:42 +02:00
2008-12-05 02:20:14 +01:00
// Look for module in array of already loaded
InternalModule* im = scanModule(initialModule);
if (im)
{
return Module(im);
}
2001-05-23 15:26:42 +02:00
// apply suffix (and/or prefix) and try that name
Firebird::PathName module(initialModule);
2006-11-26 14:33:52 +01:00
for (size_t i = 0; i < sizeof(libfixes) / sizeof(Libfix); i++)
{
const Libfix* l = &libfixes[i];
// os-dependent module name modification
Firebird::PathName fixedModule(module);
switch (l->kind)
{
case MOD_PREFIX:
fixedModule = l->txt + fixedModule;
break;
case MOD_SUFFIX:
fixedModule += l->txt;
}
if (l->permanent)
{
module = fixedModule;
}
2001-05-23 15:26:42 +02:00
// Look for module with fixed name
im = scanModule(fixedModule);
if (im)
{
return Module(im);
}
2001-05-23 15:26:42 +02:00
if (udf)
{
// UdfAccess verification
Firebird::PathName path, relative;
2008-12-05 02:20:14 +01:00
// Search for module name in UdfAccess restricted
// paths list
PathUtils::splitLastComponent(path, relative, fixedModule);
2008-12-14 09:58:13 +01:00
if (path.length() == 0 && PathUtils::isRelative(fixedModule))
2004-11-30 07:18:39 +01:00
{
path = fixedModule;
2006-11-26 14:33:52 +01:00
if (! iUdfDirectoryList().expandFileName(fixedModule, path))
{
// relative path was used, but no appropriate file present
continue;
}
}
// The module name, including directory path,
// must satisfy UdfAccess entry in config file.
2006-11-26 14:33:52 +01:00
if (! iUdfDirectoryList().isPathInList(fixedModule))
{
2008-12-05 02:20:14 +01:00
ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("UDF/BLOB-filter module") <<
Arg::Str(initialModule));
2006-11-26 14:33:52 +01:00
}
2008-12-05 02:20:14 +01:00
ModuleLoader::Module* mlm = ModuleLoader::loadModule(fixedModule);
if (mlm)
{
2006-11-26 14:33:52 +01:00
im = FB_NEW(*getDefaultMemoryPool())
2008-12-14 09:58:13 +01:00
InternalModule(*getDefaultMemoryPool(), mlm, initialModule, fixedModule);
2006-11-26 14:33:52 +01:00
loadedModules().add(im);
return Module(im);
}
}
else
{
// try to load permanent module
ModuleLoader::Module* mlm = ModuleLoader::loadModule(fixedModule);
if (mlm)
{
im = FB_NEW(*getDefaultMemoryPool())
2008-12-14 09:58:13 +01:00
InternalModule(*getDefaultMemoryPool(), mlm, initialModule, fixedModule);
loadedModules().add(im);
im->acquire(); // make permanent
return Module(im);
}
}
}
// let others raise 'missing library' error if needed
return Module();
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
Module::~Module()
2001-05-24 16:54:26 +02:00
{
if (interMod)
{
interMod->release();
if (! interMod->inUse())
{
Firebird::MutexLockGuard lg(modulesMutex);
for (size_t m = 0; m < loadedModules().getCount(); m++)
{
if (loadedModules()[m] == interMod)
{
loadedModules().remove(m);
delete interMod;
return;
}
}
fb_assert(false);
// In production server we delete interMod here
// (though this is not normal case)
delete interMod;
}
}
2001-05-24 16:54:26 +02:00
}
2001-05-23 15:26:42 +02:00
} // namespace Jrd