00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include "plugin_p.h"
00033 #include <gwenhywfar/buffer.h>
00034 #include <gwenhywfar/debug.h>
00035 #include <gwenhywfar/directory.h>
00036 #include <gwenhywfar/pathmanager.h>
00037 #include <gwenhywfar/gwenhywfar.h>
00038
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #ifdef HAVE_UNISTD_H
00042 # include <unistd.h>
00043 #endif
00044 #include <errno.h>
00045 #include <string.h>
00046 #ifdef HAVE_STRINGS_H
00047 # include <strings.h>
00048 #endif
00049 #include <ctype.h>
00050
00051 #ifdef OS_WIN32
00052 # include <windows.h>
00053 #endif
00054
00055 static GWEN_PLUGIN_MANAGER_LIST *gwen_plugin_manager__list=0;
00056
00057
00058 GWEN_INHERIT_FUNCTIONS(GWEN_PLUGIN)
00059 GWEN_LIST_FUNCTIONS(GWEN_PLUGIN, GWEN_Plugin)
00060 GWEN_INHERIT_FUNCTIONS(GWEN_PLUGIN_MANAGER)
00061 GWEN_LIST_FUNCTIONS(GWEN_PLUGIN_MANAGER, GWEN_PluginManager)
00062
00063
00064
00065 int GWEN_Plugin_ModuleInit(){
00066 gwen_plugin_manager__list=GWEN_PluginManager_List_new();
00067 return 0;
00068 }
00069
00070
00071
00072 int GWEN_Plugin_ModuleFini(){
00073 GWEN_PluginManager_List_free(gwen_plugin_manager__list);
00074 return 0;
00075 }
00076
00077
00078
00079 GWEN_PLUGIN *GWEN_Plugin_new(GWEN_PLUGIN_MANAGER *pm,
00080 const char *name,
00081 const char *fileName){
00082 GWEN_PLUGIN *p;
00083
00084 assert(pm);
00085 assert(name);
00086 GWEN_NEW_OBJECT(GWEN_PLUGIN, p);
00087 DBG_MEM_INC("GWEN_PLUGIN", 0);
00088 p->refCount=1;
00089 GWEN_INHERIT_INIT(GWEN_PLUGIN, p);
00090 GWEN_LIST_INIT(GWEN_PLUGIN, p);
00091 p->manager=pm;
00092 p->name=strdup(name);
00093 if (fileName)
00094 p->fileName=strdup(fileName);
00095
00096 return p;
00097 }
00098
00099
00100
00101 void GWEN_Plugin_free(GWEN_PLUGIN *p){
00102 if (p) {
00103 DBG_MEM_DEC("GWEN_PLUGIN");
00104 assert(p->refCount);
00105 if (--(p->refCount)==0) {
00106 GWEN_INHERIT_FINI(GWEN_PLUGIN, p);
00107 free(p->name);
00108 free(p->fileName);
00109 if (p->libLoader) {
00110 GWEN_LibLoader_CloseLibrary(p->libLoader);
00111 GWEN_LibLoader_free(p->libLoader);
00112 }
00113 GWEN_LIST_FINI(GWEN_PLUGIN, p);
00114 GWEN_FREE_OBJECT(p);
00115 }
00116 }
00117 }
00118
00119
00120
00121 void GWEN_Plugin_Attach(GWEN_PLUGIN *p){
00122 assert(p);
00123 assert(p->refCount);
00124 DBG_MEM_INC("GWEN_PLUGIN", 1);
00125 p->refCount++;
00126 }
00127
00128
00129
00130 GWEN_PLUGIN_MANAGER *GWEN_Plugin_GetManager(const GWEN_PLUGIN *p){
00131 assert(p);
00132 return p->manager;
00133 }
00134
00135
00136
00137 const char *GWEN_Plugin_GetName(const GWEN_PLUGIN *p){
00138 assert(p);
00139 return p->name;
00140 }
00141
00142
00143
00144 const char *GWEN_Plugin_GetFileName(const GWEN_PLUGIN *p){
00145 assert(p);
00146 return p->fileName;
00147 }
00148
00149
00150
00151 GWEN_LIBLOADER *GWEN_Plugin_GetLibLoader(const GWEN_PLUGIN *p){
00152 assert(p);
00153 return p->libLoader;
00154 }
00155
00156
00157
00158 void GWEN_Plugin_SetLibLoader(GWEN_PLUGIN *p, GWEN_LIBLOADER *ll){
00159 assert(p);
00160 p->libLoader=ll;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 GWEN_PLUGIN_MANAGER *GWEN_PluginManager_new(const char *name,
00171 const char *destLib){
00172 GWEN_PLUGIN_MANAGER *pm;
00173
00174 assert(name);
00175 assert(destLib);
00176 GWEN_NEW_OBJECT(GWEN_PLUGIN_MANAGER, pm);
00177 DBG_MEM_INC("GWEN_PLUGIN_MANAGER", 0);
00178 GWEN_INHERIT_INIT(GWEN_PLUGIN_MANAGER, pm);
00179 GWEN_LIST_INIT(GWEN_PLUGIN_MANAGER, pm);
00180 pm->name=strdup(name);
00181 pm->destLib=strdup(destLib);
00182 pm->plugins=GWEN_Plugin_List_new();
00183
00184 return pm;
00185 }
00186
00187
00188
00189 void GWEN_PluginManager_free(GWEN_PLUGIN_MANAGER *pm){
00190 if (pm) {
00191 DBG_MEM_DEC("GWEN_PLUGIN_MANAGER");
00192 GWEN_Plugin_List_free(pm->plugins);
00193 GWEN_INHERIT_FINI(GWEN_PLUGIN_MANAGER, pm);
00194 free(pm->destLib);
00195 free(pm->name);
00196 GWEN_LIST_FINI(GWEN_PLUGIN_MANAGER, pm);
00197 GWEN_FREE_OBJECT(pm);
00198 }
00199 }
00200
00201
00202
00203 const char *GWEN_PluginManager_GetName(const GWEN_PLUGIN_MANAGER *pm){
00204 assert(pm);
00205 return pm->name;
00206 }
00207
00208
00209
00210 int GWEN_PluginManager_AddPath(GWEN_PLUGIN_MANAGER *pm,
00211 const char *callingLib,
00212 const char *s){
00213 assert(pm);
00214 return GWEN_PathManager_AddPath(callingLib,
00215 pm->destLib,
00216 pm->name,
00217 s);
00218 }
00219
00220
00221
00222 int GWEN_PluginManager_AddRelPath(GWEN_PLUGIN_MANAGER *pm,
00223 const char *callingLib,
00224 const char *s,
00225 GWEN_PATHMANAGER_RELMODE rm) {
00226 assert(pm);
00227 return GWEN_PathManager_AddRelPath(callingLib,
00228 pm->destLib,
00229 pm->name,
00230 s,
00231 rm);
00232 }
00233
00234
00235
00236 int GWEN_PluginManager_InsertPath(GWEN_PLUGIN_MANAGER *pm,
00237 const char *callingLib,
00238 const char *s) {
00239 assert(pm);
00240 return GWEN_PathManager_InsertPath(callingLib,
00241 pm->destLib,
00242 pm->name,
00243 s);
00244 }
00245
00246
00247
00248 int GWEN_PluginManager_RemovePath(GWEN_PLUGIN_MANAGER *pm,
00249 const char *callingLib,
00250 const char *s) {
00251 assert(pm);
00252 return GWEN_PathManager_RemovePath(callingLib,
00253 pm->destLib,
00254 pm->name,
00255 s);
00256 }
00257
00258
00259
00260 #ifdef OS_WIN32
00261 int GWEN_PluginManager_AddPathFromWinReg(GWEN_PLUGIN_MANAGER *pm,
00262 const char *callingLib,
00263 const char *keypath,
00264 const char *varname){
00265 HKEY hkey;
00266 TCHAR nbuffer[MAX_PATH];
00267 BYTE vbuffer[MAX_PATH];
00268 DWORD nsize;
00269 DWORD vsize;
00270 DWORD typ;
00271 int i;
00272
00273 assert(pm);
00274
00275 snprintf(nbuffer, sizeof(nbuffer), keypath);
00276
00277
00278 if (RegOpenKey(HKEY_LOCAL_MACHINE, nbuffer, &hkey)){
00279 DBG_INFO(GWEN_LOGDOMAIN, "RegOpenKey %s failed.", keypath);
00280 return 1;
00281 }
00282
00283
00284 for (i=0;; i++) {
00285 nsize=sizeof(nbuffer);
00286 vsize=sizeof(vbuffer);
00287 if (ERROR_SUCCESS!=RegEnumValue(hkey,
00288 i,
00289 nbuffer,
00290 &nsize,
00291 0,
00292 &typ,
00293 vbuffer,
00294 &vsize))
00295 break;
00296 if (strcasecmp(nbuffer, varname)==0 && typ==REG_SZ) {
00297
00298 RegCloseKey(hkey);
00299 return GWEN_PathManager_AddPath(callingLib,
00300 pm->destLib,
00301 pm->name,
00302 (char*)vbuffer);
00303 }
00304 }
00305
00306 RegCloseKey(hkey);
00307 DBG_INFO(GWEN_LOGDOMAIN,
00308 "In RegKey \"%s\" the variable \"%s\" does not exist",
00309 keypath, varname);
00310 return 1;
00311
00312 }
00313
00314 #else
00315
00316 int GWEN_PluginManager_AddPathFromWinReg(GWEN_UNUSED GWEN_PLUGIN_MANAGER *pm,
00317 GWEN_UNUSED const char *callingLib,
00318 GWEN_UNUSED const char *keypath,
00319 GWEN_UNUSED const char *varname){
00320 return 0;
00321 }
00322 #endif
00323
00324
00325
00326 GWEN_PLUGIN *GWEN_PluginManager_LoadPlugin(GWEN_PLUGIN_MANAGER *pm,
00327 const char *modname){
00328 #ifdef ENABLE_PLUGIN_LOADING
00329 GWEN_LIBLOADER *ll;
00330 GWEN_PLUGIN *plugin;
00331 GWEN_PLUGIN_FACTORYFN fn;
00332 void *p;
00333 GWEN_BUFFER *nbuf;
00334 const char *s;
00335 const char *fname;
00336 int err;
00337 GWEN_STRINGLIST *sl;
00338 GWEN_STRINGLISTENTRY *se;
00339
00340 assert(pm);
00341 ll=GWEN_LibLoader_new();
00342 sl=GWEN_PathManager_GetPaths(pm->destLib, pm->name);
00343 if (sl==NULL) {
00344 DBG_ERROR(GWEN_LOGDOMAIN, "No paths for plugins (%s)", pm->name);
00345 GWEN_LibLoader_free(ll);
00346 return NULL;
00347 }
00348 nbuf=GWEN_Buffer_new(0, 128, 0, 1);
00349 s=modname;
00350 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++)));
00351 se=GWEN_StringList_FirstEntry(sl);
00352 fname=0;
00353 while(se) {
00354 fname=GWEN_StringListEntry_Data(se);
00355 assert(fname);
00356 if (GWEN_LibLoader_OpenLibraryWithPath(ll, fname,
00357 GWEN_Buffer_GetStart(nbuf))==0)
00358 break;
00359 else {
00360 DBG_DEBUG(GWEN_LOGDOMAIN,
00361 "Could not load plugin \"%s\" from \"%s\"", modname, fname);
00362 }
00363 se=GWEN_StringListEntry_Next(se);
00364 }
00365 if (!se) {
00366 DBG_ERROR(GWEN_LOGDOMAIN, "Plugin \"%s\" not found.", modname);
00367 GWEN_Buffer_free(nbuf);
00368 GWEN_StringList_free(sl);
00369 GWEN_LibLoader_free(ll);
00370 return NULL;
00371 }
00372 GWEN_Buffer_free(nbuf);
00373
00374
00375 nbuf=GWEN_Buffer_new(0, 128, 0, 1);
00376 s=pm->name;
00377 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++)));
00378 GWEN_Buffer_AppendByte(nbuf, '_');
00379 s=modname;
00380 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++)));
00381 GWEN_Buffer_AppendString(nbuf, "_factory");
00382
00383
00384 err=GWEN_LibLoader_Resolve(ll, GWEN_Buffer_GetStart(nbuf), &p);
00385 if (err) {
00386 DBG_ERROR_ERR(GWEN_LOGDOMAIN, err);
00387 GWEN_Buffer_free(nbuf);
00388 GWEN_LibLoader_CloseLibrary(ll);
00389 GWEN_StringList_free(sl);
00390 GWEN_LibLoader_free(ll);
00391 return 0;
00392 }
00393 GWEN_Buffer_free(nbuf);
00394
00395 fn=(GWEN_PLUGIN_FACTORYFN)p;
00396 assert(fn);
00397 plugin=fn(pm, modname, fname);
00398 if (!plugin) {
00399 DBG_ERROR(GWEN_LOGDOMAIN, "Error in plugin: No plugin created");
00400 GWEN_LibLoader_CloseLibrary(ll);
00401 GWEN_StringList_free(sl);
00402 GWEN_LibLoader_free(ll);
00403 return 0;
00404 }
00405
00406
00407 GWEN_StringList_free(sl);
00408 GWEN_Plugin_SetLibLoader(plugin, ll);
00409 return plugin;
00410 #else
00411 DBG_ERROR(GWEN_LOGDOMAIN, "Loading of plugins is disabled");
00412 return NULL;
00413 #endif
00414 }
00415
00416
00417
00418 GWEN_PLUGIN *GWEN_PluginManager_LoadPluginFile(GWEN_PLUGIN_MANAGER *pm,
00419 const char *modname,
00420 const char *fname){
00421 #ifdef ENABLE_PLUGIN_LOADING
00422 GWEN_LIBLOADER *ll;
00423 GWEN_PLUGIN *plugin;
00424 GWEN_PLUGIN_FACTORYFN fn;
00425 void *p;
00426 GWEN_BUFFER *nbuf;
00427 const char *s;
00428 int err;
00429
00430 ll=GWEN_LibLoader_new();
00431 if (GWEN_LibLoader_OpenLibrary(ll, fname)) {
00432 DBG_INFO(GWEN_LOGDOMAIN,
00433 "Could not load plugin \"%s\" (%s)", modname, fname);
00434 GWEN_LibLoader_free(ll);
00435 return 0;
00436 }
00437
00438
00439 nbuf=GWEN_Buffer_new(0, 128, 0, 1);
00440 s=pm->name;
00441 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++)));
00442 GWEN_Buffer_AppendByte(nbuf, '_');
00443 s=modname;
00444 while(*s) GWEN_Buffer_AppendByte(nbuf, tolower(*(s++)));
00445 GWEN_Buffer_AppendString(nbuf, "_factory");
00446
00447
00448 err=GWEN_LibLoader_Resolve(ll, GWEN_Buffer_GetStart(nbuf), &p);
00449 if (err) {
00450 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00451 GWEN_Buffer_free(nbuf);
00452 GWEN_LibLoader_CloseLibrary(ll);
00453 GWEN_LibLoader_free(ll);
00454 return 0;
00455 }
00456 GWEN_Buffer_free(nbuf);
00457
00458 fn=(GWEN_PLUGIN_FACTORYFN)p;
00459 assert(fn);
00460 plugin=fn(pm, modname, fname);
00461 if (!plugin) {
00462 DBG_INFO(GWEN_LOGDOMAIN, "Error in plugin: No plugin created");
00463 GWEN_LibLoader_CloseLibrary(ll);
00464 GWEN_LibLoader_free(ll);
00465 return 0;
00466 }
00467
00468
00469 GWEN_Plugin_SetLibLoader(plugin, ll);
00470
00471 return plugin;
00472 #else
00473 DBG_ERROR(GWEN_LOGDOMAIN, "Loading of plugins is disabled");
00474 return NULL;
00475 #endif
00476 }
00477
00478
00479
00480 GWEN_PLUGIN *GWEN_PluginManager__FindPlugin(GWEN_PLUGIN_MANAGER *pm,
00481 const char *s){
00482 GWEN_PLUGIN *p;
00483
00484 assert(pm);
00485 p=GWEN_Plugin_List_First(pm->plugins);
00486 while(p) {
00487 if (strcasecmp(p->name, s)==0)
00488 break;
00489 p=GWEN_Plugin_List_Next(p);
00490 }
00491
00492 return p;
00493 }
00494
00495
00496
00497 GWEN_PLUGIN *GWEN_PluginManager_GetPlugin(GWEN_PLUGIN_MANAGER *pm,
00498 const char *s){
00499 GWEN_PLUGIN *p;
00500
00501 p=GWEN_PluginManager__FindPlugin(pm, s);
00502 if (p)
00503 return p;
00504 p=GWEN_PluginManager_LoadPlugin(pm, s);
00505 if (p) {
00506 GWEN_Plugin_List_Add(p, pm->plugins);
00507 return p;
00508 }
00509 DBG_INFO(GWEN_LOGDOMAIN, "Plugin \"%s\" not found", s);
00510 return 0;
00511 }
00512
00513
00514
00515 GWEN_PLUGIN_MANAGER *GWEN_PluginManager_FindPluginManager(const char *s){
00516 GWEN_PLUGIN_MANAGER *pm;
00517
00518 pm=GWEN_PluginManager_List_First(gwen_plugin_manager__list);
00519 while(pm) {
00520 if (strcasecmp(pm->name, s)==0)
00521 break;
00522 pm=GWEN_PluginManager_List_Next(pm);
00523 }
00524
00525 return pm;
00526 }
00527
00528
00529
00530 int GWEN_PluginManager_Register(GWEN_PLUGIN_MANAGER *pm){
00531 GWEN_PLUGIN_MANAGER *tpm;
00532 int rv;
00533
00534 assert(gwen_plugin_manager__list);
00535 assert(pm);
00536 tpm=GWEN_PluginManager_FindPluginManager(pm->name);
00537 if (tpm) {
00538 DBG_ERROR(GWEN_LOGDOMAIN,
00539 "Plugin type \"%s\" already registered",
00540 pm->name);
00541 return -1;
00542 }
00543
00544 rv=GWEN_PathManager_DefinePath(pm->destLib, pm->name);
00545 if (rv) {
00546 DBG_INFO(GWEN_LOGDOMAIN, "Could not define path for plugin [%s:%s]",
00547 pm->destLib, pm->name);
00548 return rv;
00549 }
00550
00551 GWEN_PluginManager_List_Add(pm, gwen_plugin_manager__list);
00552 DBG_INFO(GWEN_LOGDOMAIN,
00553 "Plugin type \"%s\" registered",
00554 pm->name);
00555 return 0;
00556 }
00557
00558
00559
00560 int GWEN_PluginManager_Unregister(GWEN_PLUGIN_MANAGER *pm){
00561 GWEN_PLUGIN_MANAGER *tpm;
00562 int rv;
00563
00564 assert(gwen_plugin_manager__list);
00565 assert(pm);
00566 tpm=GWEN_PluginManager_FindPluginManager(pm->name);
00567 if (!tpm) {
00568 DBG_ERROR(GWEN_LOGDOMAIN,
00569 "Plugin type \"%s\" not registered",
00570 pm->name);
00571 return -1;
00572 }
00573
00574 rv=GWEN_PathManager_UndefinePath(pm->destLib, pm->name);
00575 if (rv) {
00576 DBG_INFO(GWEN_LOGDOMAIN, "Could not undefine path for plugin [%s:%s]",
00577 pm->destLib, pm->name);
00578 return rv;
00579 }
00580
00581 GWEN_PluginManager_List_Del(pm);
00582 DBG_INFO(GWEN_LOGDOMAIN,
00583 "Plugin type \"%s\" unregistered",
00584 pm->name);
00585 return 0;
00586 }
00587
00588
00589
00590 GWEN_PLUGIN_DESCRIPTION_LIST2*
00591 GWEN_PluginManager_GetPluginDescrs(GWEN_PLUGIN_MANAGER *pm){
00592 GWEN_PLUGIN_DESCRIPTION_LIST2 *pl;
00593 GWEN_STRINGLIST *sl;
00594 GWEN_STRINGLISTENTRY *se;
00595
00596 sl=GWEN_PathManager_GetPaths(pm->destLib, pm->name);
00597 if (sl==NULL) {
00598 DBG_ERROR(GWEN_LOGDOMAIN, "No paths for plugins (%s)", pm->name);
00599 return NULL;
00600 }
00601 se=GWEN_StringList_FirstEntry(sl);
00602 if (!se) {
00603 DBG_ERROR(GWEN_LOGDOMAIN, "No paths given");
00604 GWEN_StringList_free(sl);
00605 return 0;
00606 }
00607
00608 pl=GWEN_PluginDescription_List2_new();
00609 while(se) {
00610 int rv;
00611 const char *path;
00612
00613 path=GWEN_StringListEntry_Data(se);
00614 assert(path);
00615 rv=GWEN_LoadPluginDescrsByType(path, pm->name, pl);
00616 if (rv) {
00617 DBG_INFO(GWEN_LOGDOMAIN,
00618 "Error loading plugin description in \"%s\"", path);
00619 }
00620 se=GWEN_StringListEntry_Next(se);
00621 }
00622
00623 if (GWEN_PluginDescription_List2_GetSize(pl)==0) {
00624 GWEN_PluginDescription_List2_free(pl);
00625 GWEN_StringList_free(sl);
00626 return 0;
00627 }
00628
00629 GWEN_StringList_free(sl);
00630 return pl;
00631 }
00632
00633
00634 GWEN_STRINGLIST *GWEN_PluginManager_GetPaths(const GWEN_PLUGIN_MANAGER *pm){
00635 assert(pm);
00636 return GWEN_PathManager_GetPaths(pm->destLib, pm->name);
00637 }
00638
00639
00640
00641 GWEN_PLUGIN_DESCRIPTION*
00642 GWEN_PluginManager_GetPluginDescr(GWEN_PLUGIN_MANAGER *pm,
00643 const char *modName) {
00644 GWEN_PLUGIN_DESCRIPTION_LIST2 *dl;
00645
00646 dl=GWEN_PluginManager_GetPluginDescrs(pm);
00647 if (dl==0)
00648 return 0;
00649 else {
00650 GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *dit;
00651
00652 dit=GWEN_PluginDescription_List2_First(dl);
00653 if (dit) {
00654 GWEN_PLUGIN_DESCRIPTION *d;
00655
00656 d=GWEN_PluginDescription_List2Iterator_Data(dit);
00657 while(d) {
00658 if (strcasecmp(GWEN_PluginDescription_GetName(d), modName)==0)
00659 break;
00660 d=GWEN_PluginDescription_List2Iterator_Next(dit);
00661 }
00662 GWEN_PluginDescription_List2Iterator_free(dit);
00663
00664 if (d) {
00665 d=GWEN_PluginDescription_dup(d);
00666 GWEN_PluginDescription_List2_freeAll(dl);
00667 return d;
00668 }
00669 }
00670 GWEN_PluginDescription_List2_freeAll(dl);
00671 }
00672
00673 return 0;
00674 }
00675
00676
00677
00678 void GWEN_PluginManager_AddPlugin(GWEN_PLUGIN_MANAGER *pm, GWEN_PLUGIN *p) {
00679 #if 0
00680 DBG_ERROR(0, "Adding plugin [%s] of type [%s]",
00681 p->name, pm->name);
00682 #endif
00683 GWEN_Plugin_List_Add(p, pm->plugins);
00684 }
00685
00686
00687
00688
00689
00690