00001
00002 #include <kore/kore.h>
00003 #include <kore/version.h>
00004 #include <kore/pluginloader.h>
00005 #include <kore/plugin.h>
00006 #if defined( KORE_WIN32 )
00007 #elif defined( KORE_BEOS )
00008 #include <image.h>
00009 #elif defined( KORE_ATHEOS )
00010 #include <atheos/image.h>
00011 #else
00012 #include <dlfcn.h>
00013 #endif
00014
00015 #define PLDR_MAJOR 0
00016 #define PLDR_MINOR 0
00017 #define PLDR_REVISION 1
00018 #define PLDR_VERSION "0.0.1"
00019 #define PLDR_API_MAJOR 0
00020 #define PLDR_API_MINOR 0
00021 #define PLDR_API_REVISION 1
00022 #define PLDR_API_VERSION "0.0.1"
00023 #define PLDR_NAME "Plugin Loader"
00024 #define PLDR_TYPE "Plugin Loader"
00025 #define PLDR_DESCRIPTION "Default Kore Plugin Loader"
00026 #define PLDR_SERVICE "Kore/Kernel/Plugin Loader"
00027 #define PLDR_SERVICE_DESCRIPTION "Kore Plugin Loader"
00028
00029 using namespace kore;
00030
00031 PluginLoader::PluginLoader()
00032 {
00033 _loaderVersion = new Version(PLDR_MAJOR,PLDR_MINOR,PLDR_REVISION,PLDR_VERSION);
00034 _loaderAPIVersion = new Version(PLDR_API_MAJOR,PLDR_API_MINOR,PLDR_API_REVISION,PLDR_API_VERSION);
00035 _loaderInfo = new Info(this, PLDR_NAME, PLDR_TYPE, PLDR_DESCRIPTION, _loaderVersion, _loaderAPIVersion);
00036 setInfo(_loaderInfo);
00037 _loaderService = new Service(this, PLDR_SERVICE, PLDR_SERVICE_DESCRIPTION);
00038 addService(_loaderService);
00039 }
00040 PluginLoader::~PluginLoader()
00041 {
00042 delete _loaderInfo;
00043 delete _loaderVersion;
00044 delete _loaderAPIVersion;
00045 delete _loaderService;
00046 }
00047
00048
00049 char* PluginLoader::libName2fileName(const char* libName)
00050 {
00051 int n = strlen(libName);
00052 #ifdef KORE_WIN32
00053 char* fn = new char[n+1+4];
00054 return strcat(strcpy(fn,libName),".dll");
00055 #else
00056 char* fn = new char[n+1+6];
00057 return strcat(strcat(strcpy(fn,"lib"),libName),".so");
00058 #endif
00059 }
00060
00061 char* PluginLoader::fileName2libName(const char* fileName)
00062 {
00063 #ifdef KORE_WIN32
00064 int n = strlen(libName) - 4;
00065 char* ln = new char[n+1];
00066 #else
00067 char* pos = strstr(fileName, ".so");
00068 int n = pos - fileName - 3;
00069 char* ln = new char[n+1];
00070 fileName += 3;
00071 #endif
00072 return strncpy(ln, fileName, n);
00073 }
00074
00075 Plugin* PluginLoader::runPlugin(const char* libName, const char* libPath, int libFlags)
00076 {
00077 Plugin* plugin = openPlugin(libName, libPath, libFlags);
00078 if( plugin )
00079 plugin->initPlugin();
00080 return plugin;
00081 }
00082 Plugin* PluginLoader::openPlugin(const char* libName, const char* libPath, int libFlags)
00083 {
00084 HMODULE handle;
00085 char* fileName = libName2fileName(libName);
00086 char* filePath = 0;
00087 Plugin* res;
00088 if( libPath && libPath[0] )
00089 {
00090 int n = strlen(libPath);
00091 int slash = libPath[n-1] == '/' ? 0 : 1;
00092 filePath = new char[n+strlen(fileName)+slash+1];
00093 strcpy(filePath, libPath);
00094 if( slash )
00095 {
00096 filePath[n] = '/';
00097 filePath[n+1] = 0;
00098 }
00099 }
00100 else
00101 {
00102 filePath = new char[strlen(fileName)+1];
00103 filePath[0] = 0;
00104 }
00105 strcat( filePath, fileName );
00106
00107 delete[] fileName;
00108 #if defined( KORE_WIN32 )
00109 handle = LoadLibrary(filePath);
00110 #elif defined( KORE_BEOS )
00111 handle = load_add_on(filePath);
00112 #elif defined( KORE_ATHEOS )
00113 handle = load_library( filePath, 0 );
00114 #else
00115 handle = dlopen(filePath, libFlags | RTLD_NOW );
00116 #endif
00117 delete[] filePath;
00118
00119 #if defined( KORE_BEOS )
00120 if( handle < B_NO_ERROR )
00121 #elif defined( KORE_ATHEOS )
00122 if( handle < 0 )
00123 #else
00124 if( !handle )
00125 #endif
00126 return 0;
00127
00128 PluginFuncType sym = 0;
00129 #if defined( KORE_WIN32 )
00130 sym = (PluginFuncType) GetProcAddress( handle, "plugin" );
00131 #elif defined( KORE_BEOS )
00132 if( B_OK != get_image_symbol( handle, "plugin", B_SYMBOL_TYPE_TEXT, reinterpret_cast<void**>(&sym) ) )
00133 sym = 0;
00134 #elif defined( KORE_ATHEOS )
00135 if( 0 != get_symbol_address( handle, "plugin", -1, reinterpret_cast<void**>(&sym) ) )
00136 sym = 0;
00137 #else
00138 sym = (PluginFuncType) dlsym( const_cast<void*>(handle), "plugin" );
00139 #endif
00140
00141 if( !sym )
00142 res = new Plugin(handle,libName,libPath,libFlags);
00143 else
00144 res = sym(handle,libName,libPath,libFlags);
00145
00146 res->pluginLoaded();
00147 return res;
00148 }
00149
00150 void PluginLoader::closePlugin(Plugin* plugin)
00151 {
00152 plugin->unloadingPlugin();
00153 #if defined( KORE_WIN32 )
00154 FreeLibrary( plugin->libHandle() );
00155 #elif defined( KORE_BEOS )
00156 unload_add_on( plugin->libHandle() );
00157 #elif defined( KORE_ATHEOS )
00158 unload_library( plugin->libHandle() );
00159 #else
00160 dlclose(const_cast<void*> (plugin->libHandle()));
00161 #endif
00162 }
00163
00164 const char* PluginLoader::lastError()
00165 {
00166 _lastError[0]=0;
00167 #if defined( KORE_WIN32 )
00168 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
00169 GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), _lastError, 100, NULL );
00170 #elif defined( KORE_BEOS )
00171 strncpy(_lastError, strerror(errno), 100);
00172 #elif defined( KORE_ATHEOS )
00173 strncpy(_lastError, strerror(errno), 100);
00174 #else
00175 strncpy(_lastError, dlerror(), 100);
00176 #endif
00177 return _lastError;
00178 }